https://github.com/higher-performance updated 
https://github.com/llvm/llvm-project/pull/141133

>From f384cb655ca7412f80427fafb47a26c74917b9ff Mon Sep 17 00:00:00 2001
From: higher-performance <higher.performance.git...@gmail.com>
Date: Thu, 22 May 2025 16:30:29 -0400
Subject: [PATCH 1/2] Include [[clang::require_explicit_initialization]]
 warnings in system headers

Fixes #141103
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  3 ++-
 clang/test/SemaCXX/uninitialized.cpp          | 27 ++++++++++++++++---
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0b2553d82153c..934f4453f02b9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2479,7 +2479,8 @@ def note_uninit_reference_member : Note<
   "uninitialized reference member is here">;
 def warn_field_requires_explicit_init : Warning<
   "field %select{%1|in %1}0 requires explicit initialization but is not "
-   "explicitly initialized">, InGroup<UninitializedExplicitInit>;
+   "explicitly initialized">, InGroup<UninitializedExplicitInit>,
+   ShowInSystemHeader;
 def warn_field_is_uninit : Warning<"field %0 is uninitialized when used here">,
   InGroup<Uninitialized>;
 def warn_base_class_is_uninit : Warning<
diff --git a/clang/test/SemaCXX/uninitialized.cpp 
b/clang/test/SemaCXX/uninitialized.cpp
index c7cef3e06fb2b..98e1e93ec53cc 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -2,6 +2,23 @@
 // 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
 
+#if defined(BE_THE_HEADER)
+
+// Wuninitialized-explicit-init should warn in system headers 
(std::construct_at...) too.
+
+#pragma clang system_header
+namespace std {
+template <class T, class... U>
+constexpr T* construct_at(T* ptr, U&&... args) {
+  return ::new (static_cast<void*>(ptr)) T(static_cast<U&&>(args)...);  // 
#FIELD_EMBED2_CONSTRUCT_AT
+}
+}
+
+#else
+
+#define BE_THE_HEADER
+#include __FILE__
+
 void* operator new(__SIZE_TYPE__, void*);
 
 // definitions for std::move
@@ -1564,11 +1581,11 @@ void aggregate() {
     explicit F(const char(&)[1]) : f1() {
       // expected-warning@+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@+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@#FIELD_EMBED2_CONSTRUCT_AT {{field in 'Embed' 
requires explicit initialization but is not explicitly initialized}} 
expected-note@+1 {{in instantiation of function template specialization 
'std::construct_at<Embed>' requested here}} expected-note@#FIELD_EMBED2 
{{'embed2' declared here}}
+      std::construct_at(&f1);
 #if __cplusplus >= 202002L
-      // expected-warning@+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);
+      // expected-warning@#FIELD_EMBED2_CONSTRUCT_AT {{field 'embed2' requires 
explicit initialization but is not explicitly initialized}} expected-note@+1 
{{in instantiation of function template specialization 
'std::construct_at<Embed, int>' requested here}} expected-note@#FIELD_EMBED2 
{{'embed2' declared here}}
+      std::construct_at(&f1, 1);
 #endif
       // expected-warning@+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};
@@ -1726,3 +1743,5 @@ void aggregate() {
   InheritWithExplicit<Special> specialized_implicit;  // no-warning
   (void)specialized_implicit;
 }
+
+#endif

>From c5d3605436197426f08724369c6e0acf534b6cab Mon Sep 17 00:00:00 2001
From: higher-performance <higher.performance.git...@gmail.com>
Date: Tue, 27 May 2025 16:37:01 -0400
Subject: [PATCH 2/2] Suppress [[clang::require_explicit_initialization]] in
 unevaluated operands

---
 clang/include/clang/Basic/AttrDocs.td |  6 +++---
 clang/lib/Sema/SemaInit.cpp           | 14 +++++++++-----
 clang/test/Sema/uninit-variables.c    |  2 ++
 clang/test/SemaCXX/uninitialized.cpp  |  2 ++
 4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 43442f177ab7b..fefdaba7f8bf5 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -1750,9 +1750,9 @@ to guard against use of uninitialized memory.
 
 Rather, it is intended for use in "parameter-objects", used to simulate,
 for example, the passing of named parameters.
-The attribute generates a warning when explicit initializers for such
-variables are not provided (this occurs regardless of whether any in-class 
field
-initializers exist):
+Except inside unevaluated contexts, the attribute generates a warning when
+explicit initializers for such variables are not provided (this occurs
+regardless of whether any in-class field initializers exist):
 
 .. code-block:: c++
 
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 0844cb4d6c3cd..95746b35f71ef 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -790,7 +790,8 @@ void InitListChecker::FillInEmptyInitForField(unsigned 
Init, FieldDecl *Field,
       return;
     }
 
