Fix issue 8757: Throw syntax error on invalid code (#1378)

* Fix issue 8757: Throw syntax error on invalid code

* Fix FP with lambda returns

* Remove double percent

* Check more keywords

* Skip preprocessor directives

* Check for valid PP directive

* Fix preprocessor check

* Dont check for preprocessor directives
This commit is contained in:
Paul Fultz II 2018-10-28 11:17:53 -05:00 committed by Daniel Marjamäki
parent f5811c6818
commit 2b6cc33dc6
3 changed files with 19 additions and 1 deletions

View File

@ -8493,6 +8493,12 @@ void Tokenizer::findGarbageCode() const
if (Token::Match(tok, "> %cop%")) if (Token::Match(tok, "> %cop%"))
continue; continue;
} }
if (Token::Match(tok, "%or%|%oror%|==|!=|+|-|/|!|>=|<=|~|++|--|::|sizeof|throw|decltype|typeof {|if|else|try|catch|while|do|for|return|switch|break|namespace"))
syntaxError(tok);
if (Token::Match(tok, "( %any% )") && tok->next()->isKeyword() && !Token::simpleMatch(tok->next(), "void"))
syntaxError(tok);
if (Token::Match(tok, "%num%|%bool%|%char%|%str% %num%|%bool%|%char%|%str%") && !Token::Match(tok, "%str% %str%"))
syntaxError(tok);
if (Token::Match(tok, "%assign% typename|class %assign%")) if (Token::Match(tok, "%assign% typename|class %assign%"))
syntaxError(tok); syntaxError(tok);
if (Token::Match(tok, "%cop%|=|,|[ %or%|%oror%|/|%")) if (Token::Match(tok, "%cop%|=|,|[ %or%|%oror%|/|%"))

View File

@ -230,6 +230,7 @@ private:
TEST_CASE(garbageCode197); // #8385 TEST_CASE(garbageCode197); // #8385
TEST_CASE(garbageCode198); // #8383 TEST_CASE(garbageCode198); // #8383
TEST_CASE(garbageCode199); // #8752 TEST_CASE(garbageCode199); // #8752
TEST_CASE(garbageCode200); // #8757
TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1 TEST_CASE(garbageCodeFuzzerClientMode1); // test cases created with the fuzzer client, mode 1
@ -975,7 +976,7 @@ private:
} }
void garbageCode131() { void garbageCode131() {
checkCode("( void ) { ( ) } ( ) / { ( ) }"); ASSERT_THROW(checkCode("( void ) { ( ) } ( ) / { ( ) }"), InternalError);
// actually the invalid code should trigger an syntax error... // actually the invalid code should trigger an syntax error...
} }
@ -1545,6 +1546,11 @@ private:
checkCode("d f(){e n00e0[]n00e0&""0+f=0}"); checkCode("d f(){e n00e0[]n00e0&""0+f=0}");
} }
// #8757
void garbageCode200() {
ASSERT_THROW(checkCode("(){e break,{(case)!{e:[]}}}"), 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
@ -1599,6 +1605,10 @@ private:
// case must be inside switch block // case must be inside switch block
ASSERT_THROW(checkCode("void f() { switch (a) {}; case 1: }"), InternalError); // #8184 ASSERT_THROW(checkCode("void f() { switch (a) {}; case 1: }"), InternalError); // #8184
ASSERT_THROW(checkCode("struct V : { public case {} ; struct U : U void { V *f (int x) (x) } }"), InternalError); // #5120 ASSERT_THROW(checkCode("struct V : { public case {} ; struct U : U void { V *f (int x) (x) } }"), InternalError); // #5120
ASSERT_THROW(checkCode("void f() { 0 0; }"), InternalError);
ASSERT_THROW(checkCode("void f() { true 0; }"), InternalError);
ASSERT_THROW(checkCode("void f() { 'a' 0; }"), InternalError);
ASSERT_THROW(checkCode("void f() { 1 \"\"; }"), InternalError);
} }
void enumTrailingComma() { void enumTrailingComma() {

View File

@ -8641,6 +8641,8 @@ private:
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) {} }"));
ASSERT_NO_THROW(tokenizeAndStringify("void f() { UNKNOWN_MACRO if (a) {} }")) ASSERT_NO_THROW(tokenizeAndStringify("void f() { UNKNOWN_MACRO if (a) {} }"))
ASSERT_NO_THROW(tokenizeAndStringify("void f() { []() -> int * {}; }"));
ASSERT_NO_THROW(tokenizeAndStringify("void f() { const char* var = \"1\" \"2\"; }"));
// TODO ASSERT_NO_THROW(tokenizeAndStringify("void f() { MACRO(switch); }")); // TODO ASSERT_NO_THROW(tokenizeAndStringify("void f() { MACRO(switch); }"));
// TODO ASSERT_NO_THROW(tokenizeAndStringify("void f() { MACRO(x,switch); }")); // TODO ASSERT_NO_THROW(tokenizeAndStringify("void f() { MACRO(x,switch); }"));