diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 322686fce0b04..d62ecb438ae68 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -689,6 +689,7 @@ Bug Fixes in This Version - Fixed type mismatch error when 'builtin-elementwise-math' arguments have different 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 struct A { + union { + struct { + T x, y, z; + }; + }; + constexpr A(T, T, T) : x(), y(), z() {} +}; +typedef A 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);