-    if (!VerifyOnly && Field->hasAttr<ExplicitInitAttr>()) {
+    if (!VerifyOnly && Field->hasAttr<ExplicitInitAttr>() &&
+        !SemaRef.isUnevaluatedContext()) {
       SemaRef.Diag(ILE->getExprLoc(), diag::warn_field_requires_explicit_init)
           << /* Var-in-Record */ 0 << Field;
       SemaRef.Diag(Field->getLocation(), diag::note_entity_declared_at)
@@ -4631,7 +4632,8 @@ static void TryConstructorInitialization(Sema &S,
          Kind.getKind() == InitializationKind::IK_Direct) &&
         !(CtorDecl->isCopyOrMoveConstructor() && CtorDecl->isImplicit()) &&
         DestRecordDecl->isAggregate() &&
-        DestRecordDecl->hasUninitializedExplicitInitFields()) {
+        DestRecordDecl->hasUninitializedExplicitInitFields() &&
+        !S.isUnevaluatedContext()) {
       S.Diag(Kind.getLocation(), diag::warn_field_requires_explicit_init)
           << /* Var-in-Record */ 1 << DestRecordDecl;
       emitUninitializedExplicitInitFields(S, DestRecordDecl);
@@ -5995,7 +5997,8 @@ static void TryOrBuildParenListInitialization(
       } else {
         // We've processed all of the args, but there are still members that
         // have to be initialized.
-        if (!VerifyOnly && FD->hasAttr<ExplicitInitAttr>()) {
+        if (!VerifyOnly && FD->hasAttr<ExplicitInitAttr>() &&
+            !S.isUnevaluatedContext()) {
           S.Diag(Kind.getLocation(), diag::warn_field_requires_explicit_init)
               << /* Var-in-Record */ 0 << FD;
           S.Diag(FD->getLocation(), diag::note_entity_declared_at) << FD;
@@ -6617,7 +6620,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
     if (RecordDecl *Rec = DestType->getAsRecordDecl()) {
       VarDecl *Var = dyn_cast_or_null<VarDecl>(Entity.getDecl());
       if (Rec->hasUninitializedExplicitInitFields()) {
-        if (Var && !Initializer) {
+        if (Var && !Initializer && !S.isUnevaluatedContext()) {
           S.Diag(Var->getLocation(), diag::warn_field_requires_explicit_init)
               << /* Var-in-Record */ 1 << Rec;
           emitUninitializedExplicitInitFields(S, Rec);
@@ -7481,7 +7484,8 @@ PerformConstructorInitialization(Sema &S,
       if (RD && RD->isAggregate() && RD->hasUninitializedExplicitInitFields()) 
{
         unsigned I = 0;
         for (const FieldDecl *FD : RD->fields()) {
-          if (I >= ConstructorArgs.size() && FD->hasAttr<ExplicitInitAttr>()) {
+          if (I >= ConstructorArgs.size() && FD->hasAttr<ExplicitInitAttr>() &&
+              !S.isUnevaluatedContext()) {
             S.Diag(Loc, diag::warn_field_requires_explicit_init)
                 << /* Var-in-Record */ 0 << FD;
             S.Diag(FD->getLocation(), diag::note_entity_declared_at) << FD;
diff --git a/clang/test/Sema/uninit-variables.c 
b/clang/test/Sema/uninit-variables.c
index 6d79d419f72e7..17e83de5f489a 100644
--- a/clang/test/Sema/uninit-variables.c
+++ b/clang/test/Sema/uninit-variables.c
@@ -580,4 +580,6 @@ void aggregate() {
 
   struct with_explicit_flex_array f = {2}; // expected-warning {{field 
'flex_arr' requires explicit initialization but is not explicitly initialized}} 
expected-note@#FIELD_FLEX_ARR {{'flex_arr' declared here}}
   (void)f;
+
+  (void)sizeof({ struct with_explicit_field a; a; });  // no warning -- 
unevaluated operand
 }
diff --git a/clang/test/SemaCXX/uninitialized.cpp 
b/clang/test/SemaCXX/uninitialized.cpp
index 98e1e93ec53cc..251e888f73973 100644
--- a/clang/test/SemaCXX/uninitialized.cpp
+++ b/clang/test/SemaCXX/uninitialized.cpp
@@ -1642,6 +1642,8 @@ void aggregate() {
   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}}
 
+  (void)sizeof(S{}); // no warning -- unevaluated operand
+
   S s{.s1 = 100, .s4 = 100};
   (void)s;
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to