]> granicus.if.org Git - clang/commitdiff
Objective-C [qoi]: Issue better warning when nsstring literal is missing
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 10 Jun 2013 23:51:51 +0000 (23:51 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 10 Jun 2013 23:51:51 +0000 (23:51 +0000)
the '@'. PR16287 and // rdar://14106083

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183713 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/FixIt/fixit-objc.m

index 99b342454c42b7cabc8ab4817386af8c2c1d9df0..5d9b9c93e685d7150b894a340a2a7e70aba4d959 100644 (file)
@@ -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.
index b9c0518decee88231fe4761b70edc4e24455af37..c476ac906eeef2c1b4bf64783553b7794dbf4de3 100644 (file)
@@ -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<ObjCLiteralComparison>;
+def warn_missing_atsign_prefix : Warning<
+  "string literal must be prefixed by '@' ">, InGroup<ObjCLiteralMissingAtSign>;
 def warn_objc_string_literal_comparison : Warning<
   "direct comparison of a string literal has undefined behavior">, 
   InGroup<ObjCStringComparison>;
index fcfe17a007bc36a905ab1c5944548ab0004c11ed..66598992d7f33857cebe850b3e6e00c9497b2edd 100644 (file)
@@ -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:
index ea57fe671b9435b2fb8dd5a8552139d938a69edb..7c4776ae71e7d150563a7f779841f4e0875517c4 100644 (file)
@@ -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 '@'}}
 
   // <rdar://problem/6896493>
   [t test:@"Foo"]]; // expected-error{{extraneous ']' before ';'}}