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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69943 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 89f834c..edf769b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1231,37 +1231,33 @@
// 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 @@
<< 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,