Warn about unknown macro causing template syntax error (#2222)

This commit is contained in:
IOBYTE 2019-09-26 10:01:01 -04:00 committed by Daniel Marjamäki
parent cd816f42eb
commit d0968a1377
3 changed files with 15 additions and 2 deletions

View File

@ -9405,8 +9405,12 @@ void Tokenizer::findGarbageCode() const
for (const Token *tok = tokens(); tok; tok = tok->next()) {
if (!Token::simpleMatch(tok, "template <"))
continue;
if (tok->previous() && !Token::Match(tok->previous(), "[:;{})>]"))
syntaxError(tok);
if (tok->previous() && !Token::Match(tok->previous(), "[:;{})>]")) {
if (tok->previous()->isUpperCaseName())
unknownMacroError(tok->previous());
else
syntaxError(tok);
}
const Token * const tok1 = tok;
tok = tok->next()->findClosingBracket();
if (!tok)

View File

@ -186,6 +186,7 @@ private:
TEST_CASE(template146); // syntax error
TEST_CASE(template147); // syntax error
TEST_CASE(template148); // syntax error
TEST_CASE(template149); // unknown macro
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -3543,6 +3544,13 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template149() { // unknown macro
const char code[] = "BEGIN_VERSIONED_NAMESPACE_DECL\n"
"template<typename T> class Fred { };\n"
"END_VERSIONED_NAMESPACE_DECL";
ASSERT_THROW_EQUALS(tok(code), InternalError, "There is an unknown macro here somewhere. Configuration is required. If BEGIN_VERSIONED_NAMESPACE_DECL is a macro then please configure it.");
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"

View File

@ -104,6 +104,7 @@ extern std::ostringstream output;
#define ASSERT_EQUALS_DOUBLE( EXPECTED , ACTUAL, TOLERANCE ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL, TOLERANCE)
#define ASSERT_EQUALS_MSG( EXPECTED , ACTUAL, MSG ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL, MSG)
#define ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&) { } catch (...) { assertThrowFail(__FILE__, __LINE__); }
#define ASSERT_THROW_EQUALS( CMD, EXCEPTION, EXPECTED ) try { CMD ; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&e) { assertEquals(__FILE__, __LINE__, EXPECTED, e.errorMessage); } catch (...) { assertThrowFail(__FILE__, __LINE__); }
#define ASSERT_NO_THROW( CMD ) try { CMD ; } catch (...) { assertNoThrowFail(__FILE__, __LINE__); }
#define TODO_ASSERT_THROW( CMD, EXCEPTION ) try { CMD ; } catch (const EXCEPTION&) { } catch (...) { assertThrow(__FILE__, __LINE__); }
#define TODO_ASSERT( CONDITION ) { const bool condition=(CONDITION); todoAssertEquals(__FILE__, __LINE__, true, false, condition); }