llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-modules

Author: Dmitry Polukhin (dmpolukhin)

<details>
<summary>Changes</summary>

Use canonical field decl when evaluating constexpr to avoid resetting computed 
union value due to using different instances of the merged field decl. Pointer 
to the field comparison `Value-&gt;isUnion() &amp;&amp; 
Value-&gt;getUnionField() != FD` few lines below requires stable ID for the 
field and canonical decl seems to be good option.

---
Full diff: https://github.com/llvm/llvm-project/pull/143168.diff


2 Files Affected:

- (modified) clang/lib/AST/ExprConstant.cpp (+1-1) 
- (added) clang/test/Modules/constexpr-initialization-failure.cpp (+44) 


``````````diff
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d1cc722fb7945..8f7016d8256fb 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6781,7 +6781,7 @@ static bool HandleConstructorCall(const Expr *E, const 
LValue &This,
       // and make sure we've initialized every step along it.
       auto IndirectFieldChain = IFD->chain();
       for (auto *C : IndirectFieldChain) {
-        FD = cast<FieldDecl>(C);
+        FD = cast<FieldDecl>(C)->getCanonicalDecl();
         CXXRecordDecl *CD = cast<CXXRecordDecl>(FD->getParent());
         // Switch the union field if it differs. This happens if we had
         // preceding zero-initialization, and we're now initializing a union
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);

``````````

</details>


https://github.com/llvm/llvm-project/pull/143168
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to