Objective-C. After providing a fix-it for a

cstring, converted to NSString, produce the
matching AST for it. This also required some
refactoring of the previous code. // rdar://14106083

llvm-svn: 197605
This commit is contained in:
Fariborz Jahanian 2013-12-18 21:04:43 +00:00
parent afa854c15e
commit 283bf89506
8 changed files with 36 additions and 46 deletions

View 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);

View 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:

View 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

View 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();
}

View File

@ -11,7 +11,7 @@ id foo(int x) {
title = @"bar";
break;
default:
title = "@baz";
title = @"baz";
break;
}
return title;

View 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) {

View 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 '@'}}

View 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