From 6fd157e93be6d7bdb015eddc9b1a2a02220835ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Thu, 11 Jan 2018 14:22:27 +0100 Subject: [PATCH] ValueFlow: Template arguments have 'possible' values --- lib/valueflow.cpp | 40 +++++++++++++++++++++++----------------- test/testvalueflow.cpp | 7 +++++++ 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 736908595..a635a65f4 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -670,21 +670,25 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti { if ((tok->isNumber() && MathLib::isInt(tok->str())) || (tok->tokType() == Token::eChar)) { ValueFlow::Value value(MathLib::toLongNumber(tok->str())); - value.setKnown(); + if (!tok->isTemplateArg()) + value.setKnown(); setTokenValue(const_cast(tok), value, settings); } else if (tok->isNumber() && MathLib::isFloat(tok->str())) { ValueFlow::Value value; value.valueType = ValueFlow::Value::FLOAT; value.floatValue = MathLib::toDoubleNumber(tok->str()); - value.setKnown(); + if (!tok->isTemplateArg()) + value.setKnown(); setTokenValue(const_cast(tok), value, settings); } else if (tok->enumerator() && tok->enumerator()->value_known) { ValueFlow::Value value(tok->enumerator()->value); - value.setKnown(); + if (!tok->isTemplateArg()) + value.setKnown(); setTokenValue(const_cast(tok), value, settings); } else if (tok->str() == "NULL" || (cpp && tok->str() == "nullptr")) { ValueFlow::Value value(0); - value.setKnown(); + if (!tok->isTemplateArg()) + value.setKnown(); setTokenValue(const_cast(tok), value, settings); } else if (Token::simpleMatch(tok, "sizeof (")) { const Token *tok2 = tok->tokAt(2); @@ -695,7 +699,7 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti size = getSizeOfType(type, settings); } ValueFlow::Value value(size); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok), value, settings); setTokenValue(const_cast(tok->next()), value, settings); @@ -708,7 +712,7 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti } } ValueFlow::Value value(size); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok), value, settings); setTokenValue(const_cast(tok->next()), value, settings); @@ -724,7 +728,7 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti sz1->variable()->dimensionKnown(0) && (Token::Match(sz2, "* %varid% )", varid1) || Token::Match(sz2, "%varid% [ 0 ] )", varid1))) { ValueFlow::Value value(sz1->variable()->dimension(0)); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->tokAt(4)), value, settings); } @@ -732,42 +736,42 @@ static Token * valueFlowSetConstantValue(const Token *tok, const Settings *setti const ValueType &vt = ValueType::parseDecl(tok2,settings); if (vt.pointer) { ValueFlow::Value value(settings->sizeof_pointer); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::CHAR) { ValueFlow::Value value(1); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::SHORT) { ValueFlow::Value value(settings->sizeof_short); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::INT) { ValueFlow::Value value(settings->sizeof_int); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::LONG) { ValueFlow::Value value(settings->sizeof_long); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::LONGLONG) { ValueFlow::Value value(settings->sizeof_long_long); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::FLOAT) { ValueFlow::Value value(settings->sizeof_float); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } else if (vt.type == ValueType::Type::DOUBLE) { ValueFlow::Value value(settings->sizeof_double); - if (settings->platformType != cppcheck::Platform::Unspecified) + if (!tok2->isTemplateArg() && settings->platformType != cppcheck::Platform::Unspecified) value.setKnown(); setTokenValue(const_cast(tok->next()), value, settings); } @@ -789,13 +793,15 @@ static void valueFlowNumber(TokenList *tokenlist) for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { if (tok->isName() && !tok->varId() && Token::Match(tok, "false|true")) { ValueFlow::Value value(tok->str() == "true"); - value.setKnown(); + if (!tok->isTemplateArg()) + value.setKnown(); setTokenValue(tok, value, tokenlist->getSettings()); } else if (Token::Match(tok, "[(,] NULL [,)]")) { // NULL function parameters are not simplified in the // normal tokenlist ValueFlow::Value value(0); - value.setKnown(); + if (!tok->isTemplateArg()) + value.setKnown(); setTokenValue(tok->next(), value, tokenlist->getSettings()); } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index c290efca6..5b9b15b54 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -2622,6 +2622,13 @@ private: ASSERT_EQUALS(true, testValueOfX(code, 4U, 6)); ASSERT_EQUALS(false, testValueOfX(code, 4U, 7)); ASSERT(value.isKnown()); + + // template parameters are not known + code = "template void f() { a = X; }\n" + "f<1>();"; + value = valueOfTok(code, "1"); + ASSERT_EQUALS(1, value.intvalue); + ASSERT_EQUALS(false, value.isKnown()); } void valueFlowSizeofForwardDeclaredEnum() {