@@ -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 () &&
@@ -5408,6 +5373,53 @@ bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
5408
5373
return true ;
5409
5374
}
5410
5375
5376
+ static bool hasTrivialDefaultCtorParent (const FieldDecl *FD) {
5377
+ assert (FD);
5378
+ assert (FD->getParent ()->isUnion ());
5379
+ const auto *CXXRD = dyn_cast<CXXRecordDecl>(FD->getParent ());
5380
+ return !CXXRD || CXXRD->hasTrivialDefaultConstructor ();
5381
+ }
5382
+
5383
+ template <class Emitter > bool Compiler<Emitter>::refersToUnion(const Expr *E) {
5384
+ for (;;) {
5385
+ if (const auto *ME = dyn_cast<MemberExpr>(E)) {
5386
+ if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl ());
5387
+ FD && FD->getParent ()->isUnion () && hasTrivialDefaultCtorParent (FD))
5388
+ return true ;
5389
+ E = ME->getBase ();
5390
+ continue ;
5391
+ }
5392
+
5393
+ if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
5394
+ E = ASE->getBase ()->IgnoreImplicit ();
5395
+ continue ;
5396
+ }
5397
+
5398
+ if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E);
5399
+ ICE && (ICE->getCastKind () == CK_NoOp ||
5400
+ ICE->getCastKind () == CK_DerivedToBase ||
5401
+ ICE->getCastKind () == CK_UncheckedDerivedToBase)) {
5402
+ E = ICE->getSubExpr ();
5403
+ continue ;
5404
+ }
5405
+
5406
+ if (const auto *This = dyn_cast<CXXThisExpr>(E)) {
5407
+ const auto *ThisRecord =
5408
+ This->getType ()->getPointeeType ()->getAsRecordDecl ();
5409
+ if (!ThisRecord->isUnion ())
5410
+ return false ;
5411
+ // Otherwise, always activate if we're in the ctor.
5412
+ if (const auto *Ctor =
5413
+ dyn_cast_if_present<CXXConstructorDecl>(CompilingFunction))
5414
+ return Ctor->getParent () == ThisRecord;
5415
+ return false ;
5416
+ }
5417
+
5418
+ break ;
5419
+ }
5420
+ return false ;
5421
+ }
5422
+
5411
5423
template <class Emitter >
5412
5424
bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS,
5413
5425
bool EvaluateConditionDecl) {
@@ -5940,16 +5952,15 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
5940
5952
return false ;
5941
5953
5942
5954
if (OptPrimType T = this ->classify (InitExpr)) {
5955
+ if (Activate && !this ->emitActivateThisField (FieldOffset, InitExpr))
5956
+ return false ;
5957
+
5943
5958
if (!this ->visit (InitExpr))
5944
5959
return false ;
5945
5960
5946
5961
bool BitField = F->isBitField ();
5947
- if (BitField && Activate)
5948
- return this ->emitInitThisBitFieldActivate (*T, F, FieldOffset, InitExpr);
5949
5962
if (BitField)
5950
5963
return this ->emitInitThisBitField (*T, F, FieldOffset, InitExpr);
5951
- if (Activate)
5952
- return this ->emitInitThisFieldActivate (*T, FieldOffset, InitExpr);
5953
5964
return this ->emitInitThisField (*T, FieldOffset, InitExpr);
5954
5965
}
5955
5966
// Non-primitive case. Get a pointer to the field-to-initialize
0 commit comments