Skip to content

Commit 90192e8

Browse files
Fix false positive of [[clang::require_explicit_initialization]] on copy/move constructors (#126553)
Fixes #126490
1 parent be354cf commit 90192e8

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

clang/lib/Sema/SemaInit.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4576,7 +4576,9 @@ static void TryConstructorInitialization(Sema &S,
45764576
if (!IsListInit &&
45774577
(Kind.getKind() == InitializationKind::IK_Default ||
45784578
Kind.getKind() == InitializationKind::IK_Direct) &&
4579-
DestRecordDecl != nullptr && DestRecordDecl->isAggregate() &&
4579+
DestRecordDecl != nullptr &&
4580+
!(CtorDecl->isCopyOrMoveConstructor() && CtorDecl->isImplicit()) &&
4581+
DestRecordDecl->isAggregate() &&
45804582
DestRecordDecl->hasUninitializedExplicitInitFields()) {
45814583
S.Diag(Kind.getLocation(), diag::warn_field_requires_explicit_init)
45824584
<< /* Var-in-Record */ 1 << DestRecordDecl;

clang/test/SemaCXX/uninitialized.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1542,9 +1542,15 @@ void aggregate() {
15421542
};
15431543
};
15441544

1545+
struct CopyAndMove {
1546+
CopyAndMove() = default;
1547+
CopyAndMove(const CopyAndMove &) {}
1548+
CopyAndMove(CopyAndMove &&) {}
1549+
};
15451550
struct Embed {
15461551
int embed1; // #FIELD_EMBED1
15471552
int embed2 [[clang::require_explicit_initialization]]; // #FIELD_EMBED2
1553+
CopyAndMove force_separate_move_ctor;
15481554
};
15491555
struct EmbedDerived : Embed {};
15501556
struct F {
@@ -1582,7 +1588,33 @@ void aggregate() {
15821588
F("___"),
15831589
F("____")
15841590
};
1585-
(void)ctors;
1591+
1592+
struct MoveOrCopy {
1593+
Embed e;
1594+
EmbedDerived ed;
1595+
F f;
1596+
// no-error
1597+
MoveOrCopy(const MoveOrCopy &c) : e(c.e), ed(c.ed), f(c.f) {}
1598+
// no-error
1599+
MoveOrCopy(MoveOrCopy &&c)
1600+
: e(std::move(c.e)), ed(std::move(c.ed)), f(std::move(c.f)) {}
1601+
};
1602+
F copy1(ctors[0]); // no-error
1603+
(void)copy1;
1604+
F move1(std::move(ctors[0])); // no-error
1605+
(void)move1;
1606+
F copy2{ctors[0]}; // no-error
1607+
(void)copy2;
1608+
F move2{std::move(ctors[0])}; // no-error
1609+
(void)move2;
1610+
F copy3 = ctors[0]; // no-error
1611+
(void)copy3;
1612+
F move3 = std::move(ctors[0]); // no-error
1613+
(void)move3;
1614+
F copy4 = {ctors[0]}; // no-error
1615+
(void)copy4;
1616+
F move4 = {std::move(ctors[0])}; // no-error
1617+
(void)move4;
15861618

15871619
S::foo(S{1, 2, 3, 4});
15881620
S::foo(S{.s1 = 100, .s4 = 100});

0 commit comments

Comments
 (0)