diff options
| author | Chris Lattner <sabre@nondot.org> | 2009-04-24 00:30:45 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2009-04-24 00:30:45 +0000 |
| commit | 62975a788e75d85cfc8600184fbbbc521ff74ed0 (patch) | |
| tree | 4c65ecb1eedcdcc92707e48f0ef3b34c438a2d32 /clang/lib | |
| parent | ac345a399078ee22075488092a4d6bfe6d9738b9 (diff) | |
| download | bcm5719-llvm-62975a788e75d85cfc8600184fbbbc521ff74ed0.tar.gz bcm5719-llvm-62975a788e75d85cfc8600184fbbbc521ff74ed0.zip | |
Fix rdar://6821047 - clang crashes on subscript of interface in 64-bit mode
Several changes here:
1. We change Type::isIncompleteType to realize that forward declared
interfaces are incomplete. This eliminate special case code for this
from the sizeof path, and starts us rejecting P[4] when P is a pointer
to an incomplete interface.
2. Explicitly reject P[4] when P points to an interface in non-fragile ABI
mode.
3. Switch the sizeof(interface) diagnostic back to an error instead of a
warning in non-fragile abi mode.
llvm-svn: 69943
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Type.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 45 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 4 |
3 files changed, 30 insertions, 23 deletions
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 7daa20704b2..a94310bbdf3 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -825,6 +825,10 @@ bool Type::isIncompleteType() const { case IncompleteArray: // An array of unknown size is an incomplete type (C99 6.2.5p22). return true; + case ObjCInterface: + case ObjCQualifiedInterface: + // ObjC interfaces are incomplete if they are @class, not @interface. + return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl(); } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 89f834cf5ae..edf769b2fe4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1231,37 +1231,33 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, // C99 6.5.3.4p1: if (isa<FunctionType>(exprType)) { - // alignof(function) is allowed. + // alignof(function) is allowed as an extension. if (isSizeof) Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange; return false; } + // Allow sizeof(void)/alignof(void) as an extension. if (exprType->isVoidType()) { Diag(OpLoc, diag::ext_sizeof_void_type) << (isSizeof ? "sizeof" : "__alignof") << ExprRange; return false; } - // sizeof(interface) and sizeof(interface<proto>) - if (const ObjCInterfaceType *IIT = exprType->getAsObjCInterfaceType()) { - if (IIT->getDecl()->isForwardDecl()) { - Diag(OpLoc, diag::err_sizeof_forward_interface) - << IIT->getDecl()->getDeclName() << isSizeof; - return true; - } - - if (LangOpts.ObjCNonFragileABI) { - Diag(OpLoc, diag::err_sizeof_nonfragile_interface) - << IIT->getDecl()->getDeclName() << isSizeof; - //return false; - } + if (RequireCompleteType(OpLoc, exprType, + isSizeof ? diag::err_sizeof_incomplete_type : + diag::err_alignof_incomplete_type, + ExprRange)) + return true; + + // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode. + if (exprType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) { + Diag(OpLoc, diag::err_sizeof_nonfragile_interface) + << exprType << isSizeof; + return true; } - return RequireCompleteType(OpLoc, exprType, - isSizeof ? diag::err_sizeof_incomplete_type : - diag::err_alignof_incomplete_type, - ExprRange); + return false; } bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, @@ -1651,12 +1647,19 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc, << ResultType << BaseExpr->getSourceRange(); return ExprError(); } + if (!ResultType->isDependentType() && - RequireCompleteType(BaseExpr->getLocStart(), ResultType, - diag::err_subscript_incomplete_type, + RequireCompleteType(LLoc, ResultType, diag::err_subscript_incomplete_type, BaseExpr->getSourceRange())) return ExprError(); - + + // Diagnose bad cases where we step over interface counts. + if (ResultType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) { + Diag(LLoc, diag::err_subscript_nonfragile_interface) + << ResultType << BaseExpr->getSourceRange(); + return ExprError(); + } + Base.release(); Idx.release(); return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 50f5071306c..62d2489b345 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1060,8 +1060,8 @@ void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) { /// @returns @c true if @p T is incomplete and a diagnostic was emitted, /// @c false otherwise. bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag, - SourceRange Range1, SourceRange Range2, - QualType PrintType) { + SourceRange Range1, SourceRange Range2, + QualType PrintType) { // If we have a complete type, we're done. if (!T->isIncompleteType()) return false; |

