This commit is contained in:
parent
13e74507dd
commit
c1aed9681d
|
@ -553,6 +553,10 @@ public:
|
|||
return mDimensions.at(index_).known;
|
||||
}
|
||||
|
||||
void setDimensions(const std::vector<Dimension> &dimensions_) {
|
||||
mDimensions = dimensions_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the variable is an STL type ('std::')
|
||||
* E.g.:
|
||||
|
|
|
@ -3393,6 +3393,8 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
|
|||
} else {
|
||||
ValueFlow::setValues(list, *mSymbolDatabase, mErrorLogger, mSettings, mTimerResults);
|
||||
}
|
||||
|
||||
arraySizeAfterValueFlow();
|
||||
}
|
||||
|
||||
// Warn about unhandled character literals
|
||||
|
@ -3807,6 +3809,45 @@ void Tokenizer::arraySize()
|
|||
}
|
||||
}
|
||||
|
||||
void Tokenizer::arraySizeAfterValueFlow()
|
||||
{
|
||||
// After ValueFlow, adjust array sizes.
|
||||
for (const Variable* var: mSymbolDatabase->variableList()) {
|
||||
if (!var || !var->isArray())
|
||||
continue;
|
||||
if (!Token::Match(var->nameToken(), "%name% [ ] = { ["))
|
||||
continue;
|
||||
MathLib::bigint maxIndex = -1;
|
||||
const Token* const startToken = var->nameToken()->tokAt(4);
|
||||
const Token* const endToken = startToken->link();
|
||||
for (const Token* tok = startToken; tok != endToken; tok = tok->next()) {
|
||||
if (!Token::Match(tok, "[{,] [") || !Token::simpleMatch(tok->linkAt(1), "] ="))
|
||||
continue;
|
||||
const Token* expr = tok->next()->astOperand1();
|
||||
if (expr && expr->hasKnownIntValue())
|
||||
maxIndex = std::max(maxIndex, expr->getKnownIntValue());
|
||||
}
|
||||
if (maxIndex >= 0) {
|
||||
// insert array size
|
||||
Token* tok = const_cast<Token*>(var->nameToken()->next());
|
||||
tok->insertToken(std::to_string(maxIndex + 1));
|
||||
// ast
|
||||
tok->astOperand2(tok->next());
|
||||
// Token::scope
|
||||
tok->next()->scope(tok->scope());
|
||||
// Value flow
|
||||
ValueFlow::Value value(maxIndex + 1);
|
||||
value.setKnown();
|
||||
tok->next()->addValue(value);
|
||||
// Set array dimensions
|
||||
Dimension d;
|
||||
d.num = maxIndex + 1;
|
||||
std::vector<Dimension> dimensions{d};
|
||||
const_cast<Variable*>(var)->setDimensions(dimensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Token *skipTernaryOp(Token *tok)
|
||||
{
|
||||
int colonLevel = 1;
|
||||
|
|
|
@ -164,6 +164,7 @@ public:
|
|||
|
||||
/** Insert array size where it isn't given */
|
||||
void arraySize();
|
||||
void arraySizeAfterValueFlow(); // cppcheck-suppress functionConst
|
||||
|
||||
/** Simplify labels and 'case|default' syntaxes.
|
||||
*/
|
||||
|
|
|
@ -272,6 +272,7 @@ private:
|
|||
TEST_CASE(cpp14template); // Ticket #6708
|
||||
|
||||
TEST_CASE(arraySize);
|
||||
TEST_CASE(arraySizeAfterValueFlow);
|
||||
|
||||
TEST_CASE(labels);
|
||||
TEST_CASE(simplifyInitVar);
|
||||
|
@ -4156,6 +4157,11 @@ private:
|
|||
ASSERT_EQUALS("; const char c [ 4 ] = \"abc\" ;", tokenizeAndStringify(";const char c[] = { \"abc\" };"));
|
||||
}
|
||||
|
||||
void arraySizeAfterValueFlow() {
|
||||
const char code[] = "enum {X=10}; int a[] = {[X]=1};";
|
||||
ASSERT_EQUALS("enum Anonymous0 { X = 10 } ; int a [ 11 ] = { [ X ] = 1 } ;", tokenizeAndStringify(code));
|
||||
}
|
||||
|
||||
void labels() {
|
||||
ASSERT_EQUALS("void f ( ) { ab : ; a = 0 ; }", tokenizeAndStringify("void f() { ab: a=0; }"));
|
||||
//ticket #3176
|
||||
|
|
Loading…
Reference in New Issue