r180833 - Point diagnostics that complain about a use of a selector in an objc message, to the selector location.

Argyrios Kyrtzidis akyrtzi at gmail.com
Tue Apr 30 17:24:09 PDT 2013


Author: akirtzidis
Date: Tue Apr 30 19:24:09 2013
New Revision: 180833

URL: http://llvm.org/viewvc/llvm-project?rev=180833&view=rev
Log:
Point diagnostics that complain about a use of a selector in an objc message, to the selector location.

Previously it would point to the left bracket or the receiver, which can be particularly
problematic if the receiver is a block literal and we end up point the diagnostic far away
for the selector that is complaining about.

rdar://13620447

Modified:
    cfe/trunk/lib/ARCMigrate/TransAPIUses.cpp
    cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/ARCMT/check-with-serialized-diag.m
    cfe/trunk/test/ARCMT/migrate-plist-output.m
    cfe/trunk/test/SemaObjC/message.m
    cfe/trunk/test/SemaObjC/warn-missing-super.m

Modified: cfe/trunk/lib/ARCMigrate/TransAPIUses.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransAPIUses.cpp?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransAPIUses.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransAPIUses.cpp Tue Apr 30 19:24:09 2013
@@ -91,12 +91,12 @@ public:
         E->getSelector() == zoneSel &&
         Pass.TA.hasDiagnostic(diag::err_unavailable,
                               diag::err_unavailable_message,
-                              E->getInstanceReceiver()->getExprLoc())) {
+                              E->getSelectorLoc(0))) {
       // Calling -zone is meaningless in ARC, change it to nil.
       Transaction Trans(Pass.TA);
       Pass.TA.clearDiagnostic(diag::err_unavailable,
                               diag::err_unavailable_message,
-                              E->getInstanceReceiver()->getExprLoc());
+                              E->getSelectorLoc(0));
       Pass.TA.replace(E->getSourceRange(), getNilString(Pass.Ctx));
     }
     return true;

