@@ -1015,11 +1015,14 @@ static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
10151015 assert (Desc->isRecord () || Desc->isCompositeArray ());
10161016
10171017 if (Desc->isCompositeArray ()) {
1018+ unsigned N = Desc->getNumElems ();
1019+ if (N == 0 )
1020+ return true ;
10181021 const Descriptor *ElemDesc = Desc->ElemDesc ;
10191022 assert (ElemDesc->isRecord ());
10201023
10211024 Pointer RP (const_cast <Block *>(B));
1022- for (unsigned I = 0 ; I != Desc-> getNumElems (); ++ I) {
1025+ for (int I = static_cast < int >(N) - 1 ; I >= 0 ; -- I) {
10231026 if (!runRecordDestructor (S, OpPC, RP.atIndex (I).narrow (), ElemDesc))
10241027 return false ;
10251028 }
@@ -1238,8 +1241,10 @@ static bool checkConstructor(InterpState &S, CodePtr OpPC, const Function *Func,
12381241 const Pointer &ThisPtr) {
12391242 assert (Func->isConstructor ());
12401243
1241- const Descriptor *D = ThisPtr.getFieldDesc ();
1244+ if (Func->getParentDecl ()->isInvalidDecl ())
1245+ return false ;
12421246
1247+ const Descriptor *D = ThisPtr.getFieldDesc ();
12431248 // FIXME: I think this case is not 100% correct. E.g. a pointer into a
12441249 // subobject of a composite array.
12451250 if (!D->ElemRecord )
@@ -1377,6 +1382,18 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
13771382 size_t ArgSize = Func->getArgSize () + VarArgSize;
13781383 size_t ThisOffset = ArgSize - (Func->hasRVO () ? primSize (PT_Ptr) : 0 );
13791384 Pointer &ThisPtr = S.Stk .peek <Pointer>(ThisOffset);
1385+ const FunctionDecl *Callee = Func->getDecl ();
1386+
1387+ // C++2a [class.abstract]p6:
1388+ // the effect of making a virtual call to a pure virtual function [...] is
1389+ // undefined
1390+ if (Callee->isPureVirtual ()) {
1391+ S.FFDiag (S.Current ->getSource (OpPC), diag::note_constexpr_pure_virtual_call,
1392+ 1 )
1393+ << Callee;
1394+ S.Note (Callee->getLocation (), diag::note_declared_at);
1395+ return false ;
1396+ }
13801397
13811398 const CXXRecordDecl *DynamicDecl = nullptr ;
13821399 {
@@ -1393,7 +1410,7 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func,
13931410 assert (DynamicDecl);
13941411
13951412 const auto *StaticDecl = cast<CXXRecordDecl>(Func->getParentDecl ());
1396- const auto *InitialFunction = cast<CXXMethodDecl>(Func-> getDecl () );
1413+ const auto *InitialFunction = cast<CXXMethodDecl>(Callee );
13971414 const CXXMethodDecl *Overrider = S.getContext ().getOverridingFunction (
13981415 DynamicDecl, StaticDecl, InitialFunction);
13991416
0 commit comments