[clang] [Clang][Sema] Diagnosis for constexpr constructor not initializing a union member (PR #81042)

via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 8 00:58:22 PST 2024


https://github.com/mahtohappy updated https://github.com/llvm/llvm-project/pull/81042

>From 9271e67ab27f850413e3d6d6f1383454067efe75 Mon Sep 17 00:00:00 2001
From: mahtohappy <Happy.Kumar at windriver.com>
Date: Wed, 7 Feb 2024 13:29:45 -0800
Subject: [PATCH 1/2] Diagnosis for constexpr constructor not initializing a
 union member

---
 clang/lib/Sema/SemaDeclCXX.cpp                | 19 +++++++++++++++++++
 .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp |  3 +++
 .../SemaCXX/constexpr-union-temp-ctor-cxx.cpp | 18 ++++++++++++++++++
 3 files changed, 40 insertions(+)
 create mode 100644 clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5adc262cd6bc97..ef4e274389f60b 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2393,6 +2393,25 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
                                              Kind))
             return false;
       }
+    } else if(!Constructor->isDelegatingConstructor()){
+      for(const Decl* decl : RD->decls()){
+        if(const auto* inner = dyn_cast<CXXRecordDecl>(decl)){
+          if(inner->isUnion()){
+              if (Constructor->getNumCtorInitializers() == 0 &&
+                RD->hasVariantMembers()) {
+              if (Kind == Sema::CheckConstexprKind::Diagnose) {
+                SemaRef.Diag(
+                    Dcl->getLocation(),
+                    SemaRef.getLangOpts().CPlusPlus20
+                        ? diag::warn_cxx17_compat_constexpr_union_ctor_no_init
+                        : diag::ext_constexpr_union_ctor_no_init);
+              } else if (!SemaRef.getLangOpts().CPlusPlus20) {
+                return false;
+              }
+            }
+          }
+        }
+      }
     }
   } else {
     if (ReturnStmts.empty()) {
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index f1f677ebfcd341..0d9b4d740a7c11 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -224,6 +224,9 @@ struct TemplateInit {
   };
   // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
   constexpr TemplateInit() {} // desired-error {{must initialize all members}}
+#ifndef CXX2A
+  // expected-error at 226 {{constexpr union constructor that does not initialize any member is a C++20 extension}}
+#endif
 };
 template<typename T> struct TemplateInit2 {
   Literal l;
diff --git a/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp b/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp
new file mode 100644
index 00000000000000..1300641f28f1c6
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++14 -verify -fcxx-exceptions -Werror=c++14-extensions -Werror=c++20-extensions %s
+
+template <class> struct C {
+    union {
+      int i;
+    };
+    constexpr C() {} // expected-error {{constexpr union constructor that does not initialize any member is a C++20 extension}}
+};
+constexpr C<int> c;
+
+template <class> class D {
+    union {
+      int i;
+    };
+public:
+    constexpr D() {} // expected-error {{constexpr union constructor that does not initialize any member is a C++20 extension}}
+};
+constexpr D<int> d;
\ No newline at end of file

>From a6e1168db911fbb6778f2711f685a0feaf97a9f5 Mon Sep 17 00:00:00 2001
From: mahtohappy <Happy.Kumar at windriver.com>
Date: Thu, 8 Feb 2024 00:55:58 -0800
Subject: [PATCH 2/2] [Clang][Sema] Diagnosis for constexpr constructor not
 initializing a union member

---
 clang/docs/ReleaseNotes.rst                          | 2 +-
 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp | 2 +-
 clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1d278fe032d264..46a03b7c91220d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -150,7 +150,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses member template declarations with multiple declarators.
 - Clang now diagnoses use of the ``template`` keyword after declarative nested name specifiers.
-- Clang now diagnoses constexpr constructor for not initializing atleast one member
+- Clang now diagnoses constexpr constructor for not initializing atleast one member of union
 - Fixes(`#46689 Constexpr constructor not initializing a union member is not diagnosed`)
 
 Improvements to Clang's time-trace
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
index 0d9b4d740a7c11..37c9e2c36ad657 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -225,7 +225,7 @@ struct TemplateInit {
   // FIXME: This is ill-formed (no diagnostic required). We should diagnose it.
   constexpr TemplateInit() {} // desired-error {{must initialize all members}}
 #ifndef CXX2A
-  // expected-error at 226 {{constexpr union constructor that does not initialize any member is a C++20 extension}}
+  // expected-error at -2 {{constexpr union constructor that does not initialize any member is a C++20 extension}}
 #endif
 };
 template<typename T> struct TemplateInit2 {
diff --git a/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp b/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp
index 1300641f28f1c6..519e0557a0e393 100644
--- a/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp
+++ b/clang/test/SemaCXX/constexpr-union-temp-ctor-cxx.cpp
@@ -15,4 +15,4 @@ template <class> class D {
 public:
     constexpr D() {} // expected-error {{constexpr union constructor that does not initialize any member is a C++20 extension}}
 };
-constexpr D<int> d;
\ No newline at end of file
+constexpr D<int> d;



More information about the cfe-commits mailing list