]> granicus.if.org Git - clang/commitdiff
Don't crash on boxed strings when +stringWithUTF8String: is missing.
authorJordy Rose <jediknil@belkadan.com>
Sat, 12 May 2012 15:53:41 +0000 (15:53 +0000)
committerJordy Rose <jediknil@belkadan.com>
Sat, 12 May 2012 15:53:41 +0000 (15:53 +0000)
Also, unify some diagnostics for boxed expressions that have the same form.

Fixes PR12804.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExprObjC.cpp
test/SemaObjC/objc-literal-nsnumber.m
test/SemaObjC/objc-literal-sig.m

index 90c1551b2ce8a3083de5b76419bc903be6324310..ddb8b280fba25e183764d04d6fbfc6761f7ce056 100644 (file)
@@ -1545,12 +1545,8 @@ def err_undeclared_nsarray : Error<
 def err_undeclared_nsdictionary : Error<
   "NSDictionary must be available to use Objective-C dictionary "
   "literals">;
-def err_undeclared_arraywithobjects : Error<
-  "declaration of %0 is missing in NSArray class">;
-def err_undeclared_dictwithobjects : Error<
-  "declaration of %0 is missing in NSDictionary class">;
-def err_undeclared_nsnumber_method : Error<
-  "declaration of %0 is missing in NSNumber class">;
+def err_undeclared_boxing_method : Error<
+  "declaration of %0 is missing in %1 class">;
 def err_objc_literal_method_sig : Error<
   "literal construction method %0 has incompatible signature">;
 def note_objc_literal_method_param : Note<
index ed71eb128c693db28090300ffae0e9dbcd075644..24f4437b61ae860b208eb244ff2db08b04259275 100644 (file)
@@ -214,7 +214,9 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
   }
 
   if (!Method) {
-    S.Diag(Loc, diag::err_undeclared_nsnumber_method) << Sel;
+    // FIXME: Is there a better way to avoid quotes than using getName()?
+    S.Diag(Loc, diag::err_undeclared_boxing_method)
+      << Sel << S.NSNumberDecl->getName();
     return 0;
   }
   
@@ -471,8 +473,25 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
           M->setMethodParams(Context, value, ArrayRef<SourceLocation>());
           StringWithUTF8StringMethod = M;
         }
-        assert(StringWithUTF8StringMethod &&
-               "StringWithUTF8StringMethod should not be NULL");
+
+        // FIXME: Copied from getNSNumberFactoryMethod().
+        if (!StringWithUTF8StringMethod) {
+          // FIXME: Is there a better way to avoid quotes than using getName()?
+          Diag(SR.getBegin(), diag::err_undeclared_boxing_method)
+            << stringWithUTF8String << NSStringDecl->getName();
+          return ExprError();
+        }
+  
+        // Make sure the return type is reasonable.
+        QualType ResultType = StringWithUTF8StringMethod->getResultType();
+        if (!ResultType->isObjCObjectPointerType()) {
+          Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
+            << stringWithUTF8String;
+          Diag(StringWithUTF8StringMethod->getLocation(),
+               diag::note_objc_literal_method_return)
+            << ResultType;
+          return ExprError();
+        }
       }
       
       BoxingMethod = StringWithUTF8StringMethod;
@@ -633,7 +652,9 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
     }
 
     if (!ArrayWithObjectsMethod) {
-      Diag(SR.getBegin(), diag::err_undeclared_arraywithobjects) << Sel;
+      // FIXME: Is there a better way to avoid quotes than using getName()?
+      Diag(SR.getBegin(), diag::err_undeclared_boxing_method)
+        << Sel << NSArrayDecl->getName();
       return ExprError();
     }
   }
@@ -773,7 +794,9 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
     }
 
     if (!DictionaryWithObjectsMethod) {
-      Diag(SR.getBegin(), diag::err_undeclared_dictwithobjects) << Sel;
+      // FIXME: Is there a better way to avoid quotes than using getName()?
+      Diag(SR.getBegin(), diag::err_undeclared_boxing_method)
+        << Sel << NSDictionaryDecl->getName();
       return ExprError();    
     }
   }
index 6635bea72e7f3ed00b3f98f18ad7856f7f3c84fb..26bca189d1f6b4d1444c997422c2202b168b6ead 100644 (file)
@@ -83,3 +83,7 @@ typedef float BOOL;
 BOOL radar11231426() {
         return __objc_yes;
 }
+
+id stringBoxingNoSuchMethod(const char *str) {
+  return @(str); // expected-error {{declaration of 'stringWithUTF8String:' is missing in NSString class}}
+}
index fb5c79fd8437dbf40a64fcde6557d2b8e077ca58..350fdd07479f1ab46b2cc61d001058b8fe5c52a3 100644 (file)
@@ -19,6 +19,10 @@ typedef _Bool BOOL;
 + (int)numberWithBool:(BOOL)value; // expected-note{{method returns unexpected type 'int' (should be an object type)}}
 @end
 
+@interface NSString
++ (char)stringWithUTF8String:(const char *)value; // expected-note{{method returns unexpected type 'char' (should be an object type)}}
+@end
+
 @interface NSArray
 @end
 
@@ -37,4 +41,5 @@ void test_sig() {
   (void)@__objc_yes; // expected-error{{literal construction method 'numberWithBool:' has incompatible signature}}
   id array = @[ @17 ]; // expected-error{{literal construction method 'arrayWithObjects:count:' has incompatible signature}}
   id dict = @{ @"hello" : @17 }; // expected-error{{literal construction method 'dictionaryWithObjects:forKeys:count:' has incompatible signature}}
+  id str = @("hello"); // expected-error{{literal construction method 'stringWithUTF8String:' has incompatible signature}}
 }