Fix issue 8740: Add a pass to check for valid operators (#1372)
This commit is contained in:
parent
18eff25c98
commit
fa40b821e6
|
@ -1202,6 +1202,30 @@ void TokenList::validateAst() const
|
||||||
} else {
|
} else {
|
||||||
safeAstTokens.insert(tok);
|
safeAstTokens.insert(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check binary operators
|
||||||
|
if (Token::Match(tok, "%or%|%oror%|%assign%|%comp%")) {
|
||||||
|
// Skip lambda captures
|
||||||
|
if (Token::Match(tok, "= ,|]"))
|
||||||
|
continue;
|
||||||
|
// Dont check templates
|
||||||
|
if (tok->link())
|
||||||
|
continue;
|
||||||
|
// Skip pure virtual functions
|
||||||
|
if (Token::simpleMatch(tok->previous(), ") = 0"))
|
||||||
|
continue;
|
||||||
|
// Skip incomplete code
|
||||||
|
if (!tok->astOperand1() && !tok->astOperand2() && !tok->astParent())
|
||||||
|
continue;
|
||||||
|
// FIXME
|
||||||
|
if (Token::Match(tok->previous(), "%name%") && Token::Match(tok->next(), "%name%"))
|
||||||
|
continue;
|
||||||
|
// Skip lambda assignment and/or initializer
|
||||||
|
if (Token::Match(tok, "= {|^"))
|
||||||
|
continue;
|
||||||
|
if (!tok->astOperand1() || !tok->astOperand2())
|
||||||
|
throw InternalError(tok, "Syntax Error: AST broken, binary operator doesn't have two operands.", InternalError::AST);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void testautovar12() { // Ticket #5024, #5050 - Crash on invalid input
|
void testautovar12() { // Ticket #5024, #5050 - Crash on invalid input
|
||||||
check("void f(int* a) { a = }");
|
ASSERT_THROW(check("void f(int* a) { a = }"), InternalError);
|
||||||
check("struct custom_type { custom_type(int) {} };\n"
|
check("struct custom_type { custom_type(int) {} };\n"
|
||||||
"void func(int) {}\n"
|
"void func(int) {}\n"
|
||||||
"int var;\n"
|
"int var;\n"
|
||||||
|
|
|
@ -2353,7 +2353,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void clarifyCondition5() { // ticket #3609 (using | in template instantiation)
|
void clarifyCondition5() { // ticket #3609 (using | in template instantiation)
|
||||||
check("CWinTraits<WS_CHILD|WS_VISIBLE>::GetWndStyle(0);");
|
check("template<bool B> struct CWinTraits;\n"
|
||||||
|
"CWinTraits<WS_CHILD|WS_VISIBLE>::GetWndStyle(0);");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,8 @@ private:
|
||||||
TEST_CASE(garbageCode190); // #8307
|
TEST_CASE(garbageCode190); // #8307
|
||||||
TEST_CASE(garbageCode191); // #8333
|
TEST_CASE(garbageCode191); // #8333
|
||||||
TEST_CASE(garbageCode192); // #8386 (segmentation fault)
|
TEST_CASE(garbageCode192); // #8386 (segmentation fault)
|
||||||
|
TEST_CASE(garbageCode193); // #8740
|
||||||
|
TEST_CASE(garbageCode194); // #8384
|
||||||
|
|
||||||
TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1
|
TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1
|
||||||
|
|
||||||
|
@ -630,15 +632,15 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode49() { // #6715
|
void garbageCode49() { // #6715
|
||||||
checkCode(" ( ( ) ) { } ( { ( __builtin_va_arg_pack ( ) ) ; } ) { ( int { ( ) ( ( ) ) } ( ) { } ( ) ) += ( ) }");
|
ASSERT_THROW(checkCode(" ( ( ) ) { } ( { ( __builtin_va_arg_pack ( ) ) ; } ) { ( int { ( ) ( ( ) ) } ( ) { } ( ) ) += ( ) }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode51() { // #6719
|
void garbageCode51() { // #6719
|
||||||
checkCode(" (const \"C\" ...); struct base { int f2; base (int arg1, int arg2); }; global_base(0x55, 0xff); { ((global_base.f1 0x55) (global_base.f2 0xff)) { } } base::base(int arg1, int arg2) { f2 = }");
|
ASSERT_THROW(checkCode(" (const \"C\" ...); struct base { int f2; base (int arg1, int arg2); }; global_base(0x55, 0xff); { ((global_base.f1 0x55) (global_base.f2 0xff)) { } } base::base(int arg1, int arg2) { f2 = }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode53() { // #6721
|
void garbageCode53() { // #6721
|
||||||
checkCode("{ { } }; void foo (struct int i) { x->b[i] = = }");
|
ASSERT_THROW(checkCode("{ { } }; void foo (struct int i) { x->b[i] = = }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode54() { // #6722
|
void garbageCode54() { // #6722
|
||||||
|
@ -659,7 +661,7 @@ private:
|
||||||
|
|
||||||
void garbageCode58() { // #6732, #6762
|
void garbageCode58() { // #6732, #6762
|
||||||
checkCode("{ }> {= ~A()^{} }P { }");
|
checkCode("{ }> {= ~A()^{} }P { }");
|
||||||
checkCode("{= ~A()^{} }P { } { }> is");
|
ASSERT_THROW(checkCode("{= ~A()^{} }P { } { }> is"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode59() { // #6735
|
void garbageCode59() { // #6735
|
||||||
|
@ -763,7 +765,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode87() { // #6788
|
void garbageCode87() { // #6788
|
||||||
checkCode("((X (128))) (int a) { v[ = {} (x 42) a] += }"); // do not crash
|
ASSERT_THROW(checkCode("((X (128))) (int a) { v[ = {} (x 42) a] += }"), InternalError); // do not crash
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode88() { // #6786
|
void garbageCode88() { // #6786
|
||||||
|
@ -788,7 +790,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode95() { // #6804
|
void garbageCode95() { // #6804
|
||||||
checkCode("{ } x x ; { } h h [ ] ( ) ( ) { struct x ( x ) ; int __attribute__ ( ) f ( ) { h - > first = & x ; struct x * n = h - > first ; ( ) n > } }"); // do not crash
|
ASSERT_THROW(checkCode("{ } x x ; { } h h [ ] ( ) ( ) { struct x ( x ) ; int __attribute__ ( ) f ( ) { h - > first = & x ; struct x * n = h - > first ; ( ) n > } }"), InternalError); // do not crash
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode96() { // #6807
|
void garbageCode96() { // #6807
|
||||||
|
@ -813,7 +815,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode100() { // #6840
|
void garbageCode100() { // #6840
|
||||||
checkCode("( ) { ( i< ) } int foo ( ) { int i ; ( for ( i => 1 ) ; ) }");
|
ASSERT_THROW(checkCode("( ) { ( i< ) } int foo ( ) { int i ; ( for ( i => 1 ) ; ) }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode101() { // #6835
|
void garbageCode101() { // #6835
|
||||||
|
@ -832,7 +834,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode104() { // #6847
|
void garbageCode104() { // #6847
|
||||||
checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }");
|
ASSERT_THROW(checkCode("template < Types > struct S {> ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) } { ( )> >} { ( ) { } } ( ) { ( ) }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode105() { // #6859
|
void garbageCode105() { // #6859
|
||||||
|
@ -930,7 +932,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode125() {
|
void garbageCode125() {
|
||||||
checkCode("{ T struct B : T valueA_AA ; } T : [ T > ( ) { B } template < T > struct A < > : ] { ( ) { return valueA_AC struct { : } } b A < int > AC ( ) a_aa.M ; ( ) ( ) }");
|
ASSERT_THROW(checkCode("{ T struct B : T valueA_AA ; } T : [ T > ( ) { B } template < T > struct A < > : ] { ( ) { return valueA_AC struct { : } } b A < int > AC ( ) a_aa.M ; ( ) ( ) }"), InternalError);
|
||||||
ASSERT_THROW(checkCode("template < Types > struct S :{ ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) }"),
|
ASSERT_THROW(checkCode("template < Types > struct S :{ ( S < ) S >} { ( ) { } } ( ) { return S < void > ( ) }"),
|
||||||
InternalError);
|
InternalError);
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1022,7 @@ private:
|
||||||
void garbageCode134() {
|
void garbageCode134() {
|
||||||
// Ticket #5605, #5759, #5762, #5774, #5823, #6059
|
// Ticket #5605, #5759, #5762, #5774, #5823, #6059
|
||||||
ASSERT_THROW(checkCode("foo() template<typename T1 = T2 = typename = unused, T5 = = unused> struct tuple Args> tuple<Args...> { } main() { foo<int,int,int,int,int,int>(); }"), InternalError);
|
ASSERT_THROW(checkCode("foo() template<typename T1 = T2 = typename = unused, T5 = = unused> struct tuple Args> tuple<Args...> { } main() { foo<int,int,int,int,int,int>(); }"), InternalError);
|
||||||
checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }");
|
ASSERT_THROW(checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }"), InternalError);
|
||||||
checkCode("() template < T = typename = x > struct a {} { f <int> () }");
|
checkCode("() template < T = typename = x > struct a {} { f <int> () }");
|
||||||
checkCode("template < T = typename = > struct a { f <int> }");
|
checkCode("template < T = typename = > struct a { f <int> }");
|
||||||
checkCode("struct S { int i, j; }; "
|
checkCode("struct S { int i, j; }; "
|
||||||
|
@ -1060,7 +1062,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode137() { // #7034
|
void garbageCode137() { // #7034
|
||||||
checkCode("\" \" typedef signed char f; \" \"; void a() { f * s = () &[]; (; ) (; ) }");
|
ASSERT_THROW(checkCode("\" \" typedef signed char f; \" \"; void a() { f * s = () &[]; (; ) (; ) }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode138() { // #6660
|
void garbageCode138() { // #6660
|
||||||
|
@ -1229,7 +1231,7 @@ private:
|
||||||
|
|
||||||
// 6122 survive garbage code
|
// 6122 survive garbage code
|
||||||
code = "; { int i ; for ( i = 0 ; = 123 ; ) - ; }";
|
code = "; { int i ; for ( i = 0 ; = 123 ; ) - ; }";
|
||||||
checkCode(code);
|
ASSERT_THROW(checkCode(code), InternalError);
|
||||||
|
|
||||||
code = "void f1() { for (int n = 0 n < 10 n++); }";
|
code = "void f1() { for (int n = 0 n < 10 n++); }";
|
||||||
checkCode(code);
|
checkCode(code);
|
||||||
|
@ -1401,7 +1403,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode174() { // #7356
|
void garbageCode174() { // #7356
|
||||||
checkCode("{r e() { w*constD = (())D = cast< }}");
|
ASSERT_THROW(checkCode("{r e() { w*constD = (())D = cast< }}"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode175() { // #7027
|
void garbageCode175() { // #7027
|
||||||
|
@ -1431,10 +1433,11 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode184() { // #7699
|
void garbageCode184() { // #7699
|
||||||
checkCode("unsigned int AquaSalSystem::GetDisplayScreenCount() {\n"
|
ASSERT_THROW(checkCode("unsigned int AquaSalSystem::GetDisplayScreenCount() {\n"
|
||||||
" NSArray* pScreens = [NSScreen screens];\n"
|
" NSArray* pScreens = [NSScreen screens];\n"
|
||||||
" return pScreens ? [pScreens count] : 1;\n"
|
" return pScreens ? [pScreens count] : 1;\n"
|
||||||
"}");
|
"}"),
|
||||||
|
InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode185() { // #6011 crash in libreoffice failure to create proper AST
|
void garbageCode185() { // #6011 crash in libreoffice failure to create proper AST
|
||||||
|
@ -1471,11 +1474,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode190() { // #8307
|
void garbageCode190() { // #8307
|
||||||
checkCode("void foo() {\n"
|
ASSERT_THROW(checkCode("void foo() {\n"
|
||||||
" int i;\n"
|
" int i;\n"
|
||||||
" i *= 0;\n"
|
" i *= 0;\n"
|
||||||
" !i <;\n"
|
" !i <;\n"
|
||||||
"}");
|
"}"),
|
||||||
|
InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode191() { // #8333
|
void garbageCode191() { // #8333
|
||||||
|
@ -1491,6 +1495,18 @@ private:
|
||||||
ASSERT_THROW(checkCode("{(()[((0||0xf||))]0[])}"), InternalError);
|
ASSERT_THROW(checkCode("{(()[((0||0xf||))]0[])}"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #8740
|
||||||
|
void garbageCode193()
|
||||||
|
{
|
||||||
|
ASSERT_THROW(checkCode("d f(){!=[]&&0()!=0}"), InternalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// #8384
|
||||||
|
void garbageCode194()
|
||||||
|
{
|
||||||
|
ASSERT_THROW(checkCode("{((()))(return 1||);}"), InternalError);
|
||||||
|
}
|
||||||
|
|
||||||
void syntaxErrorFirstToken() {
|
void syntaxErrorFirstToken() {
|
||||||
ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818
|
ASSERT_THROW(checkCode("&operator(){[]};"), InternalError); // #7818
|
||||||
ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858
|
ASSERT_THROW(checkCode("*(*const<> (size_t); foo) { } *(*const (size_t)() ; foo) { }"), InternalError); // #6858
|
||||||
|
|
Loading…
Reference in New Issue