Fixed #10100 (FP: shadowVariable clangimport)
This commit is contained in:
parent
4e1ff86bb2
commit
203d6ebe5a
|
@ -249,6 +249,14 @@ namespace clangimport {
|
||||||
notFound(addr);
|
notFound(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void replaceVarDecl(const Variable *from, Variable *to) {
|
||||||
|
for (auto &it: mDeclMap) {
|
||||||
|
Decl &decl = it.second;
|
||||||
|
if (decl.var == from)
|
||||||
|
decl.var = to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ref(const std::string &addr, Token *tok) {
|
void ref(const std::string &addr, Token *tok) {
|
||||||
auto it = mDeclMap.find(addr);
|
auto it = mDeclMap.find(addr);
|
||||||
if (it != mDeclMap.end())
|
if (it != mDeclMap.end())
|
||||||
|
@ -632,6 +640,29 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType
|
||||||
scope->type = scopeType;
|
scope->type = scopeType;
|
||||||
scope->classDef = def;
|
scope->classDef = def;
|
||||||
scope->check = nestedIn->check;
|
scope->check = nestedIn->check;
|
||||||
|
if (Token::Match(def, "if|for|while (")) {
|
||||||
|
std::map<const Variable *, const Variable *> replaceVar;
|
||||||
|
for (const Token *vartok = def->tokAt(2); vartok; vartok = vartok->next()) {
|
||||||
|
if (!vartok->variable())
|
||||||
|
continue;
|
||||||
|
if (vartok->variable()->nameToken() == vartok) {
|
||||||
|
const Variable *from = vartok->variable();
|
||||||
|
scope->varlist.emplace_back(*from, scope);
|
||||||
|
Variable *to = &scope->varlist.back();
|
||||||
|
replaceVar[from] = to;
|
||||||
|
mData->replaceVarDecl(from, to);
|
||||||
|
}
|
||||||
|
if (replaceVar.find(vartok->variable()) != replaceVar.end())
|
||||||
|
const_cast<Token *>(vartok)->variable(replaceVar[vartok->variable()]);
|
||||||
|
}
|
||||||
|
std::list<Variable> &varlist = const_cast<Scope *>(def->scope())->varlist;
|
||||||
|
for (std::list<Variable>::iterator var = varlist.begin(); var != varlist.end();) {
|
||||||
|
if (replaceVar.find(&(*var)) != replaceVar.end())
|
||||||
|
varlist.erase(var++);
|
||||||
|
else
|
||||||
|
var++;
|
||||||
|
}
|
||||||
|
}
|
||||||
scope->bodyStart = addtoken(tokenList, "{");
|
scope->bodyStart = addtoken(tokenList, "{");
|
||||||
tokenList->back()->scope(scope);
|
tokenList->back()->scope(scope);
|
||||||
mData->scopeAccessControl[scope] = scope->defaultAccess();
|
mData->scopeAccessControl[scope] = scope->defaultAccess();
|
||||||
|
|
|
@ -1886,6 +1886,38 @@ Variable::Variable(const Token *name_, const std::string &clangType, const Token
|
||||||
setFlag(fIsInit, true);
|
setFlag(fIsInit, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variable::Variable(const Variable &var, const Scope *scope)
|
||||||
|
: mNameToken(var.mNameToken)
|
||||||
|
, mTypeStartToken(var.mTypeStartToken)
|
||||||
|
, mTypeEndToken(var.mTypeEndToken)
|
||||||
|
, mIndex(var.mIndex)
|
||||||
|
, mAccess(var.mAccess)
|
||||||
|
, mFlags(var.mFlags)
|
||||||
|
, mType(var.mType)
|
||||||
|
, mScope(scope ? scope : var.mScope)
|
||||||
|
, mValueType(nullptr)
|
||||||
|
, mDimensions(var.mDimensions)
|
||||||
|
{
|
||||||
|
if (var.mValueType)
|
||||||
|
mValueType = new ValueType(*var.mValueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable::Variable(const Variable &var)
|
||||||
|
: mNameToken(var.mNameToken)
|
||||||
|
, mTypeStartToken(var.mTypeStartToken)
|
||||||
|
, mTypeEndToken(var.mTypeEndToken)
|
||||||
|
, mIndex(var.mIndex)
|
||||||
|
, mAccess(var.mAccess)
|
||||||
|
, mFlags(var.mFlags)
|
||||||
|
, mType(var.mType)
|
||||||
|
, mScope(var.mScope)
|
||||||
|
, mValueType(nullptr)
|
||||||
|
, mDimensions(var.mDimensions)
|
||||||
|
{
|
||||||
|
if (var.mValueType)
|
||||||
|
mValueType = new ValueType(*var.mValueType);
|
||||||
|
}
|
||||||
|
|
||||||
Variable::~Variable()
|
Variable::~Variable()
|
||||||
{
|
{
|
||||||
delete mValueType;
|
delete mValueType;
|
||||||
|
|
|
@ -240,6 +240,10 @@ public:
|
||||||
const Token *typeEnd, nonneg int index_, AccessControl access_,
|
const Token *typeEnd, nonneg int index_, AccessControl access_,
|
||||||
const Type *type_, const Scope *scope_);
|
const Type *type_, const Scope *scope_);
|
||||||
|
|
||||||
|
Variable(const Variable &var, const Scope *scope);
|
||||||
|
|
||||||
|
Variable(const Variable &var);
|
||||||
|
|
||||||
~Variable();
|
~Variable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1236,6 +1240,21 @@ public:
|
||||||
containerTypeToken(nullptr),
|
containerTypeToken(nullptr),
|
||||||
originalTypeName(otn)
|
originalTypeName(otn)
|
||||||
{}
|
{}
|
||||||
|
ValueType(const ValueType &vt)
|
||||||
|
: sign(vt.sign)
|
||||||
|
, type(vt.type)
|
||||||
|
, bits(vt.bits)
|
||||||
|
, pointer(vt.pointer)
|
||||||
|
, constness(vt.constness)
|
||||||
|
, reference(vt.reference)
|
||||||
|
, typeScope(vt.typeScope)
|
||||||
|
, smartPointerType(vt.smartPointerType)
|
||||||
|
, smartPointerTypeToken(vt.smartPointerTypeToken)
|
||||||
|
, container(vt.container)
|
||||||
|
, containerTypeToken(vt.containerTypeToken)
|
||||||
|
, originalTypeName(vt.originalTypeName)
|
||||||
|
{}
|
||||||
|
|
||||||
static ValueType parseDecl(const Token *type, const Settings *settings);
|
static ValueType parseDecl(const Token *type, const Settings *settings);
|
||||||
|
|
||||||
static Type typeFromString(const std::string &typestr, bool longType);
|
static Type typeFromString(const std::string &typestr, bool longType);
|
||||||
|
|
|
@ -119,6 +119,7 @@ private:
|
||||||
TEST_CASE(symbolDatabaseVariableRRef);
|
TEST_CASE(symbolDatabaseVariableRRef);
|
||||||
TEST_CASE(symbolDatabaseVariablePointerRef);
|
TEST_CASE(symbolDatabaseVariablePointerRef);
|
||||||
TEST_CASE(symbolDatabaseNodeType1);
|
TEST_CASE(symbolDatabaseNodeType1);
|
||||||
|
TEST_CASE(symbolDatabaseForVariable);
|
||||||
|
|
||||||
TEST_CASE(valueFlow1);
|
TEST_CASE(valueFlow1);
|
||||||
TEST_CASE(valueFlow2);
|
TEST_CASE(valueFlow2);
|
||||||
|
@ -1210,6 +1211,28 @@ private:
|
||||||
ASSERT_EQUALS("signed long", tok->valueType()->str());
|
ASSERT_EQUALS("signed long", tok->valueType()->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void symbolDatabaseForVariable() {
|
||||||
|
const char clang[] = "`-FunctionDecl 0x38f8bb0 <10100.c:2:1, line:4:1> line:2:6 f 'void (void)'\n"
|
||||||
|
" `-CompoundStmt 0x38f8d88 <col:14, line:4:1>\n"
|
||||||
|
" `-ForStmt 0x38f8d50 <line:3:5, col:26>\n"
|
||||||
|
" |-DeclStmt 0x38f8d28 <col:10, col:19>\n"
|
||||||
|
" | `-VarDecl 0x38f8ca8 <col:10, col:18> col:14 i 'int' cinit\n"
|
||||||
|
" | `-IntegerLiteral 0x38f8d08 <col:18> 'int' 0\n"
|
||||||
|
" |-<<<NULL>>>\n"
|
||||||
|
" |-<<<NULL>>>\n"
|
||||||
|
" |-<<<NULL>>>\n"
|
||||||
|
" `-CompoundStmt 0x38f8d40 <col:25, col:26>";
|
||||||
|
|
||||||
|
ASSERT_EQUALS("void f ( ) { for ( int i@1 = 0 ; ; ) { } }", parse(clang));
|
||||||
|
|
||||||
|
GET_SYMBOL_DB(clang);
|
||||||
|
|
||||||
|
const Token *tok = Token::findsimplematch(tokenizer.tokens(), "i");
|
||||||
|
ASSERT(!!tok);
|
||||||
|
ASSERT(!!tok->variable());
|
||||||
|
ASSERT_EQUALS(Scope::ScopeType::eFor, tok->variable()->scope()->type);
|
||||||
|
}
|
||||||
|
|
||||||
void valueFlow1() {
|
void valueFlow1() {
|
||||||
// struct S { int x; int buf[10]; } ; int sz = sizeof(struct S);
|
// struct S { int x; int buf[10]; } ; int sz = sizeof(struct S);
|
||||||
const char clang[] = "|-RecordDecl 0x2fc5a88 <1.c:1:1, line:4:1> line:1:8 struct S definition\n"
|
const char clang[] = "|-RecordDecl 0x2fc5a88 <1.c:1:1, line:4:1> line:1:8 struct S definition\n"
|
||||||
|
|
Loading…
Reference in New Issue