Skip to content

Commit 337dfc9

Browse files
authored
Fix 12315: FP containerOutOfBounds when size of container is defined by constexpr (danmar#6412)
1 parent da124d1 commit 337dfc9

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

lib/valueflow.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,7 +2996,7 @@ struct ValueFlowAnalyzer : Analyzer {
29962996
return isThisModified(tok);
29972997

29982998
// bailout: global non-const variables
2999-
if (isGlobal() && !dependsOnThis() && Token::Match(tok, "%name% (") &&
2999+
if (isGlobal() && !dependsOnThis() && Token::Match(tok, "%name% (") && !tok->variable() &&
30003000
!Token::simpleMatch(tok->linkAt(1), ") {")) {
30013001
return isGlobalModified(tok);
30023002
}
@@ -5938,7 +5938,7 @@ static void valueFlowForwardAssign(Token* const tok,
59385938
}
59395939

59405940
// Static variable initialisation?
5941-
if (vars.size() == 1 && vars.front()->isStatic() && init)
5941+
if (vars.size() == 1 && vars.front()->isStatic() && !vars.front()->isConst() && init)
59425942
lowerToPossible(values);
59435943

59445944
// is volatile
@@ -6057,13 +6057,25 @@ static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> va
60576057

60586058
static bool isVariableInit(const Token *tok)
60596059
{
6060-
return (tok->str() == "(" || tok->str() == "{") &&
6061-
(tok->isBinaryOp() || (tok->astOperand1() && tok->link() == tok->next())) &&
6062-
tok->astOperand1()->variable() &&
6063-
tok->astOperand1()->variable()->nameToken() == tok->astOperand1() &&
6064-
tok->astOperand1()->variable()->valueType() &&
6065-
tok->astOperand1()->variable()->valueType()->type >= ValueType::Type::VOID &&
6066-
!Token::simpleMatch(tok->astOperand2(), ",");
6060+
if (!tok)
6061+
return false;
6062+
if (!Token::Match(tok->previous(), "%var% (|{"))
6063+
return false;
6064+
if (!tok->isBinaryOp() && !(tok->astOperand1() && tok->link() == tok->next()))
6065+
return false;
6066+
if (Token::simpleMatch(tok->astOperand2(), ","))
6067+
return false;
6068+
const Variable* var = tok->astOperand1()->variable();
6069+
if (!var)
6070+
return false;
6071+
if (var->nameToken() != tok->astOperand1())
6072+
return false;
6073+
const ValueType* vt = var->valueType();
6074+
if (!vt)
6075+
return false;
6076+
if (vt->type < ValueType::Type::VOID)
6077+
return false;
6078+
return true;
60676079
}
60686080

60696081
// Return true if two associative containers intersect

test/testvalueflow.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,6 +2818,27 @@ class TestValueFlow : public TestFixture {
28182818
"}\n";
28192819
ASSERT_EQUALS(true, testValueOfX(code, 4U, 3));
28202820
ASSERT_EQUALS(false, testValueOfXKnown(code, 4U, 3));
2821+
2822+
code = "void f() {\n"
2823+
" constexpr int x(123);\n"
2824+
" constexpr int y(x*x);\n"
2825+
" return x;\n"
2826+
"}";
2827+
ASSERT_EQUALS(true, testValueOfXKnown(code, 4U, 123));
2828+
2829+
code = "void f() {\n"
2830+
" static const int x(123);\n"
2831+
" static const int y(x*x);\n"
2832+
" return x;\n"
2833+
"}";
2834+
ASSERT_EQUALS(true, testValueOfXKnown(code, 4U, 123));
2835+
2836+
code = "void f() {\n"
2837+
" static int x(123);\n"
2838+
" static int y(x*x);\n"
2839+
" return x;\n"
2840+
"}";
2841+
ASSERT_EQUALS(true, testValueOfX(code, 4U, 123));
28212842
}
28222843

28232844
void valueFlowAfterSwap()

0 commit comments

Comments
 (0)