@@ -445,7 +445,8 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
445
445
return true ;
446
446
}
447
447
448
- bool CheckConstant (InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
448
+ bool CheckConstant (InterpState &S, CodePtr OpPC, const Descriptor *Desc,
449
+ bool NoDiag) {
449
450
assert (Desc);
450
451
451
452
const auto *D = Desc->asVarDecl ();
@@ -470,15 +471,15 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
470
471
}
471
472
472
473
if (IsConstant) {
473
- if (S.getLangOpts ().CPlusPlus ) {
474
+ if (S.getLangOpts ().CPlusPlus && !NoDiag ) {
474
475
S.CCEDiag (S.Current ->getLocation (OpPC),
475
476
S.getLangOpts ().CPlusPlus11
476
477
? diag::note_constexpr_ltor_non_constexpr
477
478
: diag::note_constexpr_ltor_non_integral,
478
479
1 )
479
480
<< D << T;
480
481
S.Note (D->getLocation (), diag::note_declared_at);
481
- } else {
482
+ } else if (!NoDiag) {
482
483
S.CCEDiag (S.Current ->getLocation (OpPC));
483
484
}
484
485
return true ;
@@ -493,16 +494,18 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
493
494
return true ;
494
495
}
495
496
496
- diagnoseNonConstVariable (S, OpPC, D);
497
+ if (!NoDiag)
498
+ diagnoseNonConstVariable (S, OpPC, D);
497
499
return false ;
498
500
}
499
501
500
- static bool CheckConstant (InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
502
+ static bool CheckConstant (InterpState &S, CodePtr OpPC, const Pointer &Ptr,
503
+ bool NoDiag = false ) {
501
504
if (!Ptr.isStatic () || !Ptr.isBlockPointer ())
502
505
return true ;
503
506
if (!Ptr.getDeclID ())
504
507
return true ;
505
- return CheckConstant (S, OpPC, Ptr.getDeclDesc ());
508
+ return CheckConstant (S, OpPC, Ptr.getDeclDesc (), NoDiag );
506
509
}
507
510
508
511
bool CheckNull (InterpState &S, CodePtr OpPC, const Pointer &Ptr,
@@ -1636,6 +1639,33 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
1636
1639
return true ;
1637
1640
}
1638
1641
1642
+ static bool GetDynamicDecl (InterpState &S, CodePtr OpPC, Pointer TypePtr,
1643
+ const CXXRecordDecl *&DynamicDecl) {
1644
+ while (TypePtr.isBaseClass ())
1645
+ TypePtr = TypePtr.getBase ();
1646
+
1647
+ QualType DynamicType = TypePtr.getType ();
1648
+ if (DynamicType->isPointerType () || DynamicType->isReferenceType ()) {
1649
+ DynamicDecl = DynamicType->getPointeeCXXRecordDecl ();
1650
+ } else if (DynamicType->isArrayType ()) {
1651
+ const Type *ElemType = DynamicType->getPointeeOrArrayElementType ();
1652
+ assert (ElemType);
1653
+ DynamicDecl = ElemType->getAsCXXRecordDecl ();
1654
+ } else {
1655
+ DynamicDecl = DynamicType->getAsCXXRecordDecl ();
1656
+ }
1657
+
1658
+ if (!CheckConstant (S, OpPC, TypePtr, true )) {
1659
+ const Expr *E = S.Current ->getExpr (OpPC);
1660
+ APValue V = TypePtr.toAPValue (S.getASTContext ());
1661
+ QualType TT = S.getASTContext ().getLValueReferenceType (DynamicType);
1662
+ S.FFDiag (E, diag::note_constexpr_polymorphic_unknown_dynamic_type)
1663
+ << AccessKinds::AK_MemberCall << V.getAsString (S.getASTContext (), TT);
1664
+ return false ;
1665
+ }
1666
+ return true ;
1667
+ }
1668
+
1639
1669
bool CallVirt (InterpState &S, CodePtr OpPC, const Function *Func,
1640
1670
uint32_t VarArgSize) {
1641
1671
assert (Func->hasThisPointer ());
@@ -1660,22 +1690,8 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
1660
1690
}
1661
1691
1662
1692
const CXXRecordDecl *DynamicDecl = nullptr ;
1663
- {
1664
- Pointer TypePtr = ThisPtr;
1665
- while (TypePtr.isBaseClass ())
1666
- TypePtr = TypePtr.getBase ();
1667
-
1668
- QualType DynamicType = TypePtr.getType ();
1669
- if (DynamicType->isPointerType () || DynamicType->isReferenceType ()) {
1670
- DynamicDecl = DynamicType->getPointeeCXXRecordDecl ();
1671
- } else if (DynamicType->isArrayType ()) {
1672
- const Type *ElemType = DynamicType->getPointeeOrArrayElementType ();
1673
- assert (ElemType);
1674
- DynamicDecl = ElemType->getAsCXXRecordDecl ();
1675
- } else {
1676
- DynamicDecl = DynamicType->getAsCXXRecordDecl ();
1677
- }
1678
- }
1693
+ if (!GetDynamicDecl (S, OpPC, ThisPtr, DynamicDecl))
1694
+ return false ;
1679
1695
assert (DynamicDecl);
1680
1696
1681
1697
const auto *StaticDecl = cast<CXXRecordDecl>(Func->getParentDecl ());
0 commit comments