From: Daniel Dunbar Date: Tue, 21 Apr 2009 15:48:54 +0000 (+0000) Subject: Use an ASTRecordLayout to compute the sizeof an interface, not X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ff89666e8d143b52f2bb5d2c3a108125d523abb7;p=clang Use an ASTRecordLayout to compute the sizeof an interface, not addRecordToClass. - Among other things, this fixes a crash when applying sizeof to an interface with synthesized ivars, although things still aren't "correct" here. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69675 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 8fd75f1808..b588eab642 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1079,18 +1079,18 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { if (!SrcTy->isConstantSizeType()) return false; + unsigned BitWidth = 0; if (SrcTy->isObjCInterfaceType()) { // Slightly unusual case: the size of an ObjC interface type is the - // size of the class. This code intentionally falls through to the normal - // case. + // size of the class. ObjCInterfaceDecl *OI = SrcTy->getAsObjCInterfaceType()->getDecl(); - RecordDecl *RD = const_cast(Info.Ctx.addRecordToClass(OI)); - SrcTy = Info.Ctx.getTagDeclType(static_cast(RD)); - } + const ASTRecordLayout &Layout = Info.Ctx.getASTObjCInterfaceLayout(OI); + BitWidth = Layout.getSize(); + } else + BitWidth = Info.Ctx.getTypeSize(SrcTy); // Get information about the size. - unsigned CharSize = Info.Ctx.Target.getCharWidth(); - return Success(Info.Ctx.getTypeSize(SrcTy) / CharSize, E); + return Success(BitWidth / Info.Ctx.Target.getCharWidth(), E); } bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m new file mode 100644 index 0000000000..775f5d7f56 --- /dev/null +++ b/test/SemaObjC/sizeof-interface.m @@ -0,0 +1,35 @@ +// RUN: clang-cc -triple x86_64-apple-darwin9 -fsyntax-only %t + +@class I0; +// FIXME: Reject sizeof on incomplete interface; this breaks the test! +//int g0 = sizeof(I0); // exxpected-error{{invalid application of 'sizeof' to an incomplete type ...}} + +@interface I0 { + char x[4]; +} + +@property int p0; +@end + +// size == 4 +int g1[ sizeof(I0) == 4 ? 1 : -1]; + +@implementation I0 +@synthesize p0 = _p0; +@end + +// size == 4 (we do not include extended properties in the +// sizeof). +int g2[ sizeof(I0) == 4 ? 1 : -1]; + +@interface I1 +@property int p0; +@end + +@implementation I1 +@synthesize p0 = _p0; +@end + +// FIXME: This is currently broken due to the way the record layout we +// create is tied to whether we have seen synthesized properties. Ugh. +// int g3[ sizeof(I1) == 0 ? 1 : -1];