Fix FP returnTempReference (#4793)

* Fix FP returnTempReference

* Fix mismatch between token and variable ValueType

* Format, clang-tidy

* Add test

* Format
This commit is contained in:
chrchr-github 2023-02-17 07:17:37 +01:00 committed by GitHub
parent f0ebaf9536
commit 1c11d3039d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 1 deletions

View File

@ -6037,7 +6037,12 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocatio
valuetype.setDebugPath(tok, loc);
if (var.nameToken())
valuetype.bits = var.nameToken()->bits();
valuetype.pointer = (var.valueType() && var.valueType()->container) ? 0 : var.dimensions().size();
valuetype.pointer = var.dimensions().size();
// HACK: don't set pointer for plain std::array
if (var.valueType() && var.valueType()->container && Token::simpleMatch(var.typeStartToken(), "std :: array") && !Token::simpleMatch(var.nameToken()->next(), "["))
valuetype.pointer = 0;
valuetype.typeScope = var.typeScope();
if (var.valueType()) {
valuetype.container = var.valueType()->container;

View File

@ -67,6 +67,12 @@ private:
" CharArray foo = \"\";\n"
"}");
ASSERT_EQUALS("", errout.str());
check("struct T { std::vector<int>*a[2][2]; };\n" // #11560
"void f(T& t, int i, int j) {\n"
" t.a[i][j] = new std::vector<int>;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void novardecl() {

View File

@ -1714,6 +1714,13 @@ private:
" return it->foo;\n"
"}");
ASSERT_EQUALS("", errout.str());
check("static std::vector<int> A[2];\n"
"static std::vector<int> B;\n"
"std::vector<int>& g(int i) {\n"
" return i ? A[i] : B;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
}
void returnReferenceLiteral() {

View File

@ -130,6 +130,7 @@ private:
TEST_CASE(array_ptr);
TEST_CASE(stlarray1);
TEST_CASE(stlarray2);
TEST_CASE(stlarray3);
TEST_CASE(test_isVariableDeclarationCanHandleNull);
TEST_CASE(test_isVariableDeclarationIdentifiesSimpleDeclaration);
@ -573,6 +574,56 @@ private:
ASSERT_EQUALS(20U, v->dimension(0));
}
void stlarray3() {
GET_SYMBOL_DB("std::array<int, 4> a;\n"
"std::array<int, 4> b[2];\n"
"const std::array<int, 4>& r = a;\n");
ASSERT(db != nullptr);
ASSERT_EQUALS(4, db->variableList().size()); // the first one is not used
auto it = db->variableList().begin() + 1;
ASSERT((*it)->isArray());
ASSERT(!(*it)->isPointer());
ASSERT(!(*it)->isReference());
ASSERT_EQUALS(1U, (*it)->dimensions().size());
ASSERT_EQUALS(4U, (*it)->dimension(0));
const ValueType* vt = (*it)->valueType();
ASSERT(vt && vt->container);
ASSERT_EQUALS(vt->pointer, 0);
const Token* tok = (*it)->nameToken();
ASSERT(tok && (vt = tok->valueType()));
ASSERT_EQUALS(vt->pointer, 0);
++it;
ASSERT((*it)->isArray());
ASSERT(!(*it)->isPointer());
ASSERT(!(*it)->isReference());
ASSERT_EQUALS(1U, (*it)->dimensions().size());
ASSERT_EQUALS(4U, (*it)->dimension(0));
vt = (*it)->valueType();
ASSERT_EQUALS(vt->pointer, 0);
tok = (*it)->nameToken();
ASSERT(tok && (vt = tok->valueType()));
ASSERT_EQUALS(vt->pointer, 1);
++it;
ASSERT((*it)->isArray());
ASSERT(!(*it)->isPointer());
ASSERT((*it)->isReference());
ASSERT((*it)->isConst());
ASSERT_EQUALS(1U, (*it)->dimensions().size());
ASSERT_EQUALS(4U, (*it)->dimension(0));
vt = (*it)->valueType();
ASSERT_EQUALS(vt->pointer, 0);
ASSERT(vt->reference == Reference::LValue);
tok = (*it)->nameToken();
ASSERT(tok && (vt = tok->valueType()));
ASSERT_EQUALS(vt->pointer, 0);
ASSERT_EQUALS(vt->constness, 1);
ASSERT(vt->reference == Reference::LValue);
}
void test_isVariableDeclarationCanHandleNull() {
reset();
GET_SYMBOL_DB("void main(){}");