summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-24 00:30:45 +0000
committerChris Lattner <sabre@nondot.org>2009-04-24 00:30:45 +0000
commit62975a788e75d85cfc8600184fbbbc521ff74ed0 (patch)
tree4c65ecb1eedcdcc92707e48f0ef3b34c438a2d32 /clang/lib
parentac345a399078ee22075488092a4d6bfe6d9738b9 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp45
-rw-r--r--clang/lib/Sema/SemaType.cpp4
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;
OpenPOWER on IntegriCloud