Skip to content

Commit 9797b5f

Browse files
authored
[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.
1 parent 7ffdf42 commit 9797b5f

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ Bug Fixes in This Version
693693
- Fixed type mismatch error when 'builtin-elementwise-math' arguments have different qualifiers, this should be well-formed. (#GH141397)
694694
- Constant evaluation now correctly runs the destructor of a variable declared in
695695
the second clause of a C-style ``for`` loop. (#GH139818)
696+
- Fixed a bug with constexpr evaluation for structs containing unions in case of C++ modules. (#GH143168)
696697

697698
Bug Fixes to Compiler Builtins
698699
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6844,7 +6844,8 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
68446844
// FIXME: In this case, the values of the other subobjects are
68456845
// specified, since zero-initialization sets all padding bits to zero.
68466846
if (!Value->hasValue() ||
6847-
(Value->isUnion() && Value->getUnionField() != FD)) {
6847+
(Value->isUnion() &&
6848+
!declaresSameEntity(Value->getUnionField(), FD))) {
68486849
if (CD->isUnion())
68496850
*Value = APValue(FD);
68506851
else
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: rm -fR %t
2+
// RUN: split-file %s %t
3+
// RUN: cd %t
4+
// RUN: %clang_cc1 -verify -w -std=c++20 -fmodule-name=h1.h -emit-header-unit -xc++-user-header h1.h -o h1.pcm
5+
// RUN: %clang_cc1 -verify -w -std=c++20 -fmodule-map-file=module.modulemap -fmodule-file=h1.h=h1.pcm main.cpp -o main.o
6+
7+
//--- module.modulemap
8+
module "h1.h" {
9+
header "h1.h"
10+
export *
11+
}
12+
13+
//--- h0.h
14+
// expected-no-diagnostics
15+
#pragma once
16+
17+
template <typename T> struct A {
18+
union {
19+
struct {
20+
T x, y, z;
21+
};
22+
};
23+
constexpr A(T, T, T) : x(), y(), z() {}
24+
};
25+
typedef A<float> packed_vec3;
26+
27+
//--- h1.h
28+
// expected-no-diagnostics
29+
#pragma once
30+
31+
#include "h0.h"
32+
33+
constexpr packed_vec3 kMessThingsUp = packed_vec3(5.0f, 5.0f, 5.0f);
34+
35+
//--- main.cpp
36+
// expected-no-diagnostics
37+
#include "h0.h"
38+
39+
static_assert(sizeof(packed_vec3) == sizeof(float) * 3);
40+
static_assert(alignof(packed_vec3) == sizeof(float));
41+
42+
import "h1.h";
43+
44+
constexpr packed_vec3 kDefaultHalfExtents = packed_vec3(5.0f, 5.0f, 5.0f);

0 commit comments

Comments
 (0)