[clang] Diagnosis for constexpr constructor not initializing a union member Resolves #46689 (PR #81042)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 7 15:23:25 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] 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
More information about the cfe-commits
mailing list