]> granicus.if.org Git - clang/commitdiff
Objective-C. After providing a fix-it for a
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 18 Dec 2013 21:04:43 +0000 (21:04 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 18 Dec 2013 21:04:43 +0000 (21:04 +0000)
cstring, converted to NSString, produce the
matching AST for it. This also required some
refactoring of the previous code. // rdar://14106083

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

include/clang/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaInit.cpp
test/Analysis/default-analyze.m
test/FixIt/fixit-objc-arc.m
test/FixIt/fixit-objc.m
test/Index/fix-its.m

index 847ac820d95bb4fe0935def4dc9af179ef5b8832..0e4ab07af01d1b747c05d39c6231d972d7ac892e 100644 (file)
@@ -6902,9 +6902,7 @@ public:
                                          QualType DestType, QualType SrcType,
                                          Expr *&SrcExpr);
   
-  StringLiteral * ConversionToObjCStringLiteralCheck(QualType DstType,
-                                          Expr *SrcExpr, FixItHint &Hint,
-                                          bool &IsNSString);
+  bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
   
   bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
 
index 0597a998c475fdd5ce75531e30cf03be8a69e36c..fcd972436daa26ba6e8f10d7c368028f265c1b21 100644 (file)
@@ -6613,8 +6613,9 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS,
       CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
                              DiagnoseCFAudited);
     if (getLangOpts().ObjC1 &&
-        CheckObjCBridgeRelatedConversions(E->getLocStart(),
-                                          LHSType, E->getType(), E)) {
+        (CheckObjCBridgeRelatedConversions(E->getLocStart(),
+                                          LHSType, E->getType(), E) ||
+         ConversionToObjCStringLiteralCheck(LHSType, E))) {
       RHS = Owned(E);
       return Compatible;
     }
@@ -10587,39 +10588,37 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
   return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
 }
 
-StringLiteral *
-Sema::ConversionToObjCStringLiteralCheck(QualType DstType,
-                                     Expr *SrcExpr, FixItHint &Hint,
-                                     bool &IsNSString) {
+bool
+Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
   if (!getLangOpts().ObjC1)
-    return 0;
+    return false;
 
   const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
   if (!PT)
-    return 0;
+    return false;
 
-  // Check if the destination is of type 'id'.
   if (!PT->isObjCIdType()) {
     // Check if the destination is the 'NSString' interface.
     const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
     if (!ID || !ID->getIdentifier()->isStr("NSString"))
-      return 0;
-    IsNSString = true;
+      return false;
   }
-
+  
   // Ignore any parens, implicit casts (should only be
   // array-to-pointer decays), and not-so-opaque values.  The last is
   // important for making this trigger for property assignments.
-  SrcExpr = SrcExpr->IgnoreParenImpCasts();
+  Expr *SrcExpr = Exp->IgnoreParenImpCasts();
   if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))
     if (OV->getSourceExpr())
       SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();
 
   StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
   if (!SL || !SL->isAscii())
-    return 0;
-  Hint = FixItHint::CreateInsertion(SL->getLocStart(), "@");
-  return SL;
+    return false;
+  Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
+    << FixItHint::CreateInsertion(SL->getLocStart(), "@");
+  Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).take();
+  return true;
 }
 
 bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
@@ -10638,7 +10637,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
   ConversionFixItGenerator ConvHints;
   bool MayHaveConvFixit = false;
   bool MayHaveFunctionDiff = false;
-  bool IsNSString = false;
 
   switch (ConvTy) {
   case Compatible:
@@ -10656,7 +10654,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
     MayHaveConvFixit = true;
     break;
   case IncompatiblePointer:
-    ConversionToObjCStringLiteralCheck(DstType, SrcExpr, Hint, IsNSString);
       DiagKind =
         (Action == AA_Passing_CFAudited ?
           diag::err_arc_typecheck_convert_incompatible_pointer :
@@ -10670,8 +10667,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
       SrcType = SrcType.getUnqualifiedType();
       DstType = DstType.getUnqualifiedType();
     }
-    else if (IsNSString && !Hint.isNull())
-      DiagKind = diag::err_missing_atsign_prefix;
     MayHaveConvFixit = true;
     break;
   case IncompatiblePointerSign:
index f312839a9d2b9fcf4c9f12884b2e8e333e24e1bf..8f0b90b3be29e0ec096ef1a5d3228ed7d34cde4d 100644 (file)
@@ -3615,13 +3615,9 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
   // Do not issue bridge cast" diagnostic when implicit casting a cstring
   // to 'NSString *'. Let caller issue a normal mismatched diagnostic with
   // suitable fix-it.
-  if (castACTC == ACTC_retainable && exprACTC == ACTC_none) {
-    bool IsNSString = false;
-    FixItHint Hint;
-    if (ConversionToObjCStringLiteralCheck(
-          castType, castExpr, Hint, IsNSString) && IsNSString)
-      return ACR_okay;
-  }
+  if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
+      ConversionToObjCStringLiteralCheck(castType, castExpr))
+    return ACR_okay;
   
   // Do not issue "bridge cast" diagnostic when implicit casting
   // a retainable object to a CF type parameter belonging to an audited
