[clang] 9797b5f - [C++20][Modules] Fix false compilation error with constexpr (#143168)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 11 02:35:10 PDT 2025
Author: Dmitry Polukhin
Date: 2025-06-11T10:35:06+01:00
New Revision: 9797b5fcfbb9b9c96a219985f3623849bbd3956e
URL: https://github.com/llvm/llvm-project/commit/9797b5fcfbb9b9c96a219985f3623849bbd3956e
DIFF: https://github.com/llvm/llvm-project/commit/9797b5fcfbb9b9c96a219985f3623849bbd3956e.diff
LOG: [C++20][Modules] Fix false compilation error with constexpr (#143168)
Use declaresSameEntity when evaluating constexpr to avoid resetting
computed union value due to using different instances of the merged
field decl.
Added:
clang/test/Modules/constexpr-initialization-failure.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5645edc73431b..b5e6cf088a4b1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -693,6 +693,7 @@ Bug Fixes in This Version
- Fixed type mismatch error when 'builtin-elementwise-math' arguments have
diff erent qualifiers, this should be well-formed. (#GH141397)
- Constant evaluation now correctly runs the destructor of a variable declared in
the second clause of a C-style ``for`` loop. (#GH139818)
+- Fixed a bug with constexpr evaluation for structs containing unions in case of C++ modules. (#GH143168)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fa4e10e84de05..27ea55e981446 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6844,7 +6844,8 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
// FIXME: In this case, the values of the other subobjects are
// specified, since zero-initialization sets all padding bits to zero.
if (!Value->hasValue() ||
- (Value->isUnion() && Value->getUnionField() != FD)) {
+ (Value->isUnion() &&
+ !declaresSameEntity(Value->getUnionField(), FD))) {
if (CD->isUnion())
*Value = APValue(FD);
else
diff --git a/clang/test/Modules/constexpr-initialization-failure.cpp b/clang/test/Modules/constexpr-initialization-failure.cpp
new file mode 100644
index 0000000000000..8ff20f2fc8ac6
--- /dev/null
+++ b/clang/test/Modules/constexpr-initialization-failure.cpp
@@ -0,0 +1,44 @@
+// RUN: rm -fR %t
+// RUN: split-file %s %t
+// RUN: cd %t
+// RUN: %clang_cc1 -verify -w -std=c++20 -fmodule-name=h1.h -emit-header-unit -xc++-user-header h1.h -o h1.pcm
+// RUN: %clang_cc1 -verify -w -std=c++20 -fmodule-map-file=module.modulemap -fmodule-file=h1.h=h1.pcm main.cpp -o main.o
+
+//--- module.modulemap
+module "h1.h" {
+ header "h1.h"
+ export *
+}
+
+//--- h0.h
+// expected-no-diagnostics
+#pragma once
+
+template <typename T> struct A {
+ union {
+ struct {
+ T x, y, z;
+ };
+ };
+ constexpr A(T, T, T) : x(), y(), z() {}
+};
+typedef A<float> packed_vec3;
+
+//--- h1.h
+// expected-no-diagnostics
+#pragma once
+
+#include "h0.h"
+
+constexpr packed_vec3 kMessThingsUp = packed_vec3(5.0f, 5.0f, 5.0f);
+
+//--- main.cpp
+// expected-no-diagnostics
+#include "h0.h"
+
+static_assert(sizeof(packed_vec3) == sizeof(float) * 3);
+static_assert(alignof(packed_vec3) == sizeof(float));
+
+import "h1.h";
+
+constexpr packed_vec3 kDefaultHalfExtents = packed_vec3(5.0f, 5.0f, 5.0f);
More information about the cfe-commits
mailing list