ValueType: Handle auto in range for loop
This commit is contained in:
parent
2da360eec5
commit
7ecd5db8fb
|
@ -4433,10 +4433,7 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
|
||||||
else if (Token::Match(var1Tok->tokAt(-3), "[;{}] auto *"))
|
else if (Token::Match(var1Tok->tokAt(-3), "[;{}] auto *"))
|
||||||
autoTok = var1Tok->tokAt(-2);
|
autoTok = var1Tok->tokAt(-2);
|
||||||
if (autoTok) {
|
if (autoTok) {
|
||||||
ValueType vt(*vt2);
|
setValueType(autoTok, *vt2, cpp, defaultSignedness, settings);
|
||||||
if (vt.pointer > 0 && autoTok->strAt(1) == "*")
|
|
||||||
vt.pointer--;
|
|
||||||
setValueType(autoTok, vt, cpp, defaultSignedness, settings);
|
|
||||||
setValueType(var1Tok, *vt2, cpp, defaultSignedness, settings);
|
setValueType(var1Tok, *vt2, cpp, defaultSignedness, settings);
|
||||||
setValueType(parent->previous(), *vt2, cpp, defaultSignedness, settings);
|
setValueType(parent->previous(), *vt2, cpp, defaultSignedness, settings);
|
||||||
}
|
}
|
||||||
|
@ -4489,6 +4486,24 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// range for loop, auto
|
||||||
|
if (vt2 &&
|
||||||
|
parent->str() == ":" &&
|
||||||
|
Token::Match(parent->astParent(), "( const| auto *| %var% :") &&
|
||||||
|
!parent->previous()->valueType() &&
|
||||||
|
Token::simpleMatch(parent->astParent()->astOperand1(), "for")) {
|
||||||
|
bool isconst = Token::simpleMatch(parent->astParent()->next(), "const");
|
||||||
|
Token * const autoToken = const_cast<Token *>(parent->astParent()->tokAt(isconst ? 2 : 1));
|
||||||
|
if (vt2->pointer) {
|
||||||
|
ValueType vt(*vt2);
|
||||||
|
vt.pointer--;
|
||||||
|
if (isconst)
|
||||||
|
vt.constness |= 1;
|
||||||
|
setValueType(autoToken, vt, cpp, defaultSignedness, settings);
|
||||||
|
setValueType(parent->previous(), vt, cpp, defaultSignedness, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!vt1)
|
if (!vt1)
|
||||||
return;
|
return;
|
||||||
if (parent->astOperand2() && !vt2)
|
if (parent->astOperand2() && !vt2)
|
||||||
|
@ -4628,6 +4643,10 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V
|
||||||
valuetype->pointer = vt->pointer;
|
valuetype->pointer = vt->pointer;
|
||||||
if (vt->sign != ValueType::Sign::UNKNOWN_SIGN)
|
if (vt->sign != ValueType::Sign::UNKNOWN_SIGN)
|
||||||
valuetype->sign = vt->sign;
|
valuetype->sign = vt->sign;
|
||||||
|
valuetype->constness = vt->constness;
|
||||||
|
while (Token::Match(type, "%name%|*|&|::") && !type->variable())
|
||||||
|
type = type->next();
|
||||||
|
break;
|
||||||
} else if (!valuetype->typeScope && (type->str() == "struct" || type->str() == "enum"))
|
} else if (!valuetype->typeScope && (type->str() == "struct" || type->str() == "enum"))
|
||||||
valuetype->type = ValueType::Type::NONSTD;
|
valuetype->type = ValueType::Type::NONSTD;
|
||||||
else if (!valuetype->typeScope && type->type() && type->type()->classScope) {
|
else if (!valuetype->typeScope && type->type() && type->type()->classScope) {
|
||||||
|
|
|
@ -4240,8 +4240,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto variables
|
// auto variables
|
||||||
ASSERT_EQUALS("signed int", typeOf("; auto x = 3;", "auto"));
|
ASSERT_EQUALS("signed int", typeOf("; auto x = 3;", "x"));
|
||||||
ASSERT_EQUALS("signed int", typeOf("; auto *p = (int *)0;", "auto"));
|
ASSERT_EQUALS("signed int *", typeOf("; auto *p = (int *)0;", "p"));
|
||||||
|
ASSERT_EQUALS("const signed short", typeOf("short values[10]; void f() { for (const auto *x : values); }", "x"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void variadic1() { // #7453
|
void variadic1() { // #7453
|
||||||
|
|
Loading…
Reference in New Issue