Skip to content

Commit 0725c22

Browse files
committed
Tokenizer: Do not simplify function pointers to normal pointers as we loose important information
1 parent e0c8118 commit 0725c22

7 files changed

Lines changed: 122 additions & 97 deletions

File tree

lib/checkunusedvar.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,11 @@ static bool isPartOfClassStructUnion(const Token* tok)
594594
return false;
595595
}
596596

597+
static bool isVarDecl(const Token *tok)
598+
{
599+
return tok && tok->variable() && tok->variable()->nameToken() == tok;
600+
}
601+
597602
// Skip [ .. ]
598603
static const Token * skipBrackets(const Token *tok)
599604
{
@@ -1047,11 +1052,11 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
10471052
variables.use(tok->astOperand2()->varId(), tok->astOperand2());
10481053
}
10491054

1050-
else if (tok->isExtendedOp() && tok->next() && tok->next()->varId() && tok->strAt(2) != "=") {
1055+
else if (tok->isExtendedOp() && tok->next() && tok->next()->varId() && tok->strAt(2) != "=" && !isVarDecl(tok->next())) {
10511056
variables.readAll(tok->next()->varId(), tok);
10521057
}
10531058

1054-
else if (tok->varId() && tok->next() && (tok->next()->str() == ")" || tok->next()->isExtendedOp())) {
1059+
else if (tok->varId() && !isVarDecl(tok) && tok->next() && (tok->next()->str() == ")" || tok->next()->isExtendedOp())) {
10551060
if (Token::Match(tok->tokAt(-2), "%name% ( %var% [,)]") &&
10561061
!(tok->tokAt(-2)->variable() && tok->tokAt(-2)->variable()->isReference()))
10571062
variables.use(tok->varId(), tok);

lib/symboldatabase.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5603,8 +5603,14 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V
56035603
valuetype->type = ValueType::Type::INT;
56045604
} else
56055605
valuetype->type = ValueType::Type::RECORD;
5606-
while (Token::Match(type, "%name%|*|&|::") && !Token::Match(type, "typename|template") &&
5606+
bool par = false;
5607+
while (Token::Match(type, "%name%|*|&|::|(") && !Token::Match(type, "typename|template") &&
56075608
!type->variable() && !type->function()) {
5609+
if (type->str() == "(") {
5610+
if (par)
5611+
break;
5612+
par = true;
5613+
}
56085614
if (type->isSigned())
56095615
valuetype->sign = ValueType::Sign::SIGNED;
56105616
else if (type->isUnsigned())

lib/tokenize.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2994,6 +2994,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
29942994
bool hasstruct = false; // Is there a "struct" or "class"?
29952995
bool bracket = false;
29962996
bool ref = false;
2997+
bool par = false;
29972998
while (tok2) {
29982999
if (tok2->isName()) {
29993000
if (cpp && Token::Match(tok2, "namespace|public|private|protected"))
@@ -3042,7 +3043,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
30423043
}
30433044
} else if (Token::Match(tok2, "&|&&")) {
30443045
ref = !bracket;
3045-
} else if (singleNameCount == 1 && Token::Match(tok2, "( [*&]") && Token::Match(tok2->link()->next(), "(|[")) {
3046+
} else if (singleNameCount >= 1 && !par && Token::Match(tok2, "( [*&]") && Token::Match(tok2->link()->next(), "(|[")) {
30463047
bracket = true; // Skip: Seems to be valid pointer to array or function pointer
30473048
} else if (tok2->str() == "::") {
30483049
singleNameCount = 0;
@@ -6502,10 +6503,22 @@ void Tokenizer::simplifyFunctionPointers()
65026503

65036504
// ok simplify this function pointer to an ordinary pointer
65046505
Token::eraseTokens(tok->link(), endTok->next());
6505-
tok->link()->deleteThis();
6506-
while (Token::Match(tok, "( %type% ::"))
6507-
tok->deleteNext(2);
6508-
tok->deleteThis();
6506+
if (Token::simpleMatch(tok->link()->previous(), ") )")) {
6507+
// Function returning function pointer
6508+
// void (*dostuff(void))(void) {}
6509+
tok->link()->deleteThis();
6510+
tok->deleteThis();
6511+
} else {
6512+
// Function pointer variable
6513+
// void (*p)(void) {}
6514+
tok->link()->insertToken("(");
6515+
Token *par1 = tok->link()->next();
6516+
par1->insertToken(")");
6517+
par1->link(par1->next());
6518+
par1->next()->link(par1);
6519+
while (Token::Match(tok, "( %type% ::"))
6520+
tok->deleteNext(2);
6521+
}
65096522
}
65106523
}
65116524

@@ -6732,8 +6745,17 @@ void Tokenizer::simplifyVarDecl(Token * tokBegin, const Token * const tokEnd, co
67326745
}
67336746
varName = varName->next();
67346747
}
6748+
// Function pointer
6749+
if (Token::simpleMatch(varName, "( *") && Token::Match(varName->link()->previous(), "%name% ) ( ) =")) {
6750+
Token *endDecl = varName->link()->tokAt(2);
6751+
varName = varName->link()->previous();
6752+
endDecl->insertToken(";");
6753+
endDecl = endDecl->next();
6754+
endDecl->insertToken(varName->str());
6755+
continue;
6756+
}
67356757
//non-VLA case
6736-
if (Token::Match(varName, "%name% ,|=")) {
6758+
else if (Token::Match(varName, "%name% ,|=")) {
67376759
if (varName->str() != "operator") {
67386760
tok2 = varName->next(); // The ',' or '=' token
67396761

test/testsimplifytokens.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4692,7 +4692,7 @@ class TestSimplifyTokens : public TestFixture {
46924692

46934693
// #ticket #5339 (simplify function pointer after comma)
46944694
void simplifyFunctionPointer() {
4695-
ASSERT_EQUALS("f ( double x , double * y ) ;", tok("f (double x, double (*y) ());", true));
4695+
ASSERT_EQUALS("f ( double x , double ( * y ) ( ) ) ;", tok("f (double x, double (*y) ());", true));
46964696
}
46974697

46984698
void redundant_semicolon() {

test/testsimplifytypedef.cpp

Lines changed: 60 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,8 @@ class TestSimplifyTypedef : public TestFixture {
725725
"void addCallback1(Callback callback, int j) { }";
726726

727727
const char expected[] =
728-
"void addCallback ( bool * callback ) { } "
729-
"void addCallback1 ( bool * callback , int j ) { }";
728+
"void addCallback ( bool ( * callback ) ( ) ) { } "
729+
"void addCallback1 ( bool ( * callback ) ( ) , int j ) { }";
730730

731731
ASSERT_EQUALS(expected, tok(code, false));
732732
}
@@ -740,9 +740,9 @@ class TestSimplifyTypedef : public TestFixture {
740740
"}";
741741

742742
const char expected[] =
743-
"void g ( int * f ) "
743+
"void g ( int ( * f ) ( ) ) "
744744
"{ "
745-
"int * f2 ; f2 = ( int * ) f ; "
745+
"int ( * f2 ) ( ) ; f2 = ( int * ) f ; "
746746
"}";
747747

748748
ASSERT_EQUALS(expected, tok(code, false));
@@ -756,9 +756,9 @@ class TestSimplifyTypedef : public TestFixture {
756756
"}";
757757

758758
const char expected[] =
759-
"void g ( int * f ) "
759+
"void g ( int ( * f ) ( ) ) "
760760
"{ "
761-
"int * f2 ; f2 = static_cast < int * > ( f ) ; "
761+
"int ( * f2 ) ( ) ; f2 = static_cast < int * > ( f ) ; "
762762
"}";
763763

764764
ASSERT_EQUALS(expected, tok(code, false));
@@ -1078,7 +1078,7 @@ class TestSimplifyTypedef : public TestFixture {
10781078
"class X { } ; "
10791079
"int main ( ) "
10801080
"{ "
1081-
"X * * Foo ; Foo = new X ( * ) ( const X & ) [ 2 ] ; "
1081+
"X ( * * Foo ) ( ) ; Foo = new X ( * ) ( const X & ) [ 2 ] ; "
10821082
"}";
10831083

10841084
ASSERT_EQUALS(expected, tok(code, false));
@@ -1354,7 +1354,7 @@ class TestSimplifyTypedef : public TestFixture {
13541354
"F f;";
13551355

13561356
// The expected result..
1357-
const char expected[] = "void * f ;";
1357+
const char expected[] = "void ( * f ) ( ) ;";
13581358
ASSERT_EQUALS(expected, tok(code));
13591359
}
13601360
}
@@ -1489,7 +1489,7 @@ class TestSimplifyTypedef : public TestFixture {
14891489
// The expected result..
14901490
const char expected[] = "struct C { "
14911491
""
1492-
"const void * pr ; " // this gets simplified to a regular pointer
1492+
"const void ( * pr ) ( ) ; "
14931493
"operatorconstvoid(*)()& ( ) { return pr ; } "
14941494
"} ;";
14951495
ASSERT_EQUALS(expected, tok(code));
@@ -1552,7 +1552,7 @@ class TestSimplifyTypedef : public TestFixture {
15521552
" localEntitiyAddFunc_t f;\n"
15531553
"}";
15541554
// The expected result..
1555-
const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean * f ; }";
1555+
const char expected[] = "enum qboolean { qfalse , qtrue } ; void f ( ) { qboolean b ; qboolean ( * f ) ( ) ; }";
15561556
ASSERT_EQUALS(expected, tok(code, false));
15571557
ASSERT_EQUALS("", errout.str());
15581558
}
@@ -1669,7 +1669,7 @@ class TestSimplifyTypedef : public TestFixture {
16691669
const char code[] = "typedef FMAC1 void (* a) ();\n"
16701670
"void *(*b) ();";
16711671
const std::string actual(tok(code));
1672-
ASSERT_EQUALS("void * * b ;", actual);
1672+
ASSERT_EQUALS("void * ( * b ) ( ) ;", actual);
16731673
ASSERT_EQUALS("", errout.str());
16741674
}
16751675

@@ -2120,7 +2120,7 @@ class TestSimplifyTypedef : public TestFixture {
21202120
"};";
21212121
const char expected[] = "class symbol_table { "
21222122
"public: "
2123-
"expression_error :: error_code * f ; "
2123+
"expression_error :: error_code ( * f ) ( ) ; "
21242124
"} ;";
21252125
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
21262126
ASSERT_EQUALS("", errout.str());
@@ -2867,12 +2867,12 @@ class TestSimplifyTypedef : public TestFixture {
28672867

28682868
// The expected result..
28692869
const char expected[] = "C f1 ( ) ; "
2870-
"C * f2 ; " // this gets simplified to a regular pointer
2870+
"C ( * f2 ) ( ) ; "
28712871
"C ( & f3 ) ( ) ; "
2872-
"C * f4 ; " // this gets simplified to a regular pointer
2873-
"C * f5 ; " // this gets simplified to a regular pointer
2874-
"C * f6 ; " // this gets simplified to a regular pointer
2875-
"C * f7 ;"; // this gets simplified to a regular pointer
2872+
"C ( * f4 ) ( ) ; "
2873+
"C ( * f5 ) ( ) ; "
2874+
"C ( * f6 ) ( ) ; "
2875+
"C ( * f7 ) ( ) ;";
28762876
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
28772877
ASSERT_EQUALS("", errout.str());
28782878
}
@@ -2896,12 +2896,12 @@ class TestSimplifyTypedef : public TestFixture {
28962896
// The expected result..
28972897
// C const -> const C
28982898
const char expected[] = "const C f1 ( ) ; "
2899-
"const C * f2 ; " // this gets simplified to a regular pointer
2899+
"const C ( * f2 ) ( ) ; "
29002900
"const C ( & f3 ) ( ) ; "
2901-
"const C * f4 ; " // this gets simplified to a regular pointer
2902-
"const C * f5 ; " // this gets simplified to a regular pointer
2903-
"const C * f6 ; " // this gets simplified to a regular pointer
2904-
"const C * f7 ;"; // this gets simplified to a regular pointer
2901+
"const C ( * f4 ) ( ) ; "
2902+
"const C ( * f5 ) ( ) ; "
2903+
"const C ( * f6 ) ( ) ; "
2904+
"const C ( * f7 ) ( ) ;";
29052905
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
29062906
ASSERT_EQUALS("", errout.str());
29072907
}
@@ -2924,12 +2924,12 @@ class TestSimplifyTypedef : public TestFixture {
29242924

29252925
// The expected result..
29262926
const char expected[] = "const C f1 ( ) ; "
2927-
"const C * f2 ; " // this gets simplified to a regular pointer
2927+
"const C ( * f2 ) ( ) ; "
29282928
"const C ( & f3 ) ( ) ; "
2929-
"const C * f4 ; " // this gets simplified to a regular pointer
2930-
"const C * f5 ; " // this gets simplified to a regular pointer
2931-
"const C * f6 ; " // this gets simplified to a regular pointer
2932-
"const C * f7 ;"; // this gets simplified to a regular pointer
2929+
"const C ( * f4 ) ( ) ; "
2930+
"const C ( * f5 ) ( ) ; "
2931+
"const C ( * f6 ) ( ) ; "
2932+
"const C ( * f7 ) ( ) ;";
29332933
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
29342934
ASSERT_EQUALS("", errout.str());
29352935
}
@@ -2952,12 +2952,12 @@ class TestSimplifyTypedef : public TestFixture {
29522952

29532953
// The expected result..
29542954
const char expected[] = "C * f1 ( ) ; "
2955-
"C * * f2 ; " // this gets simplified to a regular pointer
2955+
"C * ( * f2 ) ( ) ; "
29562956
"C * ( & f3 ) ( ) ; "
2957-
"C * * f4 ; " // this gets simplified to a regular pointer
2958-
"C * * f5 ; " // this gets simplified to a regular pointer
2959-
"C * * f6 ; " // this gets simplified to a regular pointer
2960-
"C * * f7 ;"; // this gets simplified to a regular pointer
2957+
"C * ( * f4 ) ( ) ; "
2958+
"C * ( * f5 ) ( ) ; "
2959+
"C * ( * f6 ) ( ) ; "
2960+
"C * ( * f7 ) ( ) ;";
29612961
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
29622962
ASSERT_EQUALS("", errout.str());
29632963
}
@@ -2980,12 +2980,12 @@ class TestSimplifyTypedef : public TestFixture {
29802980

29812981
// The expected result..
29822982
const char expected[] = "const C * f1 ( ) ; "
2983-
"const C * * f2 ; " // this gets simplified to a regular pointer
2983+
"const C * ( * f2 ) ( ) ; "
29842984
"const C * ( & f3 ) ( ) ; "
2985-
"const C * * f4 ; " // this gets simplified to a regular pointer
2986-
"const C * * f5 ; " // this gets simplified to a regular pointer
2987-
"const C * * f6 ; " // this gets simplified to a regular pointer
2988-
"const C * * f7 ;"; // this gets simplified to a regular pointer
2985+
"const C * ( * f4 ) ( ) ; "
2986+
"const C * ( * f5 ) ( ) ; "
2987+
"const C * ( * f6 ) ( ) ; "
2988+
"const C * ( * f7 ) ( ) ;";
29892989
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
29902990
ASSERT_EQUALS("", errout.str());
29912991
}
@@ -3009,12 +3009,12 @@ class TestSimplifyTypedef : public TestFixture {
30093009
// The expected result..
30103010
// C const -> const C
30113011
const char expected[] = "const C * f1 ( ) ; "
3012-
"const C * * f2 ; " // this gets simplified to a regular pointer
3012+
"const C * ( * f2 ) ( ) ; "
30133013
"const C * ( & f3 ) ( ) ; "
3014-
"const C * * f4 ; " // this gets simplified to a regular pointer
3015-
"const C * * f5 ; " // this gets simplified to a regular pointer
3016-
"const C * * f6 ; " // this gets simplified to a regular pointer
3017-
"const C * * f7 ;"; // this gets simplified to a regular pointer
3014+
"const C * ( * f4 ) ( ) ; "
3015+
"const C * ( * f5 ) ( ) ; "
3016+
"const C * ( * f6 ) ( ) ; "
3017+
"const C * ( * f7 ) ( ) ;";
30183018
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
30193019
ASSERT_EQUALS("", errout.str());
30203020
}
@@ -3063,14 +3063,14 @@ class TestSimplifyTypedef : public TestFixture {
30633063
"type12 t12;";
30643064

30653065
// The expected result..
3066-
const char expected[] = "int * t1 ; " // simplified to regular pointer
3067-
"int * const t2 ; "
3068-
"int * volatile t3 ; "
3069-
"int * const volatile t4 ; "
3070-
"int * t5 ; "
3071-
"int * const t6 ; "
3072-
"int * volatile t7 ; "
3073-
"int * const volatile t8 ; "
3066+
const char expected[] = "int ( * t1 ) ( ) ; "
3067+
"int ( * const t2 ) ( ) ; "
3068+
"int ( * volatile t3 ) ( ) ; "
3069+
"int ( * const volatile t4 ) ( ) ; "
3070+
"int ( * t5 ) ( ) ; "
3071+
"int ( * const t6 ) ( ) ; "
3072+
"int ( * volatile t7 ) ( ) ; "
3073+
"int ( * const volatile t8 ) ( ) ; "
30743074
"int ( :: C :: * t9 ) ( float ) ; "
30753075
"int ( :: C :: * const t10 ) ( float ) ; "
30763076
"int ( :: C :: * volatile t11 ) ( float ) ; "
@@ -3156,10 +3156,10 @@ class TestSimplifyTypedef : public TestFixture {
31563156
"func4 f4;";
31573157

31583158
// The expected result..
3159-
const char expected[] = "B :: C * f1 ; "
3160-
"B :: C * f2 ; "
3161-
"B :: C * f3 ; "
3162-
"B :: C * f4 ;";
3159+
const char expected[] = "B :: C ( * f1 ) ( ) ; "
3160+
"B :: C ( * f2 ) ( ) ; "
3161+
"B :: C ( * f3 ) ( ) ; "
3162+
"B :: C ( * f4 ) ( ) ;";
31633163
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
31643164
ASSERT_EQUALS("", errout.str());
31653165
}
@@ -3194,10 +3194,10 @@ class TestSimplifyTypedef : public TestFixture {
31943194
"func4 f4;";
31953195

31963196
// The expected result..
3197-
const char expected[] = "A :: B :: C * f1 ; "
3198-
"A :: B :: C * f2 ; "
3199-
"A :: B :: C * f3 ; "
3200-
"A :: B :: C * f4 ;";
3197+
const char expected[] = "A :: B :: C ( * f1 ) ( ) ; "
3198+
"A :: B :: C ( * f2 ) ( ) ; "
3199+
"A :: B :: C ( * f3 ) ( ) ; "
3200+
"A :: B :: C ( * f4 ) ( ) ;";
32013201
ASSERT_EQUALS(expected, tok(code, true, Settings::Native, false));
32023202
ASSERT_EQUALS("", errout.str());
32033203
}
@@ -3216,8 +3216,8 @@ class TestSimplifyTypedef : public TestFixture {
32163216
"namespace MySpace { "
32173217
"enum Format_E2 { FORMAT21 , FORMAT22 } ; enum Format_E2 Format_T2 ; "
32183218
"} "
3219-
"Format_E1 * * t1 ; "
3220-
"MySpace :: Format_E2 * * t2 ;",
3219+
"Format_E1 ( * * t1 ) ( ) ; "
3220+
"MySpace :: Format_E2 ( * * t2 ) ( ) ;",
32213221
tok(code,false));
32223222
}
32233223

0 commit comments

Comments
 (0)