]> granicus.if.org Git - clang/commitdiff
reject explicit pointer arithmetic on interface pointers in 64-bit objc ABI
authorChris Lattner <sabre@nondot.org>
Fri, 24 Apr 2009 23:50:08 +0000 (23:50 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 24 Apr 2009 23:50:08 +0000 (23:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70004 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/SemaObjC/sizeof-interface.m

index a5aa6bdb84b02e54e4c88e759d286e6edc00b1d7..071fcab437abcf0762d2ef99f87c69cb0cc238f5 100644 (file)
@@ -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<
index 53fe80cb72a1c8e9c013565cd66e6bb5799885da..781c64c22c2314ef18d961fa961c3ac24db83744 100644 (file)
@@ -3275,10 +3275,11 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
   if (IExp->getType()->isPointerType())
     std::swap(PExp, IExp);
 
-  if (const PointerTypePTy = 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)
index a1d722b74294d74c632ca872999c88972ed8d1ab..75d7daafbbcc278cb8f7dbfc882361ccc51e0f7e 100644 (file)
@@ -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}}
 }