Syntax check: Using keyword in global scope

This commit is contained in:
Daniel Marjamäki 2020-04-11 17:36:11 +02:00
parent db4b1f9578
commit 97b04ba9a7
8 changed files with 175 additions and 122 deletions

View File

@ -9484,6 +9484,26 @@ void Tokenizer::findGarbageCode() const
} }
} }
// Keywords in global scope
std::set<std::string> nonGlobalKeywords{"break",
"continue",
"for",
"goto",
"if",
"return",
"switch",
"while"};
if (isCPP()) {
nonGlobalKeywords.insert("try");
nonGlobalKeywords.insert("catch");
}
for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (tok->str() == "{")
tok = tok->link();
else if (tok->isName() && nonGlobalKeywords.count(tok->str()) && !Token::Match(tok->tokAt(-2), "operator %str%"))
syntaxError(tok, "keyword '" + tok->str() + "' is not allowed in global scope");
}
// keyword keyword // keyword keyword
const std::set<std::string> nonConsecutiveKeywords{"break", const std::set<std::string> nonConsecutiveKeywords{"break",
"continue", "continue",

View File

@ -483,7 +483,7 @@ private:
} }
void garbageCode10() { // #6127 void garbageCode10() { // #6127
checkCode("for( rl=reslist; rl!=NULL; rl=rl->next )"); ASSERT_THROW(checkCode("for( rl=reslist; rl!=NULL; rl=rl->next )"), InternalError);
} }
void garbageCode12() { // do not crash void garbageCode12() { // do not crash

View File

@ -4086,7 +4086,7 @@ private:
// ok code (ticket #1985) // ok code (ticket #1985)
tok("void f()\n" tok("void f()\n"
"try { ;x<y; }"); "{ try { ;x<y; } }");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
// ok code (ticket #3183) // ok code (ticket #3183)

View File

@ -197,7 +197,6 @@ private:
TEST_CASE(while0); TEST_CASE(while0);
// ticket #3140 // ticket #3140
TEST_CASE(while0for); TEST_CASE(while0for);
TEST_CASE(while1);
TEST_CASE(duplicateDefinition); // ticket #3565 TEST_CASE(duplicateDefinition); // ticket #3565
@ -347,8 +346,8 @@ private:
void simplifyTokenList1() { void simplifyTokenList1() {
// #1717 : The simplifyErrNoInWhile needs to be used before simplifyIfAndWhileAssign.. // #1717 : The simplifyErrNoInWhile needs to be used before simplifyIfAndWhileAssign..
ASSERT_EQUALS("; x = f ( ) ; while ( x == -1 ) { x = f ( ) ; }", ASSERT_EQUALS("{ x = f ( ) ; while ( x == -1 ) { x = f ( ) ; } }",
tok(";while((x=f())==-1 && errno==EINTR){}",true)); tok("{ while((x=f())==-1 && errno==EINTR){}}",true));
} }
@ -1668,7 +1667,7 @@ private:
ASSERT_EQUALS("; x ( 1 ) = x ( 1 ) + 1 ;", tok("; x(1) += 1;")); ASSERT_EQUALS("; x ( 1 ) = x ( 1 ) + 1 ;", tok("; x(1) += 1;"));
// #2368 // #2368
ASSERT_EQUALS("{ j = j - i ; }", tok("if (false) {} else { j -= i; }")); ASSERT_EQUALS("{ j = j - i ; }", tok("{if (false) {} else { j -= i; }}"));
// #2714 - wrong simplification of "a += b?c:d;" // #2714 - wrong simplification of "a += b?c:d;"
ASSERT_EQUALS("; a = a + ( b ? c : d ) ;", tok("; a+=b?c:d;")); ASSERT_EQUALS("; a = a + ( b ? c : d ) ;", tok("; a+=b?c:d;"));
@ -1690,21 +1689,21 @@ private:
void cast() { void cast() {
ASSERT_EQUALS("if ( p == 0 ) { ; }", tok("if (p == (char *)0);")); ASSERT_EQUALS("{ if ( p == 0 ) { ; } }", tok("{if (p == (char *)0);}"));
ASSERT_EQUALS("return str ;", tok("return (char *)str;")); ASSERT_EQUALS("{ return str ; }", tok("{return (char *)str;}"));
ASSERT_EQUALS("if ( * a )", tok("if ((char)*a)")); ASSERT_EQUALS("{ if ( * a ) }", tok("{if ((char)*a)}"));
ASSERT_EQUALS("if ( & a )", tok("if ((int)&a)")); ASSERT_EQUALS("{ if ( & a ) }", tok("{if ((int)&a)}"));
ASSERT_EQUALS("if ( * a )", tok("if ((unsigned int)(unsigned char)*a)")); ASSERT_EQUALS("{ if ( * a ) }", tok("{if ((unsigned int)(unsigned char)*a)}"));
ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };")); ASSERT_EQUALS("class A { A operator* ( int ) ; } ;", tok("class A { A operator *(int); };"));
ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };")); ASSERT_EQUALS("class A { A operator* ( int ) const ; } ;", tok("class A { A operator *(int) const; };"));
ASSERT_EQUALS("if ( p == 0 ) { ; }", tok("if (p == (char *)(char *)0);")); ASSERT_EQUALS("{ if ( p == 0 ) { ; } }", tok("{ if (p == (char *)(char *)0); }"));
ASSERT_EQUALS("if ( p == 0 ) { ; }", tok("if (p == (char **)0);")); ASSERT_EQUALS("{ if ( p == 0 ) { ; } }", tok("{ if (p == (char **)0); }"));
// no simplification as the cast may be important here. see #2897 for example // no simplification as the cast may be important here. see #2897 for example
ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;")); ASSERT_EQUALS("; * ( ( char * ) p + 1 ) = 0 ;", tok("; *((char *)p + 1) = 0;"));
ASSERT_EQUALS("if ( true )", tok("if ((unsigned char)1)")); // #4164 ASSERT_EQUALS("{ if ( true ) }", tok("{ if ((unsigned char)1) }")); // #4164
ASSERT_EQUALS("f ( 200 )", tok("f((unsigned char)200)")); ASSERT_EQUALS("f ( 200 )", tok("f((unsigned char)200)"));
ASSERT_EQUALS("f ( ( char ) 1234 )", tok("f((char)1234)")); // don't simplify downcast ASSERT_EQUALS("f ( ( char ) 1234 )", tok("f((char)1234)")); // don't simplify downcast
} }
@ -2032,17 +2031,17 @@ private:
void parentheses1() { void parentheses1() {
ASSERT_EQUALS("a <= 110 ;", tok("a <= (10+100);")); ASSERT_EQUALS("a <= 110 ;", tok("a <= (10+100);"));
ASSERT_EQUALS("while ( x ( ) == -1 ) { }", tok("while((x()) == -1){ }")); ASSERT_EQUALS("{ while ( x ( ) == -1 ) { } }", tok("{while((x()) == -1){ }}"));
} }
void parenthesesVar() { void parenthesesVar() {
// remove parentheses.. // remove parentheses..
ASSERT_EQUALS("a = p ;", tok("a = (p);")); ASSERT_EQUALS("a = p ;", tok("a = (p);"));
ASSERT_EQUALS("if ( a < p ) { }", tok("if(a<(p)){}")); ASSERT_EQUALS("void f ( ) { if ( a < p ) { } }", tok("void f(){if(a<(p)){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p == -1 ) { } }", tok("void f(){int p; if((p)==-1){}}")); ASSERT_EQUALS("void f ( ) { int p ; if ( p == -1 ) { } }", tok("void f(){int p; if((p)==-1){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( -1 == p ) { } }", tok("void f(){int p; if(-1==(p)){}}")); ASSERT_EQUALS("void f ( ) { int p ; if ( -1 == p ) { } }", tok("void f(){int p; if(-1==(p)){}}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } }", tok("void f(){int p; if((p)){}}")); ASSERT_EQUALS("void f ( ) { int p ; if ( p ) { } }", tok("void f(){int p; if((p)){}}"));
ASSERT_EQUALS("return p ;", tok("return (p);")); ASSERT_EQUALS("void f ( ) { return p ; }", tok("void f(){return (p);}"));
ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*(p) == 0) {}}")); ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*(p) == 0) {}}"));
ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*p == 0) {}}")); ASSERT_EQUALS("void f ( ) { int * p ; if ( * p == 0 ) { } }", tok("void f(){int *p; if (*p == 0) {}}"));
ASSERT_EQUALS("void f ( int & p ) { p = 1 ; }", tok("void f(int &p) {(p) = 1;}")); ASSERT_EQUALS("void f ( int & p ) { p = 1 ; }", tok("void f(int &p) {(p) = 1;}"));
@ -2055,7 +2054,7 @@ private:
// keep parentheses.. // keep parentheses..
ASSERT_EQUALS("b = a ;", tok("b = (char)a;")); ASSERT_EQUALS("b = a ;", tok("b = (char)a;"));
ASSERT_EQUALS("cast < char * > ( p ) ;", tok("cast<char *>(p);")); ASSERT_EQUALS("cast < char * > ( p ) ;", tok("cast<char *>(p);"));
ASSERT_EQUALS("return ( a + b ) * c ;", tok("return (a+b)*c;")); ASSERT_EQUALS("void f ( ) { return ( a + b ) * c ; }", tok("void f(){return (a+b)*c;}"));
ASSERT_EQUALS("void f ( ) { int p ; if ( 2 * p == 0 ) { } }", tok("void f(){int p; if (2*p == 0) {}}")); ASSERT_EQUALS("void f ( ) { int p ; if ( 2 * p == 0 ) { } }", tok("void f(){int p; if (2*p == 0) {}}"));
ASSERT_EQUALS("void f ( ) { DIR * f ; f = opendir ( dirname ) ; if ( closedir ( f ) ) { } }", tok("void f(){DIR * f = opendir(dirname);if (closedir(f)){}}")); ASSERT_EQUALS("void f ( ) { DIR * f ; f = opendir ( dirname ) ; if ( closedir ( f ) ) { } }", tok("void f(){DIR * f = opendir(dirname);if (closedir(f)){}}"));
ASSERT_EQUALS("void foo ( int p ) { if ( p >= 0 ) { ; } }", tok("void foo(int p){if((p)>=0);}")); ASSERT_EQUALS("void foo ( int p ) { if ( p >= 0 ) { ; } }", tok("void foo(int p){if((p)>=0);}"));
@ -2147,11 +2146,11 @@ private:
} }
void elseif1() { void elseif1() {
const char code[] = "else if(ab) { cd } else { ef }gh;"; const char code[] = "void f(){ if(x) {} else if(ab) { cd } else { ef }gh; }";
ASSERT_EQUALS("\n\n##file 0\n1: else { if ( ab ) { cd } else { ef } } gh ;\n", tokenizeDebugListing(code)); ASSERT_EQUALS("\n\n##file 0\n1: void f ( ) { if ( x ) { } else { if ( ab ) { cd } else { ef } } gh ; }\n", tokenizeDebugListing(code));
// syntax error: assert there is no segmentation fault // syntax error: assert there is no segmentation fault
ASSERT_EQUALS("\n\n##file 0\n1: else if ( x ) { }\n", tokenizeDebugListing("else if (x) { }")); ASSERT_EQUALS("\n\n##file 0\n1: void f ( ) { if ( x ) { } else { if ( x ) { } } }\n", tokenizeDebugListing("void f(){ if(x) {} else if (x) { } }"));
{ {
const char src[] = "void f(int g,int f) {\n" const char src[] = "void f(int g,int f) {\n"
@ -2263,11 +2262,13 @@ private:
void sizeof5() { void sizeof5() {
const char code[] = const char code[] =
"{"
"const char * names[2];" "const char * names[2];"
"for (int i = 0; i != sizeof(names[0]); i++)" "for (int i = 0; i != sizeof(names[0]); i++)"
"{}"; "{}"
"}";
std::ostringstream expected; std::ostringstream expected;
expected << "const char * names [ 2 ] ; for ( int i = 0 ; i != " << sizeofFromTokenizer("*") << " ; i ++ ) { }"; expected << "{ const char * names [ 2 ] ; for ( int i = 0 ; i != " << sizeofFromTokenizer("*") << " ; i ++ ) { } }";
ASSERT_EQUALS(expected.str(), tok(code)); ASSERT_EQUALS(expected.str(), tok(code));
} }
@ -2923,10 +2924,10 @@ private:
} }
void ifassign1() { void ifassign1() {
ASSERT_EQUALS("; a = b ; if ( a ) { ; }", simplifyIfAndWhileAssign(";if(a=b);")); ASSERT_EQUALS("{ a = b ; if ( a ) { ; } }", simplifyIfAndWhileAssign("{if(a=b);}"));
ASSERT_EQUALS("; a = b ( ) ; if ( a ) { ; }", simplifyIfAndWhileAssign(";if((a=b()));")); ASSERT_EQUALS("{ a = b ( ) ; if ( a ) { ; } }", simplifyIfAndWhileAssign("{if((a=b()));}"));
ASSERT_EQUALS("; a = b ( ) ; if ( ! ( a ) ) { ; }", simplifyIfAndWhileAssign(";if(!(a=b()));")); ASSERT_EQUALS("{ a = b ( ) ; if ( ! ( a ) ) { ; } }", simplifyIfAndWhileAssign("{if(!(a=b()));}"));
ASSERT_EQUALS("; a . x = b ( ) ; if ( ! ( a . x ) ) { ; }", simplifyIfAndWhileAssign(";if(!(a->x=b()));")); ASSERT_EQUALS("{ a . x = b ( ) ; if ( ! ( a . x ) ) { ; } }", simplifyIfAndWhileAssign("{if(!(a->x=b()));}"));
ASSERT_EQUALS("void f ( ) { A ( ) a = b ; if ( a ) { ; } }", simplifyIfAndWhileAssign("void f() { A() if(a=b); }")); ASSERT_EQUALS("void f ( ) { A ( ) a = b ; if ( a ) { ; } }", simplifyIfAndWhileAssign("void f() { A() if(a=b); }"));
ASSERT_EQUALS("void foo ( int a ) { a = b ( ) ; if ( a >= 0 ) { ; } }", tok("void foo(int a) {if((a=b())>=0);}")); ASSERT_EQUALS("void foo ( int a ) { a = b ( ) ; if ( a >= 0 ) { ; } }", tok("void foo(int a) {if((a=b())>=0);}"));
TODO_ASSERT_EQUALS("void foo ( A a ) { a . c = b ( ) ; if ( 0 <= a . c ) { ; } }", TODO_ASSERT_EQUALS("void foo ( A a ) { a . c = b ( ) ; if ( 0 <= a . c ) { ; } }",
@ -2956,17 +2957,21 @@ private:
} }
void whileAssign1() { void whileAssign1() {
ASSERT_EQUALS("; a = b ; while ( a ) { b = 0 ; a = b ; }", simplifyIfAndWhileAssign(";while(a=b) { b = 0; }")); ASSERT_EQUALS("{ a = b ; while ( a ) { b = 0 ; a = b ; } }", simplifyIfAndWhileAssign("{while(a=b) { b = 0; }}"));
ASSERT_EQUALS("; a . b = c ; while ( a . b ) { c = 0 ; a . b = c ; }", simplifyIfAndWhileAssign(";while(a.b=c) { c=0; }")); ASSERT_EQUALS("{ a . b = c ; while ( a . b ) { c = 0 ; a . b = c ; } }", simplifyIfAndWhileAssign("{while(a.b=c) { c=0; }}"));
ASSERT_EQUALS("struct hfs_bnode * node ; " ASSERT_EQUALS("{ "
"struct hfs_bnode * node ; "
"struct hfs_btree * tree ; " "struct hfs_btree * tree ; "
"node = tree . node_hash [ i ++ ] ; " "node = tree . node_hash [ i ++ ] ; "
"while ( node ) { node = tree . node_hash [ i ++ ] ; }", "while ( node ) { node = tree . node_hash [ i ++ ] ; } "
tok("struct hfs_bnode *node;" "}",
tok("{"
"struct hfs_bnode *node;"
"struct hfs_btree *tree;" "struct hfs_btree *tree;"
"while ((node = tree->node_hash[i++])) { }")); "while ((node = tree->node_hash[i++])) { }"
ASSERT_EQUALS("char * s ; s = new char [ 10 ] ; while ( ! s ) { s = new char [ 10 ] ; }", "}"));
tok("char *s; while (0 == (s=new char[10])) { }")); ASSERT_EQUALS("{ char * s ; s = new char [ 10 ] ; while ( ! s ) { s = new char [ 10 ] ; } }",
tok("{ char *s; while (0 == (s=new char[10])) { } }"));
} }
void whileAssign2() { void whileAssign2() {
@ -2999,11 +3004,11 @@ private:
errout.str(""); errout.str("");
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
std::istringstream istr("; while (!(m = q->push<Message>(x))) {}"); std::istringstream istr("{ while (!(m = q->push<Message>(x))) {} }");
tokenizer.tokenize(istr, "test.cpp"); tokenizer.tokenize(istr, "test.cpp");
tokenizer.simplifyTokenList2(); tokenizer.simplifyTokenList2();
ASSERT_EQUALS("; m = q . push < Message > ( x ) ; while ( ! m ) { m = q . push < Message > ( x ) ; }", tokenizer.tokens()->stringifyList(nullptr, false)); ASSERT_EQUALS("{ m = q . push < Message > ( x ) ; while ( ! m ) { m = q . push < Message > ( x ) ; } }", tokenizer.tokens()->stringifyList(nullptr, false));
ASSERT(tokenizer.tokens()->tokAt(26) != nullptr); ASSERT(tokenizer.tokens()->tokAt(26) != nullptr);
if (tokenizer.tokens()->tokAt(26)) { if (tokenizer.tokens()->tokAt(26)) {
ASSERT(tokenizer.tokens()->linkAt(6) == tokenizer.tokens()->tokAt(8)); ASSERT(tokenizer.tokens()->linkAt(6) == tokenizer.tokens()->tokAt(8));
@ -3012,18 +3017,22 @@ private:
} }
void doWhileAssign() { void doWhileAssign() {
ASSERT_EQUALS("; do { a = b ; } while ( a ) ;", simplifyIfAndWhileAssign(";do { } while(a=b);")); ASSERT_EQUALS("{ do { a = b ; } while ( a ) ; }", simplifyIfAndWhileAssign("{ do { } while(a=b); }"));
ASSERT_EQUALS("; do { a . a = 0 ; a . b = c ; } while ( a . b ) ;", simplifyIfAndWhileAssign(";do { a.a = 0; } while(a.b=c);")); ASSERT_EQUALS("{ do { a . a = 0 ; a . b = c ; } while ( a . b ) ; }", simplifyIfAndWhileAssign("{ do { a.a = 0; } while(a.b=c); }"));
ASSERT_EQUALS("struct hfs_bnode * node ; " ASSERT_EQUALS("{ "
"struct hfs_bnode * node ; "
"struct hfs_btree * tree ; " "struct hfs_btree * tree ; "
"do { node = tree . node_hash [ i ++ ] ; } while ( node ) ;", "do { node = tree . node_hash [ i ++ ] ; } while ( node ) ; "
tok("struct hfs_bnode *node;" "}",
tok("{"
"struct hfs_bnode *node;"
"struct hfs_btree *tree;" "struct hfs_btree *tree;"
"do { } while((node = tree->node_hash[i++]));")); "do { } while((node = tree->node_hash[i++]));"
ASSERT_EQUALS("char * s ; do { s = new char [ 10 ] ; } while ( ! s ) ;", "}"));
tok("char *s; do { } while (0 == (s=new char[10]));")); ASSERT_EQUALS("void foo ( ) { char * s ; do { s = new char [ 10 ] ; } while ( ! s ) ; }",
tok("void foo() { char *s; do { } while (0 == (s=new char[10])); }"));
// #4911 // #4911
ASSERT_EQUALS("; do { current = f ( ) ; } while ( ( current ) != NULL ) ;", simplifyIfAndWhileAssign(";do { } while((current=f()) != NULL);")); ASSERT_EQUALS("void foo ( ) { do { current = f ( ) ; } while ( ( current ) != NULL ) ; }", simplifyIfAndWhileAssign("void foo() { do { } while((current=f()) != NULL); }"));
} }
void not1() { void not1() {
@ -3255,7 +3264,7 @@ private:
} }
{ {
ASSERT_EQUALS("; return a ? ( b = c , d ) : e ;", tok("; return a ? b = c , d : e ;")); // Keep comma ASSERT_EQUALS("{ return a ? ( b = c , d ) : e ; }", tok("{ return a ? b = c , d : e ; }")); // Keep comma
} }
{ {
@ -3486,9 +3495,9 @@ private:
ASSERT_EQUALS(";", tok("; x = x + 0;")); ASSERT_EQUALS(";", tok("; x = x + 0;"));
ASSERT_EQUALS("if ( a == 2 ) { ; }", tok("if (a==1+1);")); ASSERT_EQUALS("{ if ( a == 2 ) { } }", tok("{if (a==1+1){}}"));
ASSERT_EQUALS("if ( a + 2 != 6 ) { ; }", tok("if (a+1+1!=1+2+3);")); ASSERT_EQUALS("{ if ( a + 2 != 6 ) { } }", tok("{if (a+1+1!=1+2+3){}}"));
ASSERT_EQUALS("if ( 4 < a ) { ; }", tok("if (14-2*5<a*4/(2*2));")); ASSERT_EQUALS("{ if ( 4 < a ) { } }", tok("{if (14-2*5<a*4/(2*2)){}}"));
ASSERT_EQUALS("( y / 2 - 2 ) ;", tok("(y / 2 - 2);")); ASSERT_EQUALS("( y / 2 - 2 ) ;", tok("(y / 2 - 2);"));
ASSERT_EQUALS("( y % 2 - 2 ) ;", tok("(y % 2 - 2);")); ASSERT_EQUALS("( y % 2 - 2 ) ;", tok("(y % 2 - 2);"));
@ -4167,13 +4176,13 @@ private:
} }
void while0() { void while0() {
ASSERT_EQUALS("; x = 1 ;", tok("; do { x = 1 ; } while (0);")); ASSERT_EQUALS("void foo ( ) { x = 1 ; }", tok("void foo() { do { x = 1 ; } while (0);}"));
ASSERT_EQUALS("; return 0 ;", tok("; do { return 0; } while (0);")); ASSERT_EQUALS("void foo ( ) { return 0 ; }", tok("void foo() { do { return 0; } while (0);}"));
ASSERT_EQUALS("void foo ( ) { goto label ; }", tok("void foo() { do { goto label; } while (0); }")); ASSERT_EQUALS("void foo ( ) { goto label ; }", tok("void foo() { do { goto label; } while (0); }"));
ASSERT_EQUALS("; { continue ; }", tok("; do { continue ; } while (0);")); ASSERT_EQUALS("void foo ( ) { continue ; }", tok("void foo() { do { continue ; } while (0); }"));
ASSERT_EQUALS("; { break ; }", tok("; do { break; } while (0);")); ASSERT_EQUALS("void foo ( ) { break ; }", tok("void foo() { do { break; } while (0); }"));
ASSERT_EQUALS(";", tok("; while (false) { a; }")); ASSERT_EQUALS("void foo ( ) { }", tok("void foo() { while (false) { a; } }"));
ASSERT_EQUALS(";", tok("; while (false) { switch (n) { case 0: return; default: break; } n*=1; }")); ASSERT_EQUALS("void foo ( ) { }", tok("void foo() { while (false) { switch (n) { case 0: return; default: break; } n*=1; } }"));
} }
void while0for() { void while0for() {
@ -4191,16 +4200,9 @@ private:
ASSERT_EQUALS("void f ( ) { int i ; for ( i = 0 ; i < 0 ; ++ i ) { } return i ; }", tok("void f() { int i; for (i=0;i<0;++i){ dostuff(); } return i; }")); ASSERT_EQUALS("void f ( ) { int i ; for ( i = 0 ; i < 0 ; ++ i ) { } return i ; }", tok("void f() { int i; for (i=0;i<0;++i){ dostuff(); } return i; }"));
} }
void while1() {
// ticket #1197
const char code[] = "void do {} while (0) { }";
const char expected[] = "void { }";
ASSERT_EQUALS(expected, tok(code));
}
void duplicateDefinition() { // #3565 - wrongly detects duplicate definition void duplicateDefinition() { // #3565 - wrongly detects duplicate definition
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
std::istringstream istr("x ; return a not_eq x;"); std::istringstream istr("{ x ; return a not_eq x; }");
tokenizer.tokenize(istr, "test.c"); tokenizer.tokenize(istr, "test.c");
Token *x_token = tokenizer.list.front()->tokAt(5); Token *x_token = tokenizer.list.front()->tokAt(5);
ASSERT_EQUALS(false, tokenizer.duplicateDefinition(&x_token)); ASSERT_EQUALS(false, tokenizer.duplicateDefinition(&x_token));
@ -4255,29 +4257,34 @@ private:
} }
void simplifyErrNoInWhile() { void simplifyErrNoInWhile() {
ASSERT_EQUALS("; while ( f ( ) ) { }", ASSERT_EQUALS("{ while ( f ( ) ) { } }",
tok("; while (f() && errno == EINTR) { }")); tok("{ while (f() && errno == EINTR) { } }"));
ASSERT_EQUALS("; while ( f ( ) ) { }", ASSERT_EQUALS("{ while ( f ( ) ) { } }",
tok("; while (f() && (errno == EINTR)) { }")); tok("{ while (f() && (errno == EINTR)) { } }"));
} }
void simplifyFuncInWhile() { void simplifyFuncInWhile() {
ASSERT_EQUALS("int cppcheck:r1 = fclose ( f ) ; " ASSERT_EQUALS("{ "
"int cppcheck:r1 = fclose ( f ) ; "
"while ( cppcheck:r1 ) " "while ( cppcheck:r1 ) "
"{ " "{ "
"foo ( ) ; " "foo ( ) ; "
"cppcheck:r1 = fclose ( f ) ; " "cppcheck:r1 = fclose ( f ) ; "
"} "
"}", "}",
tok("while(fclose(f))foo();")); tok("{while(fclose(f))foo();}"));
ASSERT_EQUALS("int cppcheck:r1 = fclose ( f ) ; " ASSERT_EQUALS("{ "
"int cppcheck:r1 = fclose ( f ) ; "
"while ( cppcheck:r1 ) " "while ( cppcheck:r1 ) "
"{ " "{ "
"; cppcheck:r1 = fclose ( f ) ; " "; cppcheck:r1 = fclose ( f ) ; "
"} "
"}", "}",
tok("while(fclose(f));")); tok("{while(fclose(f));}"));
ASSERT_EQUALS("int cppcheck:r1 = fclose ( f ) ; " ASSERT_EQUALS("{ "
"int cppcheck:r1 = fclose ( f ) ; "
"while ( cppcheck:r1 ) " "while ( cppcheck:r1 ) "
"{ " "{ "
"; cppcheck:r1 = fclose ( f ) ; " "; cppcheck:r1 = fclose ( f ) ; "
@ -4286,8 +4293,9 @@ private:
"while ( cppcheck:r2 ) " "while ( cppcheck:r2 ) "
"{ " "{ "
"; cppcheck:r2 = fclose ( g ) ; " "; cppcheck:r2 = fclose ( g ) ; "
"} "
"}", "}",
tok("while(fclose(f)); while(fclose(g));")); tok("{while(fclose(f)); while(fclose(g));}"));
} }
void simplifyStructDecl1() { void simplifyStructDecl1() {

View File

@ -390,36 +390,54 @@ private:
} }
void suspiciousSizeofCalculation() { void suspiciousSizeofCalculation() {
check("int* p;\n" check("void f() {\n"
"return sizeof(p)/5;"); " int* p;\n"
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Division of result of sizeof() on pointer type.\n", errout.str()); " return sizeof(p)/5;\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Division of result of sizeof() on pointer type.\n", errout.str());
check("unknown p;\n" check("void f() {\n"
"return sizeof(p)/5;"); " unknown p;\n"
" return sizeof(p)/5;\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("return sizeof(unknown)/5;"); check("void f() {\n"
" return sizeof(unknown)/5;\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int p;\n" check("void f() {\n"
"return sizeof(p)/5;"); " int p;\n"
" return sizeof(p)/5;\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int* p[5];\n" check("void f() {\n"
"return sizeof(p)/5;"); " int* p[5];\n"
" return sizeof(p)/5;\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("return sizeof(foo)*sizeof(bar);"); check("void f() {\n"
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Multiplying sizeof() with sizeof() indicates a logic error.\n", errout.str()); " return sizeof(foo)*sizeof(bar);\n"
"}");
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Multiplying sizeof() with sizeof() indicates a logic error.\n", errout.str());
check("return (foo)*sizeof(bar);"); check("void f() {\n"
" return (foo)*sizeof(bar);\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("return sizeof(foo)*bar;"); check("void f() {\n"
" return sizeof(foo)*bar;\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("return (end - source) / sizeof(encode_block_type) * sizeof(encode_block_type);"); check("void f() {\n"
" return (end - source) / sizeof(encode_block_type) * sizeof(encode_block_type);\n"
"}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }

View File

@ -2648,7 +2648,7 @@ private:
void symboldatabase17() { void symboldatabase17() {
// ticket #2657 - segmentation fault // ticket #2657 - segmentation fault
check("return f(){}"); check("{return f(){}}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -6826,7 +6826,7 @@ private:
string.arrayLike_indexOp = string.stdStringLike = true; string.arrayLike_indexOp = string.stdStringLike = true;
set.library.containers["test::string"] = string; set.library.containers["test::string"] = string;
ASSERT_EQUALS("signed int", typeOf("Vector<int> v; v[0]=3;", "[", "test.cpp", &set)); ASSERT_EQUALS("signed int", typeOf("Vector<int> v; v[0]=3;", "[", "test.cpp", &set));
ASSERT_EQUALS("container(test :: string)", typeOf("return test::string();", "(", "test.cpp", &set)); ASSERT_EQUALS("container(test :: string)", typeOf("{return test::string();}", "(", "test.cpp", &set));
ASSERT_EQUALS("container(test :: string)", typeOf("void foo(Vector<test::string> v) { for (auto s: v) { x=s+s; } }", "s", "test.cpp", &set)); ASSERT_EQUALS("container(test :: string)", typeOf("void foo(Vector<test::string> v) { for (auto s: v) { x=s+s; } }", "s", "test.cpp", &set));
ASSERT_EQUALS("container(test :: string)", typeOf("void foo(Vector<test::string> v) { for (auto s: v) { x=s+s; } }", "+", "test.cpp", &set)); ASSERT_EQUALS("container(test :: string)", typeOf("void foo(Vector<test::string> v) { for (auto s: v) { x=s+s; } }", "+", "test.cpp", &set));
} }

View File

@ -1108,14 +1108,14 @@ private:
const Token *const tok2 = Token::findsimplematch(var2.tokens(), "*"); const Token *const tok2 = Token::findsimplematch(var2.tokens(), "*");
ASSERT_EQUALS("*((unsigned long long*)x)", tok2->expressionString()); ASSERT_EQUALS("*((unsigned long long*)x)", tok2->expressionString());
givenACodeSampleToTokenize data3("return (t){1,2};"); givenACodeSampleToTokenize data3("void f() { return (t){1,2}; }");
ASSERT_EQUALS("return(t){1,2}", data3.tokens()->expressionString()); ASSERT_EQUALS("return(t){1,2}", data3.tokens()->tokAt(5)->expressionString());
givenACodeSampleToTokenize data4("return L\"a\";"); givenACodeSampleToTokenize data4("void f() { return L\"a\"; }");
ASSERT_EQUALS("returnL\"a\"", data4.tokens()->expressionString()); ASSERT_EQUALS("returnL\"a\"", data4.tokens()->tokAt(5)->expressionString());
givenACodeSampleToTokenize data5("return U\"a\";"); givenACodeSampleToTokenize data5("void f() { return U\"a\"; }");
ASSERT_EQUALS("returnU\"a\"", data5.tokens()->expressionString()); ASSERT_EQUALS("returnU\"a\"", data5.tokens()->tokAt(5)->expressionString());
} }
void hasKnownIntValue() { void hasKnownIntValue() {

View File

@ -1018,8 +1018,8 @@ private:
void simplifyCasts4() { void simplifyCasts4() {
// ticket #970 // ticket #970
const char code[] = "if (a >= (unsigned)(b)) {}"; const char code[] = "{if (a >= (unsigned)(b)) {}}";
const char expected[] = "if ( a >= ( unsigned int ) ( b ) ) { }"; const char expected[] = "{ if ( a >= ( unsigned int ) ( b ) ) { } }";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true)); ASSERT_EQUALS(expected, tokenizeAndStringify(code, true));
} }
@ -1091,8 +1091,8 @@ private:
} }
void simplifyCasts17() { // #6110 - don't remove any parentheses in 'a(b)(c)' void simplifyCasts17() { // #6110 - don't remove any parentheses in 'a(b)(c)'
ASSERT_EQUALS("if ( a ( b ) ( c ) >= 3 )", ASSERT_EQUALS("{ if ( a ( b ) ( c ) >= 3 ) { } }",
tokenizeAndStringify("if (a(b)(c) >= 3)", true)); tokenizeAndStringify("{ if (a(b)(c) >= 3) { } }", true));
} }
void simplifyAt() { void simplifyAt() {
@ -1151,8 +1151,8 @@ private:
ASSERT_THROW(ASSERT_EQUALS("; return f ( a [ b = c ] , asm ( \"^{}\" ) ) ;", ASSERT_THROW(ASSERT_EQUALS("; return f ( a [ b = c ] , asm ( \"^{}\" ) ) ;",
tokenizeAndStringify("; return f(a[b=c],^{});")), InternalError); // #7185 tokenizeAndStringify("; return f(a[b=c],^{});")), InternalError); // #7185
ASSERT_EQUALS("; return f ( asm ( \"^(void){somecode}\" ) ) ;", ASSERT_EQUALS("{ return f ( asm ( \"^(void){somecode}\" ) ) ; }",
tokenizeAndStringify("; return f(^(void){somecode});")); tokenizeAndStringify("{ return f(^(void){somecode}); }"));
ASSERT_THROW(ASSERT_EQUALS("; asm ( \"a?(b?(c,asm(\"^{}\")):0):^{}\" ) ;", ASSERT_THROW(ASSERT_EQUALS("; asm ( \"a?(b?(c,asm(\"^{}\")):0):^{}\" ) ;",
tokenizeAndStringify(";a?(b?(c,^{}):0):^{};")), InternalError); tokenizeAndStringify(";a?(b?(c,^{}):0):^{};")), InternalError);
ASSERT_EQUALS("template < typename T > " ASSERT_EQUALS("template < typename T > "
@ -1387,28 +1387,28 @@ private:
} }
void whileAddBraces() { void whileAddBraces() {
const char code[] = ";while(a);"; const char code[] = "{while(a);}";
ASSERT_EQUALS("; while ( a ) { ; }", tokenizeAndStringify(code, true)); ASSERT_EQUALS("{ while ( a ) { ; } }", tokenizeAndStringify(code, true));
} }
void doWhileAddBraces() { void doWhileAddBraces() {
{ {
const char code[] = "do ; while (0);"; const char code[] = "{do ; while (0);}";
const char result[] = "do { ; } while ( 0 ) ;"; const char result[] = "{ do { ; } while ( 0 ) ; }";
ASSERT_EQUALS(result, tokenizeAndStringify(code, false)); ASSERT_EQUALS(result, tokenizeAndStringify(code, false));
} }
{ {
const char code[] = "UNKNOWN_MACRO ( do ) ; while ( a -- ) ;"; const char code[] = "{ UNKNOWN_MACRO ( do ) ; while ( a -- ) ; }";
const char result[] = "UNKNOWN_MACRO ( do ) ; while ( a -- ) { ; }"; const char result[] = "{ UNKNOWN_MACRO ( do ) ; while ( a -- ) { ; } }";
ASSERT_EQUALS(result, tokenizeAndStringify(code, true)); ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
} }
{ {
const char code[] = "UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) ;"; const char code[] = "{ UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) ; }";
const char result[] = "UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) { ; }"; const char result[] = "{ UNKNOWN_MACRO ( do , foo ) ; while ( a -- ) { ; } }";
ASSERT_EQUALS(result, tokenizeAndStringify(code, true)); ASSERT_EQUALS(result, tokenizeAndStringify(code, true));
} }
@ -3345,7 +3345,7 @@ private:
} }
void removeParentheses14() { void removeParentheses14() {
ASSERT_EQUALS("; if ( ( i & 1 ) == 0 ) { ; } ;", tokenizeAndStringify("; if ( (i & 1) == 0 ); ;", false)); ASSERT_EQUALS("{ if ( ( i & 1 ) == 0 ) { ; } }", tokenizeAndStringify("{ if ( (i & 1) == 0 ); }", false));
} }
void removeParentheses15() { void removeParentheses15() {
@ -4592,7 +4592,7 @@ private:
{ {
// if (a < b || c > d) { } // if (a < b || c > d) { }
const char code[] = "if (a < b || c > d);"; const char code[] = "{ if (a < b || c > d); }";
errout.str(""); errout.str("");
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code); std::istringstream istr(code);
@ -4628,7 +4628,7 @@ private:
{ {
// if (a < ... > d) { } // if (a < ... > d) { }
const char code[] = "if (a < b || c == 3 || d > e);"; const char code[] = "{ if (a < b || c == 3 || d > e); }";
errout.str(""); errout.str("");
Tokenizer tokenizer(&settings0, this); Tokenizer tokenizer(&settings0, this);
std::istringstream istr(code); std::istringstream istr(code);
@ -5512,8 +5512,8 @@ private:
} }
{ {
const char code[] = "return doSomething(X), 0;"; const char code[] = "{ return doSomething(X), 0; }";
ASSERT_EQUALS("return doSomething ( X ) , 0 ;", tokenizeAndStringify(code, false)); ASSERT_EQUALS("{ return doSomething ( X ) , 0 ; }", tokenizeAndStringify(code, false));
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
@ -5896,10 +5896,14 @@ private:
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false)); ASSERT_EQUALS(expected, tokenizeAndStringify(code, false));
code = "using namespace std;\n" code = "using namespace std;\n"
"try { }\n" "void f() {\n"
"catch(std::exception &exception) { }"; " try { }\n"
expected = "try { }\n" " catch(std::exception &exception) { }\n"
"catch ( std :: exception & exception ) { }"; "}";
expected = "void f ( ) {\n"
"try { }\n"
"catch ( std :: exception & exception ) { }\n"
"}";
ASSERT_EQUALS(expected, tokenizeAndStringify(code, false)); ASSERT_EQUALS(expected, tokenizeAndStringify(code, false));
// #5773 (Don't prepend 'std ::' to function definitions) // #5773 (Don't prepend 'std ::' to function definitions)
@ -6361,8 +6365,8 @@ private:
const char code1[] = "using a::operator=;"; const char code1[] = "using a::operator=;";
ASSERT_EQUALS("using a :: operator= ;", tokenizeAndStringify(code1)); ASSERT_EQUALS("using a :: operator= ;", tokenizeAndStringify(code1));
const char code2[] = "return &Fred::operator!=;"; const char code2[] = "{ return &Fred::operator!=; }";
ASSERT_EQUALS("return & Fred :: operator!= ;", tokenizeAndStringify(code2)); ASSERT_EQUALS("{ return & Fred :: operator!= ; }", tokenizeAndStringify(code2));
} }
void simplifyOperatorName11() { // #8889 void simplifyOperatorName11() { // #8889
@ -8000,6 +8004,9 @@ private:
} }
void findGarbageCode() { // Test Tokenizer::findGarbageCode() void findGarbageCode() { // Test Tokenizer::findGarbageCode()
// C++ try/catch in global scope
ASSERT_THROW_EQUALS(tokenizeAndStringify("void f() try { }"), InternalError, "syntax error: keyword 'try' is not allowed in global scope");
// before if|for|while|switch // before if|for|while|switch
ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }")) ASSERT_NO_THROW(tokenizeAndStringify("void f() { do switch (a) {} while (1); }"))
ASSERT_NO_THROW(tokenizeAndStringify("void f() { label: switch (a) {} }")); ASSERT_NO_THROW(tokenizeAndStringify("void f() { label: switch (a) {} }"));