From: Jordy Rose Date: Sat, 12 May 2012 15:53:41 +0000 (+0000) Subject: Don't crash on boxed strings when +stringWithUTF8String: is missing. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=99446d934c85e8b705cc6b8624e65b8eb8c22985;p=clang Don't crash on boxed strings when +stringWithUTF8String: is missing. 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 90c1551b2c..ddb8b280fb 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index ed71eb128c..24f4437b61 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -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()); 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(); } } diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m index 6635bea72e..26bca189d1 100644 --- a/test/SemaObjC/objc-literal-nsnumber.m +++ b/test/SemaObjC/objc-literal-nsnumber.m @@ -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}} +} diff --git a/test/SemaObjC/objc-literal-sig.m b/test/SemaObjC/objc-literal-sig.m index fb5c79fd84..350fdd0747 100644 --- a/test/SemaObjC/objc-literal-sig.m +++ b/test/SemaObjC/objc-literal-sig.m @@ -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}} }