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:
parent
f0ebaf9536
commit
1c11d3039d
|
@ -6037,7 +6037,12 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocatio
|
||||||
valuetype.setDebugPath(tok, loc);
|
valuetype.setDebugPath(tok, loc);
|
||||||
if (var.nameToken())
|
if (var.nameToken())
|
||||||
valuetype.bits = var.nameToken()->bits();
|
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();
|
valuetype.typeScope = var.typeScope();
|
||||||
if (var.valueType()) {
|
if (var.valueType()) {
|
||||||
valuetype.container = var.valueType()->container;
|
valuetype.container = var.valueType()->container;
|
||||||
|
|
|
@ -67,6 +67,12 @@ private:
|
||||||
" CharArray foo = \"\";\n"
|
" CharArray foo = \"\";\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void novardecl() {
|
||||||
|
|
|
@ -1714,6 +1714,13 @@ private:
|
||||||
" return it->foo;\n"
|
" return it->foo;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void returnReferenceLiteral() {
|
||||||
|
|
|
@ -130,6 +130,7 @@ private:
|
||||||
TEST_CASE(array_ptr);
|
TEST_CASE(array_ptr);
|
||||||
TEST_CASE(stlarray1);
|
TEST_CASE(stlarray1);
|
||||||
TEST_CASE(stlarray2);
|
TEST_CASE(stlarray2);
|
||||||
|
TEST_CASE(stlarray3);
|
||||||
|
|
||||||
TEST_CASE(test_isVariableDeclarationCanHandleNull);
|
TEST_CASE(test_isVariableDeclarationCanHandleNull);
|
||||||
TEST_CASE(test_isVariableDeclarationIdentifiesSimpleDeclaration);
|
TEST_CASE(test_isVariableDeclarationIdentifiesSimpleDeclaration);
|
||||||
|
@ -573,6 +574,56 @@ private:
|
||||||
ASSERT_EQUALS(20U, v->dimension(0));
|
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() {
|
void test_isVariableDeclarationCanHandleNull() {
|
||||||
reset();
|
reset();
|
||||||
GET_SYMBOL_DB("void main(){}");
|
GET_SYMBOL_DB("void main(){}");
|
||||||
|
|
Loading…
Reference in New Issue