@@ -25,41 +25,6 @@ using APSInt = llvm::APSInt;
25
25
namespace clang {
26
26
namespace interp {
27
27
28
- static bool hasTrivialDefaultCtorParent (const FieldDecl *FD) {
29
- assert (FD);
30
- assert (FD->getParent ()->isUnion ());
31
- const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->getParent ());
32
- return !CXXRD || CXXRD->hasTrivialDefaultConstructor ();
33
- }
34
-
35
- static bool refersToUnion (const Expr *E) {
36
- for (;;) {
37
- if (const auto *ME = dyn_cast<MemberExpr>(E)) {
38
- if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl ());
39
- FD && FD->getParent ()->isUnion () && hasTrivialDefaultCtorParent (FD))
40
- return true ;
41
- E = ME->getBase ();
42
- continue ;
43
- }
44
-
45
- if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
46
- E = ASE->getBase ()->IgnoreImplicit ();
47
- continue ;
48
- }
49
-
50
- if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
51
- ICE && (ICE->getCastKind () == CK_NoOp ||
52
- ICE->getCastKind () == CK_DerivedToBase ||
53
- ICE->getCastKind () == CK_UncheckedDerivedToBase)) {
54
- E = ICE->getSubExpr ();
55
- continue ;
56
- }
57
-
58
- break ;
59
- }
60
- return false ;
61
- }
62
-
63
28
static std::optional<bool > getBoolValue (const Expr *E) {
64
29
if (const auto *CE = dyn_cast_if_present<ConstantExpr>(E);
65
30
CE && CE->hasAPValueResult () &&
@@ -5409,6 +5374,53 @@ bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
5409
5374
return true ;
5410
5375
}
5411
5376
5377
+ static bool hasTrivialDefaultCtorParent (const FieldDecl *FD) {
5378
+ assert (FD);
5379
+ assert (FD->getParent ()->isUnion ());
5380
+ const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->getParent ());
5381
+ return !CXXRD || CXXRD->hasTrivialDefaultConstructor ();
5382
+ }
5383
+
5384
+ template <class Emitter > bool Compiler<Emitter>::refersToUnion(const Expr *E) {
5385
+ for (;;) {
5386
+ if (const auto *ME = dyn_cast<MemberExpr>(E)) {
5387
+ if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl ());
5388
+ FD && FD->getParent ()->isUnion () && hasTrivialDefaultCtorParent (FD))
5389
+ return true ;
5390
+ E = ME->getBase ();
5391
+ continue ;
5392
+ }
5393
+
5394
+ if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
5395
+ E = ASE->getBase ()->IgnoreImplicit ();
5396
+ continue ;
5397
+ }
5398
+
5399
+ if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
5400
+ ICE && (ICE->getCastKind () == CK_NoOp ||
5401
+ ICE->getCastKind () == CK_DerivedToBase ||
5402
+ ICE->getCastKind () == CK_UncheckedDerivedToBase)) {
5403
+ E = ICE->getSubExpr ();
5404
+ continue ;
5405
+ }
5406
+
5407
+ if (const auto *This = dyn_cast<CXXThisExpr>(E)) {
5408
+ const auto *ThisRecord =
5409
+ This->getType ()->getPointeeType ()->getAsRecordDecl ();
5410
+ if (!ThisRecord->isUnion ())
5411
+ return false ;
5412
+ // Otherwise, always activate if we're in the ctor.
5413
+ if (const auto *Ctor =
5414
+ dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
5415
+ return Ctor->getParent () == ThisRecord;
5416
+ return false ;
5417
+ }
5418
+
5419
+ break ;
5420
+ }
5421
+ return false ;
5422
+ }
5423
+
5412
5424
template <class Emitter >
5413
5425
bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS,
5414
5426
bool EvaluateConditionDecl) {
@@ -5941,16 +5953,15 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
5941
5953
return false ;
5942
5954
5943
5955
if (std::optional<PrimType> T = this ->classify (InitExpr)) {
5956
+ if (Activate && !this ->emitActivateThisField (FieldOffset, InitExpr))
5957
+ return false ;
5958
+
5944
5959
if (!this ->visit (InitExpr))
5945
5960
return false ;
5946
5961
5947
5962
bool BitField = F->isBitField ();
5948
- if (BitField && Activate)
5949
- return this ->emitInitThisBitFieldActivate (*T, F, FieldOffset, InitExpr);
5950
5963
if (BitField)
5951
5964
return this ->emitInitThisBitField (*T, F, FieldOffset, InitExpr);
5952
- if (Activate)
5953
- return this ->emitInitThisFieldActivate (*T, FieldOffset, InitExpr);
5954
5965
return this ->emitInitThisField (*T, FieldOffset, InitExpr);
5955
5966
}
5956
5967
// Non-primitive case. Get a pointer to the field-to-initialize
0 commit comments