Skip to content

Commit 789c032

Browse files
Fix #12138 FP passedByValue with anonymous union (#5611)
1 parent df860a9 commit 789c032

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

lib/checkother.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,16 +1200,22 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
12001200
else
12011201
cumulatedSize += size;
12021202
};
1203-
for (const Variable&var : type->classScope->varlist) {
1203+
std::set<const Scope*> anonScopes;
1204+
for (const Variable& var : type->classScope->varlist) {
12041205
int size = 0;
12051206
if (var.isStatic())
12061207
continue;
12071208
if (var.isPointer() || var.isReference())
12081209
size = settings->platform.sizeof_pointer;
12091210
else if (var.type() && var.type()->classScope)
1210-
size = estimateSize(var.type(), settings, symbolDatabase, recursionDepth+1);
1211+
size = estimateSize(var.type(), settings, symbolDatabase, recursionDepth + 1);
12111212
else if (var.valueType() && var.valueType()->type == ValueType::Type::CONTAINER)
12121213
size = 3 * settings->platform.sizeof_pointer; // Just guess
1214+
else if (var.nameToken()->scope() != type->classScope && var.nameToken()->scope()->definedType) { // anonymous union
1215+
const auto ret = anonScopes.insert(var.nameToken()->scope());
1216+
if (ret.second)
1217+
size = estimateSize(var.nameToken()->scope()->definedType, settings, symbolDatabase, recursionDepth + 1);
1218+
}
12131219
else
12141220
size = symbolDatabase->sizeOfType(var.typeStartToken());
12151221

test/testother.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,6 +2172,25 @@ class TestOther : public TestFixture {
21722172
"}\n");
21732173
ASSERT_EQUALS("[test.cpp:1]: (performance) Function parameter 't' should be passed by const reference.\n", errout.str());
21742174

2175+
check("struct S {\n" // #12138
2176+
" union {\n"
2177+
" int a = 0;\n"
2178+
" int x;\n"
2179+
" };\n"
2180+
" union {\n"
2181+
" int b = 0;\n"
2182+
" int y;\n"
2183+
" };\n"
2184+
" union {\n"
2185+
" int c = 0;\n"
2186+
" int z;\n"
2187+
" };\n"
2188+
"};\n"
2189+
"void f(S s) {\n"
2190+
" if (s.x > s.y) {}\n"
2191+
"}\n");
2192+
ASSERT_EQUALS("", errout.str());
2193+
21752194
Settings settings1 = settingsBuilder().platform(Platform::Type::Win64).build();
21762195
check("using ui64 = unsigned __int64;\n"
21772196
"ui64 Test(ui64 one, ui64 two) { return one + two; }\n",

0 commit comments

Comments
 (0)