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%"))
continue;
}
if (Token::Match(tok, "%assign% typename|class %assign%"))
syntaxError(tok);
if (Token::Match(tok, "%cop%|=|,|[ %or%|%oror%|/|%"))
syntaxError(tok);
if (Token::Match(tok, ";|(|[ %comp%"))

View File

@ -1217,14 +1217,23 @@ void TokenList::validateAst() const
// Skip pure virtual functions
if (Token::simpleMatch(tok->previous(), ") = 0"))
continue;
// Skip operator definitions
if (Token::simpleMatch(tok->previous(), "operator"))
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, "= {|^"))
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;
if (!tok->astOperand1() || !tok->astOperand2())
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() {
// ticket #2604 segmentation fault
checkCode("sizeof <= A");
ASSERT_THROW(checkCode("sizeof <= A"), InternalError);
}
void garbageCode36() { // #6334
@ -1028,8 +1028,8 @@ private:
// 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("( ) template < T1 = typename = unused> struct Args { } main ( ) { foo < int > ( ) ; }"), InternalError);
checkCode("() template < T = typename = x > struct a {} { f <int> () }");
checkCode("template < T = typename = > struct a { f <int> }");
ASSERT_THROW(checkCode("() template < T = typename = x > struct a {} { f <int> () }"), InternalError);
ASSERT_THROW(checkCode("template < T = typename = > struct a { f <int> }"), InternalError);
checkCode("struct S { int i, j; }; "
"template<int S::*p, typename U> struct X {}; "
"X<&S::i, int> x = X<&S::i, int>(); "
@ -1438,11 +1438,10 @@ private:
}
void garbageCode184() { // #7699
ASSERT_THROW(checkCode("unsigned int AquaSalSystem::GetDisplayScreenCount() {\n"
checkCode("unsigned int AquaSalSystem::GetDisplayScreenCount() {\n"
" NSArray* pScreens = [NSScreen screens];\n"
" return pScreens ? [pScreens count] : 1;\n"
"}"),
InternalError);
"}");
}
void garbageCode185() { // #6011 crash in libreoffice failure to create proper AST
@ -1617,6 +1616,32 @@ private:
"template< class Predicate > int\n"
"List<T>::DeleteIf( const Predicate &pred )\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");
}
};