diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-05-01 00:24:09 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-05-01 00:24:09 +0000 |
commit | f4d02398936c0fdc9fe981348519fbc323f24ad0 (patch) | |
tree | 6fc5550624cbdd1a3057694185e79022b22bcdd8 | |
parent | 230ea4179a4684ec0d89954b7a93731b176546e9 (diff) |
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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180833 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/ARCMigrate/TransAPIUses.cpp | 4 | ||||
-rw-r--r-- | lib/ARCMigrate/TransRetainReleaseDealloc.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 65 | ||||
-rw-r--r-- | test/ARCMT/check-with-serialized-diag.m | 12 | ||||
-rw-r--r-- | test/ARCMT/migrate-plist-output.m | 6 | ||||
-rw-r--r-- | test/SemaObjC/message.m | 12 | ||||
-rw-r--r-- | test/SemaObjC/warn-missing-super.m | 2 |
7 files changed, 67 insertions, 38 deletions
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp index 2305b6defd..a0994a6b45 100644 --- a/lib/ARCMigrate/TransAPIUses.cpp +++ b/lib/ARCMigrate/TransAPIUses.cpp @@ -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; diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp index 0c8d155446..446a284a28 100644 --- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp @@ -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; diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index e7b5ec9b01..fed86eed51 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1191,6 +1191,12 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType, 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(QualType ReceiverType, 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(QualType ReceiverType, 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(QualType ReceiverType, 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(QualType ReceiverType, // 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(QualType ReceiverType, 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(QualType ReceiverType, } } - 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(TypeSourceInfo *ReceiverTypeInfo, << 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(TypeSourceInfo *ReceiverTypeInfo, 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(TypeSourceInfo *ReceiverTypeInfo, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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(Expr *Receiver, 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: diff --git a/test/ARCMT/check-with-serialized-diag.m b/test/ARCMT/check-with-serialized-diag.m index d8073d0469..77bad96dcc 100644 --- a/test/ARCMT/check-with-serialized-diag.m +++ b/test/ARCMT/check-with-serialized-diag.m @@ -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 diff --git a/test/ARCMT/migrate-plist-output.m b/test/ARCMT/migrate-plist-output.m index 12efa93f07..377dce30ca 100644 --- a/test/ARCMT/migrate-plist-output.m +++ b/test/ARCMT/migrate-plist-output.m @@ -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> diff --git a/test/SemaObjC/message.m b/test/SemaObjC/message.m index f43bdf9885..40fa102f35 100644 --- a/test/SemaObjC/message.m +++ b/test/SemaObjC/message.m @@ -106,3 +106,15 @@ void foo5(id p) { // expected-note {{to match this '['}} \ // expected-warning {{instance method '-bar' not found}} } + +@interface I1 +-(void)unavail_meth __attribute__((unavailable)); // expected-note {{marked unavailable here}} +@end + +// rdar://13620447 +void foo6(I1 *p) { + [p + bar]; // expected-warning {{instance method '-bar' not found}} + [p + unavail_meth]; // expected-error {{unavailable}} +} diff --git a/test/SemaObjC/warn-missing-super.m b/test/SemaObjC/warn-missing-super.m index 02b81651d7..e9769a9db1 100644 --- a/test/SemaObjC/warn-missing-super.m +++ b/test/SemaObjC/warn-missing-super.m @@ -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. |