Skip to content

Commit 7cb63ce

Browse files
committed
[clang][bytecode] Start implementing __builtin_{,dynamic}_object_size
1 parent cc7fc99 commit 7cb63ce

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

clang/lib/AST/ByteCode/Descriptor.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ struct Descriptor final {
265265
bool isUnknownSizeArray() const { return Size == UnknownSizeMark; }
266266

267267
/// Checks if the descriptor is of a primitive.
268-
bool isPrimitive() const { return !IsArray && !ElemRecord && !IsDummy; }
268+
bool isPrimitive() const { return !IsArray && !ElemRecord && PrimT; }
269269

270270
/// Checks if the descriptor is of an array.
271271
bool isArray() const { return IsArray; }

clang/lib/AST/ByteCode/InterpBuiltin.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -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+
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+
21822228
bool 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)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=both,expected %s
2+
// RUN: %clang_cc1 -verify=both,ref %s
3+
4+
// both-no-diagnostics
5+
6+
int a;
7+
static_assert(__builtin_object_size(&a, 0) == sizeof(int), "");
8+
float f;
9+
static_assert(__builtin_object_size(&f, 0) == sizeof(float), "");
10+
int arr[2];
11+
static_assert(__builtin_object_size(&arr, 0) == (sizeof(int)*2), "");
12+
13+
float arrf[2];
14+
static_assert(__builtin_object_size(&arrf, 0) == (sizeof(float)*2), "");

0 commit comments

Comments
 (0)