Skip some ast errors to avoid regressions (#1422)

* Skip some ast errors to avoid regressions

* Use simpleMatch

* Skip operator functions

* Add a test for issue 8788
This commit is contained in:
Paul Fultz II 2018-10-13 11:38:44 -05:00 committed by Daniel Marjamäki
parent 7833ade128
commit 9cf092657c
3 changed files with 46 additions and 10 deletions

View File

@ -8486,6 +8486,8 @@ void Tokenizer::findGarbageCode() const
if (Token::Match(tok, "> %cop%")) if (Token::Match(tok, "> %cop%"))
continue; continue;
} }
if (Token::Match(tok, "%assign% typename|class %assign%"))
syntaxError(tok);
if (Token::Match(tok, "%cop%|=|,|[ %or%|%oror%|/|%")) if (Token::Match(tok, "%cop%|=|,|[ %or%|%oror%|/|%"))
syntaxError(tok); syntaxError(tok);
if (Token::Match(tok, ";|(|[ %comp%")) if (Token::Match(tok, ";|(|[ %comp%"))

View File

@ -1217,14 +1217,23 @@ void TokenList::validateAst() const
// Skip pure virtual functions // Skip pure virtual functions
if (Token::simpleMatch(tok->previous(), ") = 0")) if (Token::simpleMatch(tok->previous(), ") = 0"))
continue; continue;
// Skip operator definitions
if (Token::simpleMatch(tok->previous(), "operator"))
continue;
// Skip incomplete code // Skip incomplete code
if (!tok->astOperand1() && !tok->astOperand2() && !tok->astParent()) if (!tok->astOperand1() && !tok->astOperand2() && !tok->astParent())
continue; continue;
// FIXME
if (Token::Match(tok->previous(), "%name%") && Token::Match(tok->next(), "%name%"))
continue;
// Skip lambda assignment and/or initializer // Skip lambda assignment and/or initializer
if (Token::Match(tok, "= {|^")) if (Token::Match(tok, "= {|^|["))
continue;
// FIXME: Workaround broken AST assignment in type aliases
if (Token::Match(tok->previous(), "%name% = %name%"))
continue;
// FIXME: Workaround when assigning from a new expression: #8749
if (Token::simpleMatch(tok, "= new"))
continue;
// FIXME: Workaround assigning when using c style cast: #8786
if (Token::Match(tok, "= ( %name%"))
continue; continue;
if (!tok->astOperand1() || !tok->astOperand2()) if (!tok->astOperand1() || !tok->astOperand2())
throw InternalError(tok, "Syntax Error: AST broken, binary operator '" + tok->str() + "' doesn't have two operands.", InternalError::AST); throw InternalError(tok, "Syntax Error: AST broken, binary operator '" + tok->str() + "' doesn't have two operands.", InternalError::AST);

View File

@ -578,7 +578,7 @@ private:
void garbageCode35() { void garbageCode35() {
// ticket #2604 segmentation fault // ticket #2604 segmentation fault
checkCode("sizeof <= A"); ASSERT_THROW(checkCode("sizeof <= A"), InternalError);
} }
void garbageCode36() { // #6334 void garbageCode36() { // #6334
@ -1028,8 +1028,8 @@ private:
// 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);
ASSERT_THROW(checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }"), InternalError); ASSERT_THROW(checkCode("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }"), InternalError);
checkCode("() template < T = typename = x > struct a {} { f <int> () }"); ASSERT_THROW(checkCode("() template < T = typename = x > struct a {} { f <int> () }"), InternalError);
checkCode("template < T = typename = > struct a { f <int> }"); ASSERT_THROW(checkCode("template < T = typename = > struct a { f <int> }"), InternalError);
checkCode("struct S { int i, j; }; " checkCode("struct S { int i, j; }; "
"template<int S::*p, typename U> struct X {}; " "template<int S::*p, typename U> struct X {}; "
"X<&S::i, int> x = X<&S::i, int>(); " "X<&S::i, int> x = X<&S::i, int>(); "
@ -1438,11 +1438,10 @@ private:
} }
void garbageCode184() { // #7699 void garbageCode184() { // #7699
ASSERT_THROW(checkCode("unsigned int AquaSalSystem::GetDisplayScreenCount() {\n" 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
@ -1617,6 +1616,32 @@ private:
"template< class Predicate > int\n" "template< class Predicate > int\n"
"List<T>::DeleteIf( const Predicate &pred )\n" "List<T>::DeleteIf( const Predicate &pred )\n"
"{}\n"); "{}\n");
// #8749
checkCode(
"typedef char A[1];\n"
"void f(void) {\n"
" char (*p)[1] = new A[1];\n"
"}\n");
// #8786
checkCode(
"void f() {\n"
" char * pBuf = (char*)(new int[32]);\n"
"}\n");
// #8749
checkCode(
"struct A {\n"
" void operator+=(A&) && = delete;\n"
"};\n");
// #8788
checkCode(
"struct foo;\n"
"void f() {\n"
" auto fn = []() -> foo* { return new foo(); };\n"
"}\n");
} }
}; };