Skip to content

Commit d901661

Browse files
Fix #14697 FN uninitMemberVarNoCtor when mixing (un)initialized member variables (#8557)
After #8556 --------- Co-authored-by: chrchr-github <noreply@github.com>
1 parent f7f0549 commit d901661

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

lib/checkclass.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,20 @@ void CheckClass::constructors()
346346

347347
// Variables with default initializers
348348
bool hasAnyDefaultInit = false;
349+
bool hasAnySelfInit = false;
350+
const bool cpp14OrLater = mSettings->standards.cpp >= Standards::CPP14;
349351
for (Usage& usage : usageList) {
350352
const Variable& var = *usage.var;
351353

352354
// check for C++11 initializer
353355
if (var.hasDefault()) {
354356
usage.init = true;
355357
hasAnyDefaultInit = true;
358+
} else if (cpp14OrLater && !hasAnySelfInit && isInitialized(usage, FunctionType::eConstructor)) {
359+
hasAnySelfInit = true;
356360
}
357361
}
358-
if (!hasAnyDefaultInit)
362+
if (!hasAnyDefaultInit && !hasAnySelfInit)
359363
continue;
360364

361365
handleUnionMembers(usageList);
@@ -366,6 +370,9 @@ void CheckClass::constructors()
366370
continue;
367371

368372
const Variable& var = *usage.var;
373+
if (var.typeScope() && var.typeScope()->numConstructors > 0)
374+
continue;
375+
369376
if (diagVars.count(&var) == 0)
370377
uninitVarError(var.nameToken(), false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true);
371378
}

test/testconstructors.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,34 @@ class TestConstructors : public TestFixture {
769769
" int a, b;\n"
770770
"};\n");
771771
ASSERT_EQUALS("", errout_str());
772+
773+
check("struct S {\n"
774+
" explicit S(int);\n"
775+
" S(const S&);\n"
776+
" int i;\n"
777+
"};\n"
778+
"struct T {\n"
779+
" S s;\n"
780+
" int j{};\n"
781+
"};\n");
782+
ASSERT_EQUALS("", errout_str());
783+
784+
const char code[] = "struct S { int i = 0; };\n" // #14697
785+
"struct T {\n"
786+
" S s;\n"
787+
" int j;\n"
788+
"};\n"
789+
"struct U {\n"
790+
" std::string a;\n"
791+
" int k;\n"
792+
"};\n";
793+
const Settings s = settingsBuilder(settings).cpp(Standards::CPP11).build();
794+
check(code, s);
795+
ASSERT_EQUALS("", errout_str());
796+
check(code);
797+
ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'T::j' has no initializer. [uninitMemberVarNoCtor]\n"
798+
"[test.cpp:8:9]: (warning) Member variable 'U::k' has no initializer. [uninitMemberVarNoCtor]\n",
799+
errout_str());
772800
}
773801

774802
// ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor."

0 commit comments

Comments
 (0)