Modified: cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp Tue Apr 30 19:24:09 2013
@@ -118,7 +118,7 @@ public:
       return true;
     case ObjCMessageExpr::SuperInstance: {
       Transaction Trans(Pass.TA);
-      clearDiagnostics(E->getSuperLoc());
+      clearDiagnostics(E->getSelectorLoc(0));
       if (tryRemoving(E))
         return true;
       Pass.TA.replace(E->getSourceRange(), "self");
@@ -132,7 +132,7 @@ public:
     if (!rec) return true;
 
     Transaction Trans(Pass.TA);
-    clearDiagnostics(rec->getExprLoc());
+    clearDiagnostics(E->getSelectorLoc(0));
 
     ObjCMessageExpr *Msg = E;
     Expr *RecContainer = Msg;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Apr 30 19:24:09 2013
@@ -1191,6 +1191,12 @@ bool Sema::CheckMessageArgumentTypes(Qua
                                      bool isClassMessage, bool isSuperMessage,
                                      SourceLocation lbrac, SourceLocation rbrac,
                                      QualType &ReturnType, ExprValueKind &VK) {
+  SourceLocation SelLoc;
+  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+    SelLoc = SelectorLocs.front();
+  else
+    SelLoc = lbrac;
+
   if (!Method) {
     // Apply default argument promotion as for (C99 6.5.2.2p6).
     for (unsigned i = 0; i != NumArgs; i++) {
@@ -1200,7 +1206,7 @@ bool Sema::CheckMessageArgumentTypes(Qua
       ExprResult result;
       if (getLangOpts().DebuggerSupport) {
         QualType paramTy; // ignored
-        result = checkUnknownAnyArg(lbrac, Args[i], paramTy);
+        result = checkUnknownAnyArg(SelLoc, Args[i], paramTy);
       } else {
         result = DefaultArgumentPromotion(Args[i]);
       }
@@ -1216,7 +1222,7 @@ bool Sema::CheckMessageArgumentTypes(Qua
       DiagID = isClassMessage ? diag::warn_class_method_not_found
                               : diag::warn_inst_method_not_found;
     if (!getLangOpts().DebuggerSupport)
-      Diag(lbrac, DiagID)
+      Diag(SelLoc, DiagID)
         << Sel << isClassMessage << SourceRange(SelectorLocs.front(), 
                                                 SelectorLocs.back());
 
@@ -1242,7 +1248,7 @@ bool Sema::CheckMessageArgumentTypes(Qua
     NumNamedArgs = Method->param_size();
   // FIXME. This need be cleaned up.
   if (NumArgs < NumNamedArgs) {
-    Diag(lbrac, diag::err_typecheck_call_too_few_args)
+    Diag(SelLoc, diag::err_typecheck_call_too_few_args)
       << 2 << NumNamedArgs << NumArgs;
     return false;
   }
@@ -1268,7 +1274,7 @@ bool Sema::CheckMessageArgumentTypes(Qua
     // from the argument.
     if (param->getType() == Context.UnknownAnyTy) {
       QualType paramType;
-      ExprResult argE = checkUnknownAnyArg(lbrac, argExpr, paramType);
+      ExprResult argE = checkUnknownAnyArg(SelLoc, argExpr, paramType);
       if (argE.isInvalid()) {
         IsError = true;
       } else {
@@ -1287,7 +1293,7 @@ bool Sema::CheckMessageArgumentTypes(Qua
 
     InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                       param);
-    ExprResult ArgE = PerformCopyInitialization(Entity, lbrac, Owned(argExpr));
+    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, Owned(argExpr));
     if (ArgE.isInvalid())
       IsError = true;
     else
@@ -1317,10 +1323,10 @@ bool Sema::CheckMessageArgumentTypes(Qua
     }
   }
 
-  DiagnoseSentinelCalls(Method, lbrac, Args, NumArgs);
+  DiagnoseSentinelCalls(Method, SelLoc, Args, NumArgs);
 
   // Do additional checkings on method.
-  IsError |= CheckObjCMethodCall(Method, lbrac, Args, NumArgs);
+  IsError |= CheckObjCMethodCall(Method, SelLoc, Args, NumArgs);
 
   return IsError;
 }
@@ -1993,7 +1999,12 @@ ExprResult Sema::BuildClassMessage(TypeS
       << FixItHint::CreateInsertion(Loc, "[");
     LBracLoc = Loc;
   }
-  
+  SourceLocation SelLoc;
+  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+    SelLoc = SelectorLocs.front();
+  else
+    SelLoc = Loc;
+
   if (ReceiverType->isDependentType()) {
     // If the receiver type is dependent, we can't type-check anything
     // at this point. Build a dependent expression.
@@ -2018,7 +2029,7 @@ ExprResult Sema::BuildClassMessage(TypeS
   assert(Class && "We don't know which class we're messaging?");
   // objc++ diagnoses during typename annotation.
   if (!getLangOpts().CPlusPlus)
-    (void)DiagnoseUseOfDecl(Class, Loc);
+    (void)DiagnoseUseOfDecl(Class, SelLoc);
   // Find the method we are messaging.
   if (!Method) {
     SourceRange TypeRange 
@@ -2043,7 +2054,7 @@ ExprResult Sema::BuildClassMessage(TypeS
     if (!Method)
       Method = Class->lookupPrivateClassMethod(Sel);
 
-    if (Method && DiagnoseUseOfDecl(Method, Loc))
+    if (Method && DiagnoseUseOfDecl(Method, SelLoc))
       return ExprError();
   }
 
@@ -2159,7 +2170,14 @@ ExprResult Sema::BuildInstanceMessage(Ex
                                       bool isImplicit) {
   // The location of the receiver.
   SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart();
-  
+  SourceRange RecRange =
+      SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
+  SourceLocation SelLoc;
+  if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+    SelLoc = SelectorLocs.front();
+  else
+    SelLoc = Loc;
+
   if (LBracLoc.isInvalid()) {
     Diag(Loc, diag::err_missing_open_square_message_send)
       << FixItHint::CreateInsertion(Loc, "[");
@@ -2264,7 +2282,7 @@ ExprResult Sema::BuildInstanceMessage(Ex
           Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
           // warn if instance method found for a Class message.
           if (Method) {
-            Diag(Loc, diag::warn_instance_method_on_class_found)
+            Diag(SelLoc, diag::warn_instance_method_on_class_found)
               << Method->getSelector() << Sel;
             Diag(Method->getLocation(), diag::note_method_declared_at)
               << Method->getDeclName();
@@ -2279,7 +2297,7 @@ ExprResult Sema::BuildInstanceMessage(Ex
             if (!Method)
               Method = ClassDecl->lookupPrivateClassMethod(Sel);
           }
-          if (Method && DiagnoseUseOfDecl(Method, Loc))
+          if (Method && DiagnoseUseOfDecl(Method, SelLoc))
             return ExprError();
         }
         if (!Method) {
@@ -2298,7 +2316,7 @@ ExprResult Sema::BuildInstanceMessage(Ex
                   if (const ObjCInterfaceDecl *ID =
                       dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
                     if (ID->getSuperClass())
-                      Diag(Loc, diag::warn_root_inst_method_not_found)
+                      Diag(SelLoc, diag::warn_root_inst_method_not_found)
                       << Sel << SourceRange(LBracLoc, RBracLoc);
                   }
             }
@@ -2317,7 +2335,7 @@ ExprResult Sema::BuildInstanceMessage(Ex
         Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
         if (!Method)
           Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
-        if (Method && DiagnoseUseOfDecl(Method, Loc))
+        if (Method && DiagnoseUseOfDecl(Method, SelLoc))
           return ExprError();
       } else if (const ObjCObjectPointerType *OCIType
                    = ReceiverType->getAsObjCInterfacePointerType()) {
@@ -2353,8 +2371,8 @@ ExprResult Sema::BuildInstanceMessage(Ex
           Method = ClassDecl->lookupPrivateMethod(Sel);
 
           if (!Method && getLangOpts().ObjCAutoRefCount) {
-            Diag(Loc, diag::err_arc_may_not_respond)
-              << OCIType->getPointeeType() << Sel 
+            Diag(SelLoc, diag::err_arc_may_not_respond)
+              << OCIType->getPointeeType() << Sel << RecRange
               << SourceRange(SelectorLocs.front(), SelectorLocs.back());
             return ExprError();
           }
@@ -2367,12 +2385,13 @@ ExprResult Sema::BuildInstanceMessage(Ex
               Method = LookupInstanceMethodInGlobalPool(Sel,
                                               SourceRange(LBracLoc, RBracLoc));
               if (Method && !forwardClass)
-                Diag(Loc, diag::warn_maynot_respond)
-                  << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
+                Diag(SelLoc, diag::warn_maynot_respond)
+                  << OCIType->getInterfaceDecl()->getIdentifier()
+                  << Sel << RecRange;
             }
           }
         }
-        if (Method && DiagnoseUseOfDecl(Method, Loc, forwardClass))
+        if (Method && DiagnoseUseOfDecl(Method, SelLoc, forwardClass))
           return ExprError();
       } else {
         // Reject other random receiver types (e.g. structs).
@@ -2401,8 +2420,6 @@ ExprResult Sema::BuildInstanceMessage(Ex
                           diag::err_illegal_message_expr_incomplete_type))
     return ExprError();
 
-  SourceLocation SelLoc = SelectorLocs.front();
-
   // In ARC, forbid the user from sending messages to 
   // retain/release/autorelease/dealloc/retainCount explicitly.
   if (getLangOpts().ObjCAutoRefCount) {
@@ -2427,8 +2444,8 @@ ExprResult Sema::BuildInstanceMessage(Ex
     case OMF_release:
     case OMF_autorelease:
     case OMF_retainCount:
-      Diag(Loc, diag::err_arc_illegal_explicit_message)
-        << Sel << SelLoc;
+      Diag(SelLoc, diag::err_arc_illegal_explicit_message)
+        << Sel << RecRange;
       break;
     
     case OMF_performSelector:

Modified: cfe/trunk/test/ARCMT/check-with-serialized-diag.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/check-with-serialized-diag.m?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/check-with-serialized-diag.m (original)
+++ cfe/trunk/test/ARCMT/check-with-serialized-diag.m Tue Apr 30 19:24:09 2013
@@ -43,13 +43,13 @@ void test1(A *a, struct UnsafeS *unsafeS
 // CHECK-NEXT: Number FIXITs = 0
 // CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: [rewriter] it is not safe to remove 'retain' message on a global variable
 // CHECK-NEXT: Number FIXITs = 0
-// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:4: error: ARC forbids explicit message send of 'retain'
-// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:23 {{.*}}check-with-serialized-diag.m:32:29
+// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:23: error: ARC forbids explicit message send of 'retain'
+// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:4 {{.*}}check-with-serialized-diag.m:32:22
 // CHECK-NEXT: Number FIXITs = 0
-// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: ARC forbids explicit message send of 'retain'
-// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:15 {{.*}}check-with-serialized-diag.m:34:21
+// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:15: error: ARC forbids explicit message send of 'retain'
+// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:4 {{.*}}check-with-serialized-diag.m:34:14
 // CHECK-NEXT: Number FIXITs = 0
-// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:4: error: ARC forbids explicit message send of 'retainCount'
-// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:6 {{.*}}check-with-serialized-diag.m:35:17
+// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:6: error: ARC forbids explicit message send of 'retainCount'
+// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:4 {{.*}}check-with-serialized-diag.m:35:5
 // CHECK-NEXT: Number FIXITs = 0
 

Modified: cfe/trunk/test/ARCMT/migrate-plist-output.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/migrate-plist-output.m?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/migrate-plist-output.m (original)
+++ cfe/trunk/test/ARCMT/migrate-plist-output.m Tue Apr 30 19:24:09 2013
@@ -26,7 +26,7 @@ void test(id p) {
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
 // CHECK:    <key>line</key><integer>10</integer>
-// CHECK:    <key>col</key><integer>4</integer>
+// CHECK:    <key>col</key><integer>6</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
 // CHECK:    <key>ranges</key>
@@ -34,12 +34,12 @@ void test(id p) {
 // CHECK:     <array>
 // CHECK:      <dict>
 // CHECK:       <key>line</key><integer>10</integer>
-// CHECK:       <key>col</key><integer>6</integer>
+// CHECK:       <key>col</key><integer>4</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
 // CHECK:      <dict>
 // CHECK:       <key>line</key><integer>10</integer>
-// CHECK:       <key>col</key><integer>12</integer>
+// CHECK:       <key>col</key><integer>4</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
 // CHECK:     </array>

Modified: cfe/trunk/test/SemaObjC/message.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/message.m?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/message.m (original)
+++ cfe/trunk/test/SemaObjC/message.m Tue Apr 30 19:24:09 2013
@@ -106,3 +106,15 @@ void foo5(id p) {
                  // expected-note {{to match this '['}} \
                  // expected-warning {{instance method '-bar' not found}}
 }
+
+ at interface I1
+-(void)unavail_meth  __attribute__((unavailable)); // expected-note {{marked unavailable here}}
+ at end
+
+// rdar://13620447
+void foo6(I1 *p) {
+  [p
+    bar]; // expected-warning {{instance method '-bar' not found}}
+  [p
+    unavail_meth]; // expected-error {{unavailable}}
+}

Modified: cfe/trunk/test/SemaObjC/warn-missing-super.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/warn-missing-super.m?rev=180833&r1=180832&r2=180833&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/warn-missing-super.m (original)
+++ cfe/trunk/test/SemaObjC/warn-missing-super.m Tue Apr 30 19:24:09 2013
@@ -54,5 +54,5 @@ __attribute__((objc_root_class))
 // CHECK-GC-ONLY: 1 warning generated.
 
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-arc %s 2>&1 | FileCheck --check-prefix=CHECK-ARC %s
-// CHECK-ARC: warn-missing-super.m:36:4: error: ARC forbids explicit message send of 'dealloc'
+// CHECK-ARC: warn-missing-super.m:36:10: error: ARC forbids explicit message send of 'dealloc'
 // CHECK-ARC: 1 error generated.





More information about the cfe-commits mailing list