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->isUnion() && Value->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