From: Fariborz Jahanian Date: Mon, 10 Jun 2013 23:51:51 +0000 (+0000) Subject: Objective-C [qoi]: Issue better warning when nsstring literal is missing X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4017d7378b1544e6c43f0ad857e6c18c3957efe0;p=clang Objective-C [qoi]: Issue better warning when nsstring literal is missing the '@'. PR16287 and // rdar://14106083 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183713 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 99b342454c..5d9b9c93e6 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -539,8 +539,10 @@ def ObjCCocoaAPI : DiagGroup<"objc-cocoa-api", [ ]>; def ObjCStringComparison : DiagGroup<"objc-string-compare">; +def ObjCLiteralMissingAtSign : DiagGroup<"objc-literal-missing-atsign">; def ObjCLiteralComparison : DiagGroup<"objc-literal-compare", [ - ObjCStringComparison + ObjCStringComparison, + ObjCLiteralMissingAtSign ]>; // Inline ASM warnings. diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b9c0518dec..c476ac906e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1879,6 +1879,8 @@ def warn_objc_literal_comparison : Warning< "direct comparison of %select{an array literal|a dictionary literal|" "a numeric literal|a boxed expression|}0 has undefined behavior">, InGroup; +def warn_missing_atsign_prefix : Warning< + "string literal must be prefixed by '@' ">, InGroup; def warn_objc_string_literal_comparison : Warning< "direct comparison of a string literal has undefined behavior">, InGroup; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index fcfe17a007..66598992d7 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10195,7 +10195,8 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { } static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, - Expr *SrcExpr, FixItHint &Hint) { + Expr *SrcExpr, FixItHint &Hint, + bool &IsNSString) { if (!SemaRef.getLangOpts().ObjC1) return; @@ -10209,6 +10210,7 @@ static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, const ObjCInterfaceDecl *ID = PT->getInterfaceDecl(); if (!ID || !ID->getIdentifier()->isStr("NSString")) return; + IsNSString = true; } // Ignore any parens, implicit casts (should only be @@ -10242,6 +10244,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, ConversionFixItGenerator ConvHints; bool MayHaveConvFixit = false; bool MayHaveFunctionDiff = false; + bool IsNSString = false; switch (ConvTy) { case Compatible: @@ -10259,7 +10262,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, MayHaveConvFixit = true; break; case IncompatiblePointer: - MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint); + MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString); DiagKind = diag::ext_typecheck_convert_incompatible_pointer; CheckInferredResultType = DstType->isObjCObjectPointerType() && SrcType->isObjCObjectPointerType(); @@ -10270,6 +10273,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, SrcType = SrcType.getUnqualifiedType(); DstType = DstType.getUnqualifiedType(); } + else if (IsNSString && !Hint.isNull()) + DiagKind = diag::warn_missing_atsign_prefix; MayHaveConvFixit = true; break; case IncompatiblePointerSign: diff --git a/test/FixIt/fixit-objc.m b/test/FixIt/fixit-objc.m index ea57fe671b..7c4776ae71 100644 --- a/test/FixIt/fixit-objc.m +++ b/test/FixIt/fixit-objc.m @@ -27,13 +27,13 @@ void g(NSString *a); // expected-note{{passing argument to parameter 'a' here}} void h(id a); // expected-note 2{{passing argument to parameter 'a' here}} void f(Test *t) { - NSString *a = "Foo"; // expected-warning {{incompatible pointer types initializing 'NSString *' with an expression of type 'char [4]'}} + NSString *a = "Foo"; // expected-warning {{string literal must be prefixed by '@'}} id b = "Foo"; // expected-warning {{incompatible pointer types initializing 'id' with an expression of type 'char [4]'}} - g("Foo"); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'NSString *'}} + g("Foo"); // expected-warning {{string literal must be prefixed by '@'}} h("Foo"); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}} h(("Foo")); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}} - [t test:"Foo"]; // expected-warning{{incompatible pointer types sending 'char [4]' to parameter of type 'NSString *'}} - t.property = "Foo"; // expected-warning{{incompatible pointer types assigning to 'NSString *' from 'char [4]'}} + [t test:"Foo"]; // expected-warning {{string literal must be prefixed by '@'}} + t.property = "Foo"; // expected-warning {{string literal must be prefixed by '@'}} // [t test:@"Foo"]]; // expected-error{{extraneous ']' before ';'}}