index 95456e52cc778d55e3613d49ede7942e1995ea38..9ba873a0780b7b4ebe05ad3beb2fa56930817ef2 100644 (file)
@@ -4462,11 +4462,14 @@ void InitializationSequence::InitializeFrom(Sema &S,
   Expr *Initializer = 0;
   if (Args.size() == 1) {
     Initializer = Args[0];
-    if (S.getLangOpts().ObjC1 &&
-        S.CheckObjCBridgeRelatedConversions(Initializer->getLocStart(),
-                                          DestType, Initializer->getType(),
-                                          Initializer))
-      Args[0] = Initializer;
+    if (S.getLangOpts().ObjC1) {
+      if (S.CheckObjCBridgeRelatedConversions(Initializer->getLocStart(),
+                                              DestType, Initializer->getType(),
+                                              Initializer) ||
+          S.ConversionToObjCStringLiteralCheck(DestType, Initializer))
+        Args[0] = Initializer;
+        
+    }
     if (!isa<InitListExpr>(Initializer))
       SourceType = Initializer->getType();
   }
index 82656b24a6e97dffb4ec1fa581751aecf12e2292..5fbaa2f98c655ceec97f0fbee9c3d17b3d034e15 100644 (file)
@@ -11,7 +11,7 @@ id foo(int x) {
     title = @"bar";
     break;
   default:
-    title = "@baz";
+    title = @"baz";
     break;
   }
   return title;
index 19a61b4108ed6238953f64f2f517c2125adfb3ab..dcee81594e780feb4bfe7a9c9ba31c4ab75f7d10 100644 (file)
@@ -8,12 +8,12 @@
 @class NSString;
 
 @interface Test
-- (void)test:(NSString *)string; // expected-note{{passing argument to parameter 'string' here}}
+- (void)test:(NSString *)string;
 
 @property (copy) NSString *property;
 @end
 
-void g(NSString *a); // expected-note{{passing argument to parameter 'a' here}}
+void g(NSString *a);
 void h(id a);
 
 void f(Test *t) {
index 17de36528e50c9c19bc35d166a08316037584282..f41f75f1d7be99fe61ec12b1f25a552dc5fc45a3 100644 (file)
@@ -18,20 +18,20 @@ void foo() {
 @class NSString;
 
 @interface Test
-- (void)test:(NSString *)string; // expected-note{{passing argument to parameter 'string' here}}
+- (void)test:(NSString *)string;
 
 @property (copy) NSString *property;
 @end
 
-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 g(NSString *a);
+void h(id a);
 
 void f(Test *t) {
   NSString *a = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
-  id b = "Foo"; // expected-warning {{incompatible pointer types initializing 'id' with an expression of type 'char [4]'}}
+  id b = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
   g("Foo"); // expected-error {{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'}}
+  h("Foo"); // expected-error {{string literal must be prefixed by '@'}}
+  h(("Foo")); // expected-error {{string literal must be prefixed by '@'}}
   [t test:"Foo"]; // expected-error {{string literal must be prefixed by '@'}}
   t.property = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
 
index b307cf4c6dc666ecc2cfba1fa8fcd8b48fee96a5..fabcdb2905f66bddba6fb7a5d7426c2a7cb259ea 100644 (file)
@@ -24,5 +24,3 @@ void _rdar_12584554_A (volatile const void * object, volatile const void * selec
 // CHECK: Number FIX-ITs = 0
 // CHECK: fix-its.m:7:77: note: expanded from macro '_rdar_12584554_B'
 // CHECK: Number FIX-ITs = 0
-// CHECK: fix-its.m:5:172: note: passing argument to parameter 'msgFormat' here
-// CHECK: Number FIX-ITs = 0