Skip to content

Commit cc00e6a

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 c738308 commit cc00e6a

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
@@ -6836,7 +6836,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
68366836
// and make sure we've initialized every step along it.
68376837
auto IndirectFieldChain = IFD->chain();
68386838
for (auto *C : IndirectFieldChain) {
6839-
FD = cast<FieldDecl>(C);
6839+
FD = cast<FieldDecl>(C)->getCanonicalDecl();
68406840
CXXRecordDecl *CD = cast<CXXRecordDecl>(FD->getParent());
68416841
// Switch the union field if it differs. This happens if we had
68426842
// 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)