Skip to content

Commit b8fbea9

Browse files
autoantwortclaude
andcommitted
Const/reference member of non-class type inhibits uninitMemberVarNoCtor for all members
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent ba74606 commit b8fbea9

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

‎lib/checkclass.cpp‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ void CheckClassImpl::constructors()
347347
// Variables with default initializers
348348
bool hasAnyDefaultInit = false;
349349
bool hasAnySelfInit = false;
350+
bool isDefaultConstructible = true;
350351
const bool cpp14OrLater = mSettings.standards.cpp >= Standards::CPP14;
351352
for (Usage& usage : usageList) {
352353
const Variable& var = *usage.var;
@@ -355,11 +356,14 @@ void CheckClassImpl::constructors()
355356
if (var.hasDefault()) {
356357
usage.init = true;
357358
hasAnyDefaultInit = true;
359+
} else if (var.isReference() || (var.isConst() && !var.isClass())) {
360+
// the default constructor is deleted, so all members are initialized by every instance
361+
isDefaultConstructible = false;
358362
} else if (cpp14OrLater && !hasAnySelfInit && isInitialized(usage, FunctionType::eConstructor)) {
359363
hasAnySelfInit = true;
360364
}
361365
}
362-
if (!hasAnyDefaultInit && !hasAnySelfInit)
366+
if (!isDefaultConstructible || (!hasAnyDefaultInit && !hasAnySelfInit))
363367
continue;
364368

365369
handleUnionMembers(usageList);
@@ -373,8 +377,8 @@ void CheckClassImpl::constructors()
373377
if (var.typeScope() && var.typeScope()->numConstructors > 0)
374378
continue;
375379

376-
// const and reference members without default initializer must be initialized by every instance
377-
if (var.isConst() || var.isReference())
380+
// a const member of class type is default constructed or makes the class not default constructible
381+
if (var.isConst())
378382
continue;
379383

380384
if (diagVars.count(&var) == 0)

‎test/testconstructors.cpp‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -798,13 +798,32 @@ class TestConstructors : public TestFixture {
798798
"[test.cpp:8:9]: (warning) Member variable 'U::k' has no initializer. [uninitMemberVarNoCtor]\n",
799799
errout_str());
800800

801-
check("struct S {\n" // const and reference members can't stay uninitialized
801+
check("struct S {\n" // #15080
802802
" int a = 0;\n"
803803
" const int b;\n"
804+
" int k;\n"
805+
"};\n");
806+
ASSERT_EQUALS("", errout_str());
807+
808+
check("struct S {\n"
809+
" int a = 0;\n"
804810
" int& c;\n"
811+
" int k;\n"
812+
"};\n");
813+
ASSERT_EQUALS("", errout_str());
814+
815+
check("struct S {\n"
816+
" int a = 0;\n"
805817
" const int* d;\n"
806818
"};\n");
807-
ASSERT_EQUALS("[test.cpp:5:16]: (warning) Member variable 'S::d' has no initializer. [uninitMemberVarNoCtor]\n", errout_str());
819+
ASSERT_EQUALS("[test.cpp:3:16]: (warning) Member variable 'S::d' has no initializer. [uninitMemberVarNoCtor]\n", errout_str());
820+
821+
check("struct S {\n"
822+
" std::string a;\n"
823+
" const std::string s;\n"
824+
" int k;\n"
825+
"};\n");
826+
ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str());
808827

809828
check("struct S {\n"
810829
" const std::array<std::uint8_t, 2> a;\n"

0 commit comments

Comments
 (0)