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
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 53fe80c..781c64c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3275,10 +3275,11 @@
   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 @@
         // 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 @@
         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 @@
                                    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)