aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-04-21 15:48:54 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-04-21 15:48:54 +0000
commitff89666e8d143b52f2bb5d2c3a108125d523abb7 (patch)
treef9d621e9391f09708dc58b1dde4f764ccf40b34c
parent30833f8d77c08f8f16371776fde85a9fde3d9b6e (diff)
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
-rw-r--r--lib/AST/ExprConstant.cpp14
-rw-r--r--test/SemaObjC/sizeof-interface.m35
2 files changed, 42 insertions, 7 deletions
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<RecordDecl*>(Info.Ctx.addRecordToClass(OI));
- SrcTy = Info.Ctx.getTagDeclType(static_cast<TagDecl*>(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];