[llvm-branch-commits] [clang] release/20.x: Fix false negative when value initializing a field annotated with [[clang::require_field_initialization]] (#124329) (PR #125249)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jan 31 08:51:15 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (llvmbot)
<details>
<summary>Changes</summary>
Backport 20fd7df0b847bb46aac2f0b5b71d242220027cbc
Requested by: @<!-- -->higher-performance
---
Full diff: https://github.com/llvm/llvm-project/pull/125249.diff
2 Files Affected:
- (modified) clang/lib/Sema/SemaInit.cpp (+3-1)
- (modified) clang/test/SemaCXX/uninitialized.cpp (+44)
``````````diff
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index b95cbbf42220568..450edcb52ae15ba 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -4573,7 +4573,9 @@ static void TryConstructorInitialization(Sema &S,
CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
if (Result != OR_Deleted) {
- if (!IsListInit && Kind.getKind() == InitializationKind::IK_Default &&
+ if (!IsListInit &&
+ (Kind.getKind() == InitializationKind::IK_Default ||
+ Kind.getKind() == InitializationKind::IK_Direct) &&
DestRecordDecl != nullptr && DestRecordDecl->isAggregate() &&
DestRecordDecl->hasUninitializedExplicitInitFields()) {
S.Diag(Kind.getLocation(), diag::warn_field_requires_explicit_init)
diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp
index 52d9897cf9be6e7..7578b288d7b3fe7 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -2,6 +2,8 @@
// RUN: %clang_cc1 -fsyntax-only -Wall -Wc++20-compat -Wuninitialized -Wno-unused-value -Wno-unused-lambda-capture -Wno-uninitialized-const-reference -std=c++1z -verify %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -fsyntax-only -Wall -Wc++20-compat -Wuninitialized -Wno-unused-value -Wno-unused-lambda-capture -Wno-uninitialized-const-reference -std=c++20 -verify %s
+void* operator new(__SIZE_TYPE__, void*);
+
// definitions for std::move
namespace std {
inline namespace foo {
@@ -1540,6 +1542,48 @@ void aggregate() {
};
};
+ struct Embed {
+ int embed1; // #FIELD_EMBED1
+ int embed2 [[clang::require_explicit_initialization]]; // #FIELD_EMBED2
+ };
+ struct EmbedDerived : Embed {};
+ struct F {
+ Embed f1;
+ // expected-warning at +1 {{field in 'Embed' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ explicit F(const char(&)[1]) : f1() {
+ // expected-warning at +1 {{field in 'Embed' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ ::new(static_cast<void*>(&f1)) decltype(f1);
+ // expected-warning at +1 {{field in 'Embed' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ ::new(static_cast<void*>(&f1)) decltype(f1)();
+#if __cplusplus >= 202002L
+ // expected-warning at +1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ ::new(static_cast<void*>(&f1)) decltype(f1)(1);
+#endif
+ // expected-warning at +1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ ::new(static_cast<void*>(&f1)) decltype(f1){1};
+ }
+#if __cplusplus >= 202002L
+ // expected-warning at +1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ explicit F(const char(&)[2]) : f1(1) {}
+#else
+ explicit F(const char(&)[2]) : f1{1, 2} { }
+#endif
+ // expected-warning at +1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ explicit F(const char(&)[3]) : f1{} {}
+ // expected-warning at +1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ explicit F(const char(&)[4]) : f1{1} {}
+ // expected-warning at +1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}}
+ explicit F(const char(&)[5]) : f1{.embed1 = 1} {}
+ };
+ F ctors[] = {
+ F(""),
+ F("_"),
+ F("__"),
+ F("___"),
+ F("____")
+ };
+ (void)ctors;
+
S::foo(S{1, 2, 3, 4});
S::foo(S{.s1 = 100, .s4 = 100});
S::foo(S{.s1 = 100}); // expected-warning {{field 's4' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_S4 {{'s4' declared here}}
``````````
</details>
https://github.com/llvm/llvm-project/pull/125249
More information about the llvm-branch-commits
mailing list