Skip to content

Commit 010a693

Browse files
committed
[C++20][Modules] Fix false compilation error with constexpr
Use cannonical field decl when evaluating constexpr to avoid resetting computed union value due to using different instances of merged decls.
1 parent f133eae commit 010a693

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6781,7 +6781,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
67816781
// and make sure we've initialized every step along it.
67826782
auto IndirectFieldChain = IFD->chain();
67836783
for (auto *C : IndirectFieldChain) {
6784-
FD = cast<FieldDecl>(C);
6784+
FD = cast<FieldDecl>(C)->getCanonicalDecl();
67856785
CXXRecordDecl *CD = cast<CXXRecordDecl>(FD->getParent());
67866786
// Switch the union field if it differs. This happens if we had
67876787
// preceding zero-initialization, and we're now initializing a union
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)