@@ -1154,6 +1154,53 @@ bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T) {
11541154 return false ;
11551155}
11561156
1157+ static bool getField (InterpState &S, CodePtr OpPC, const Pointer &Ptr,
1158+ uint32_t Off) {
1159+ if (S.getLangOpts ().CPlusPlus && S.inConstantContext () &&
1160+ !CheckNull (S, OpPC, Ptr, CSK_Field))
1161+ return false ;
1162+
1163+ if (!CheckExtern (S, OpPC, Ptr))
1164+ return false ;
1165+ if (!CheckRange (S, OpPC, Ptr, CSK_Field))
1166+ return false ;
1167+ if (!CheckArray (S, OpPC, Ptr))
1168+ return false ;
1169+ if (!CheckSubobject (S, OpPC, Ptr, CSK_Field))
1170+ return false ;
1171+
1172+ if (Ptr.isIntegralPointer ()) {
1173+ S.Stk .push <Pointer>(Ptr.asIntPointer ().atOffset (S.getASTContext (), Off));
1174+ return true ;
1175+ }
1176+
1177+ if (!Ptr.isBlockPointer ()) {
1178+ // FIXME: The only time we (seem to) get here is when trying to access a
1179+ // field of a typeid pointer. In that case, we're supposed to diagnose e.g.
1180+ // `typeid(int).name`, but we currently diagnose `&typeid(int)`.
1181+ S.FFDiag (S.Current ->getSource (OpPC),
1182+ diag::note_constexpr_access_unreadable_object)
1183+ << AK_Read << Ptr.toDiagnosticString (S.getASTContext ());
1184+ return false ;
1185+ }
1186+
1187+ if (Off > Ptr.block ()->getSize ())
1188+ return false ;
1189+
1190+ S.Stk .push <Pointer>(Ptr.atField (Off));
1191+ return true ;
1192+ }
1193+
1194+ bool GetPtrField (InterpState &S, CodePtr OpPC, uint32_t Off) {
1195+ const auto &Ptr = S.Stk .peek <Pointer>();
1196+ return getField (S, OpPC, Ptr, Off);
1197+ }
1198+
1199+ bool GetPtrFieldPop (InterpState &S, CodePtr OpPC, uint32_t Off) {
1200+ const auto &Ptr = S.Stk .pop <Pointer>();
1201+ return getField (S, OpPC, Ptr, Off);
1202+ }
1203+
11571204static bool checkConstructor (InterpState &S, CodePtr OpPC, const Function *Func,
11581205 const Pointer &ThisPtr) {
11591206 assert (Func->isConstructor ());
@@ -1595,6 +1642,41 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits,
15951642 return false ;
15961643}
15971644
1645+ bool GetTypeid (InterpState &S, CodePtr OpPC, const Type *TypePtr,
1646+ const Type *TypeInfoType) {
1647+ S.Stk .push <Pointer>(TypePtr, TypeInfoType);
1648+ return true ;
1649+ }
1650+
1651+ bool GetTypeidPtr (InterpState &S, CodePtr OpPC, const Type *TypeInfoType) {
1652+ const auto &P = S.Stk .pop <Pointer>();
1653+
1654+ if (!P.isBlockPointer ())
1655+ return false ;
1656+
1657+ if (P.isDummy ()) {
1658+ QualType StarThisType =
1659+ S.getASTContext ().getLValueReferenceType (P.getType ());
1660+ S.FFDiag (S.Current ->getSource (OpPC),
1661+ diag::note_constexpr_polymorphic_unknown_dynamic_type)
1662+ << AK_TypeId
1663+ << P.toAPValue (S.getASTContext ())
1664+ .getAsString (S.getASTContext (), StarThisType);
1665+ return false ;
1666+ }
1667+
1668+ S.Stk .push <Pointer>(P.getType ().getTypePtr (), TypeInfoType);
1669+ return true ;
1670+ }
1671+
1672+ bool DiagTypeid (InterpState &S, CodePtr OpPC) {
1673+ const auto *E = cast<CXXTypeidExpr>(S.Current ->getExpr (OpPC));
1674+ S.CCEDiag (E, diag::note_constexpr_typeid_polymorphic)
1675+ << E->getExprOperand ()->getType ()
1676+ << E->getExprOperand ()->getSourceRange ();
1677+ return false ;
1678+ }
1679+
15981680// https://github.com/llvm/llvm-project/issues/102513
15991681#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
16001682#pragma optimize("", off)
0 commit comments