aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-04-24 23:50:08 +0000
committerChris Lattner <sabre@nondot.org>2009-04-24 23:50:08 +0000
commitb5f1562d7b57a3dbe27a39b45995f59862973820 (patch)
tree8ea7e145c317f21123d49f631527d6f81edf4205
parentad38a8595f2458309de3a8e30d0d3d62566b984f (diff)
reject explicit pointer arithmetic on interface pointers in 64-bit objc ABI
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70004 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td22
-rw-r--r--lib/Sema/SemaExpr.cpp29
-rw-r--r--test/SemaObjC/sizeof-interface.m6
3 files changed, 42 insertions, 15 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index a5aa6bdb84..071fcab437 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -917,11 +917,6 @@ def ext_sizeof_function_type : Extension<
"invalid application of 'sizeof' to a function type">;
def ext_sizeof_void_type : Extension<
"invalid application of '%0' to a void type">;
-def err_sizeof_nonfragile_interface : Error<
- "invalid application of '%select{alignof|sizeof}1' to interface %0 in "
- "non-fragile ABI">;
-def err_atdef_nonfragile_interface : Error<
- "invalid application of @defs in non-fragile ABI">;
// FIXME: merge with %select
def err_sizeof_incomplete_type : Error<
"invalid application of 'sizeof' to an incomplete type %0">;
@@ -938,6 +933,20 @@ def warn_floatingpoint_eq : Warning<
"comparing floating point with == or != is unsafe">,
InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
+def err_sizeof_nonfragile_interface : Error<
+ "invalid application of '%select{alignof|sizeof}1' to interface %0 in "
+ "non-fragile ABI">;
+def err_atdef_nonfragile_interface : Error<
+ "invalid application of @defs in non-fragile ABI">;
+def err_subscript_nonfragile_interface : Error<
+ "subscript requires size of interface %0, which is not constant in "
+ "non-fragile ABI">;
+
+def err_arithmetic_nonfragile_interface : Error<
+ "arithmetic on pointer to interface %0, which is not a constant size in "
+ "non-fragile ABI">;
+
+
def err_typecheck_subscript_value : Error<
"subscripted value is neither array nor pointer">;
def err_typecheck_subscript : Error<"array subscript is not an integer">;
@@ -945,9 +954,6 @@ def err_subscript_function_type : Error<
"subscript of pointer to function type %0">;
def err_subscript_incomplete_type : Error<
"subscript of pointer to incomplete type %0">;
-def err_subscript_nonfragile_interface : Error<
- "subscript requires size of interface %0, which is not constant in "
- "non-fragile ABI">;
def err_typecheck_member_reference_struct_union : Error<
"member reference base type %0 is not a structure or union">;
def err_typecheck_member_reference_ivar : Error<
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 53fe80cb72..781c64c22c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3275,10 +3275,11 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
if (IExp->getType()->isPointerType())
std::swap(PExp, IExp);
- if (const PointerType* PTy = PExp->getType()->getAsPointerType()) {
+ if (const PointerType *PTy = PExp->getType()->getAsPointerType()) {
if (IExp->getType()->isIntegerType()) {
- // Check for arithmetic on pointers to incomplete types
- if (PTy->getPointeeType()->isVoidType()) {
+ QualType PointeeTy = PTy->getPointeeType();
+ // Check for arithmetic on pointers to incomplete types.
+ if (PointeeTy->isVoidType()) {
if (getLangOptions().CPlusPlus) {
Diag(Loc, diag::err_typecheck_pointer_arith_void_type)
<< lex->getSourceRange() << rex->getSourceRange();
@@ -3288,7 +3289,7 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
// GNU extension: arithmetic on pointer to void
Diag(Loc, diag::ext_gnu_void_ptr)
<< lex->getSourceRange() << rex->getSourceRange();
- } else if (PTy->getPointeeType()->isFunctionType()) {
+ } else if (PointeeTy->isFunctionType()) {
if (getLangOptions().CPlusPlus) {
Diag(Loc, diag::err_typecheck_pointer_arith_function_type)
<< lex->getType() << lex->getSourceRange();
@@ -3299,12 +3300,19 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
Diag(Loc, diag::ext_gnu_ptr_func_arith)
<< lex->getType() << lex->getSourceRange();
} else if (!PTy->isDependentType() &&
- RequireCompleteType(Loc, PTy->getPointeeType(),
+ RequireCompleteType(Loc, PointeeTy,
diag::err_typecheck_arithmetic_incomplete_type,
- lex->getSourceRange(), SourceRange(),
- lex->getType()))
+ PExp->getSourceRange(), SourceRange(),
+ PExp->getType()))
return QualType();
+ // Diagnose bad cases where we step over interface counts.
+ if (PointeeTy->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+ Diag(Loc, diag::err_arithmetic_nonfragile_interface)
+ << PointeeTy << PExp->getSourceRange();
+ return QualType();
+ }
+
if (CompLHSTy) {
QualType LHSTy = lex->getType();
if (LHSTy->isPromotableIntegerType())
@@ -3371,6 +3379,13 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
lex->getType()))
return QualType();
+ // Diagnose bad cases where we step over interface counts.
+ if (lpointee->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+ Diag(Loc, diag::err_arithmetic_nonfragile_interface)
+ << lpointee << lex->getSourceRange();
+ return QualType();
+ }
+
// The result type of a pointer-int computation is the pointer type.
if (rex->getType()->isIntegerType()) {
if (ComplainAboutVoid)
diff --git a/test/SemaObjC/sizeof-interface.m b/test/SemaObjC/sizeof-interface.m
index a1d722b742..75d7daafbb 100644
--- a/test/SemaObjC/sizeof-interface.m
+++ b/test/SemaObjC/sizeof-interface.m
@@ -7,6 +7,8 @@ int g0 = sizeof(I0); // expected-error{{invalid application of 'sizeof' to an in
// rdar://6821047
void *g3(I0 *P) {
+ P = P+5; // expected-error {{arithmetic on pointer to incomplete type 'I0 *'}}
+
return &P[4]; // expected-error{{subscript of pointer to incomplete type 'I0'}}
}
@@ -49,6 +51,10 @@ typedef struct { @defs(I1) } I1_defs; // expected-error {{invalid application of
// rdar://6821047
int bar(I0 *P) {
+ P = P+5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
+ P = 5+P; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
+ P = P-5; // expected-error {{arithmetic on pointer to interface 'I0', which is not a constant size in non-fragile ABI}}
+
return P[4].x[2]; // expected-error {{subscript requires size of interface 'I0', which is not constant in non-fragile ABI}}
}