@@ -2179,6 +2179,52 @@ static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC,
21792179 return true ;
21802180}
21812181
2182+ static unsigned computeFullDescSize (const ASTContext &ASTCtx,
2183+ const Descriptor *Desc) {
2184+
2185+ if (Desc->isPrimitive ())
2186+ return ASTCtx.getTypeSizeInChars (Desc->getType ()).getQuantity ();
2187+
2188+ if (Desc->isArray ())
2189+ return ASTCtx.getTypeSizeInChars (Desc->getElemQualType ()).getQuantity () *
2190+ Desc->getNumElems ();
2191+
2192+ if (Desc->isRecord ())
2193+ return ASTCtx.getTypeSizeInChars (Desc->getType ()).getQuantity ();
2194+
2195+ llvm_unreachable (" Unhandled descriptor type" );
2196+ return 0 ;
2197+ }
2198+
2199+ static bool interp__builtin_object_size (InterpState &S, CodePtr OpPC,
2200+ const InterpFrame *Frame,
2201+ const Function *Func,
2202+ const CallExpr *Call) {
2203+ PrimType KindT = *S.getContext ().classify (Call->getArg (1 ));
2204+ [[maybe_unused]] unsigned Kind = peekToAPSInt (S.Stk , KindT).getZExtValue ();
2205+
2206+ assert (Kind <= 3 && " unexpected kind" );
2207+
2208+ const Pointer &Ptr =
2209+ S.Stk .peek <Pointer>(align (primSize (KindT)) + align (primSize (PT_Ptr)));
2210+
2211+ if (Ptr.isZero ())
2212+ return false ;
2213+
2214+ const Descriptor *DeclDesc = Ptr.getDeclDesc ();
2215+ if (!DeclDesc)
2216+ return false ;
2217+
2218+ const ASTContext &ASTCtx = S.getASTContext ();
2219+
2220+ unsigned ByteOffset = 0 ;
2221+ unsigned FullSize = computeFullDescSize (ASTCtx, DeclDesc);
2222+
2223+ pushInteger (S, FullSize - ByteOffset, Call->getType ());
2224+
2225+ return true ;
2226+ }
2227+
21822228bool InterpretBuiltin (InterpState &S, CodePtr OpPC, const Function *F,
21832229 const CallExpr *Call, uint32_t BuiltinID) {
21842230 if (!S.getASTContext ().BuiltinInfo .isConstantEvaluated (BuiltinID))
@@ -2681,6 +2727,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
26812727 return false ;
26822728 break ;
26832729
2730+ case Builtin::BI__builtin_object_size:
2731+ case Builtin::BI__builtin_dynamic_object_size:
2732+ if (!interp__builtin_object_size (S, OpPC, Frame, F, Call))
2733+ return false ;
2734+ break ;
2735+
26842736 default :
26852737 S.FFDiag (S.Current ->getLocation (OpPC),
26862738 diag::note_invalid_subexpr_in_const_expr)
0 commit comments