diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 475ffd372..caade477b 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -52,6 +52,9 @@ InternalError::InternalError(const Token *tok, const std::string &errorMsg, Type case LIMIT: id = "cppcheckLimit"; break; + case INSTANTIATION: + id = "instantiationError"; + break; } } diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 4c071cfe1..11b2d4a09 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -54,7 +54,7 @@ namespace tinyxml2 { /** @brief Simple container to be thrown when internal error is detected. */ struct InternalError { - enum Type {AST, SYNTAX, UNKNOWN_MACRO, INTERNAL, LIMIT}; + enum Type {AST, SYNTAX, UNKNOWN_MACRO, INTERNAL, LIMIT, INSTANTIATION}; InternalError(const Token *tok, const std::string &errorMsg, Type type = INTERNAL); const Token *token; std::string errorMessage; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 7a4ffce0d..66c392f30 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -2180,7 +2180,7 @@ bool TemplateSimplifier::simplifyNumericCalculations(Token *tok) // Don't simplify "%num% / 0" if (Token::Match(op, "[/%] 0")) - break; + throw InternalError(op, "Instantiation error: Divide by zero in template instantiation.", InternalError::INSTANTIATION); // Integer operations if (Token::Match(op, ">>|<<|&|^|%or%")) { diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index 88862d707..c5205b9c0 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -162,6 +162,7 @@ private: TEST_CASE(template122); // #9147 TEST_CASE(template123); // #9183 TEST_CASE(template124); // #9197 + TEST_CASE(template125); TEST_CASE(template_specialization_1); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template) @@ -2923,6 +2924,17 @@ private: ASSERT_EQUALS(exp, tok(code)); } + void template125() { + ASSERT_THROW(tok("template\n" + "class GCD {\n" + "public:\n" + " enum { val = (N == 0) ? M : GCD::val };\n" + "};\n" + "int main() {\n" + " GCD< 1, 0 >::val;\n" + "}"), InternalError); + } + void template_specialization_1() { // #7868 - template specialization template struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n"