From 1c11d3039d1164fca3dc20cf0a40f4f65a7ef63e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 17 Feb 2023 07:17:37 +0100 Subject: [PATCH] Fix FP returnTempReference (#4793) * Fix FP returnTempReference * Fix mismatch between token and variable ValueType * Format, clang-tidy * Add test * Format --- lib/symboldatabase.cpp | 7 ++++- test/test64bit.cpp | 6 +++++ test/testautovariables.cpp | 7 +++++ test/testsymboldatabase.cpp | 51 +++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 574d1b169..352de2c66 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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; diff --git a/test/test64bit.cpp b/test/test64bit.cpp index a5d69eada..0cd7f51cc 100644 --- a/test/test64bit.cpp +++ b/test/test64bit.cpp @@ -67,6 +67,12 @@ private: " CharArray foo = \"\";\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("struct T { std::vector*a[2][2]; };\n" // #11560 + "void f(T& t, int i, int j) {\n" + " t.a[i][j] = new std::vector;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void novardecl() { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 143b5175f..ad58f32c3 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -1714,6 +1714,13 @@ private: " return it->foo;\n" "}"); ASSERT_EQUALS("", errout.str()); + + check("static std::vector A[2];\n" + "static std::vector B;\n" + "std::vector& g(int i) {\n" + " return i ? A[i] : B;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void returnReferenceLiteral() { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 839ff37ab..dfc43d27e 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -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 a;\n" + "std::array b[2];\n" + "const std::array& 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(){}");