mirror of https://github.com/microsoft/clang.git
ObjectiveC ARC: finishing off issuing error when
retainable pointer is passed to an audited CF function expecting CF type. // rdar://14569171 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@187543 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eff18b9b6f
commit
3d672e4aa5
|
@ -5367,6 +5367,11 @@ def err_typecheck_call_too_many_args_at_most_suggest : Error<
|
||||||
"too many %select{|||execution configuration }0arguments to "
|
"too many %select{|||execution configuration }0arguments to "
|
||||||
"%select{function|block|method|kernel function}0 call, "
|
"%select{function|block|method|kernel function}0 call, "
|
||||||
"expected at most %1, have %2; did you mean %3?">;
|
"expected at most %1, have %2; did you mean %3?">;
|
||||||
|
|
||||||
|
def err_arc_typecheck_convert_incompatible_pointer : Error<
|
||||||
|
"incompatible pointer types passing retainable parameter of type %0"
|
||||||
|
"to a CF function expecting %1 type">;
|
||||||
|
|
||||||
def note_callee_decl : Note<
|
def note_callee_decl : Note<
|
||||||
"%0 declared here">;
|
"%0 declared here">;
|
||||||
def note_defined_here : Note<"%0 defined here">;
|
def note_defined_here : Note<"%0 defined here">;
|
||||||
|
|
|
@ -1857,7 +1857,8 @@ public:
|
||||||
AA_Converting,
|
AA_Converting,
|
||||||
AA_Initializing,
|
AA_Initializing,
|
||||||
AA_Sending,
|
AA_Sending,
|
||||||
AA_Casting
|
AA_Casting,
|
||||||
|
AA_Passing_CFAudited
|
||||||
};
|
};
|
||||||
|
|
||||||
/// C++ Overloading.
|
/// C++ Overloading.
|
||||||
|
|
|
@ -4066,7 +4066,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
|
||||||
FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
|
FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
|
||||||
(!Param || !Param->hasAttr<CFConsumedAttr>()))
|
(!Param || !Param->hasAttr<CFConsumedAttr>()))
|
||||||
Arg = stripARCUnbridgedCast(Arg);
|
Arg = stripARCUnbridgedCast(Arg);
|
||||||
else if (FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
|
else if (getLangOpts().ObjCAutoRefCount &&
|
||||||
|
FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
|
||||||
(!Param || !Param->hasAttr<CFConsumedAttr>()))
|
(!Param || !Param->hasAttr<CFConsumedAttr>()))
|
||||||
CFAudited = true;
|
CFAudited = true;
|
||||||
|
|
||||||
|
@ -10391,7 +10392,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
||||||
break;
|
break;
|
||||||
case IncompatiblePointer:
|
case IncompatiblePointer:
|
||||||
MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString);
|
MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString);
|
||||||
DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
|
DiagKind =
|
||||||
|
(Action == AA_Passing_CFAudited ?
|
||||||
|
diag::err_arc_typecheck_convert_incompatible_pointer :
|
||||||
|
diag::ext_typecheck_convert_incompatible_pointer);
|
||||||
CheckInferredResultType = DstType->isObjCObjectPointerType() &&
|
CheckInferredResultType = DstType->isObjCObjectPointerType() &&
|
||||||
SrcType->isObjCObjectPointerType();
|
SrcType->isObjCObjectPointerType();
|
||||||
if (Hint.isNull() && !CheckInferredResultType) {
|
if (Hint.isNull() && !CheckInferredResultType) {
|
||||||
|
@ -10485,6 +10489,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
||||||
|
|
||||||
case AA_Returning:
|
case AA_Returning:
|
||||||
case AA_Passing:
|
case AA_Passing:
|
||||||
|
case AA_Passing_CFAudited:
|
||||||
case AA_Converting:
|
case AA_Converting:
|
||||||
case AA_Sending:
|
case AA_Sending:
|
||||||
case AA_Casting:
|
case AA_Casting:
|
||||||
|
@ -10495,6 +10500,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
||||||
}
|
}
|
||||||
|
|
||||||
PartialDiagnostic FDiag = PDiag(DiagKind);
|
PartialDiagnostic FDiag = PDiag(DiagKind);
|
||||||
|
if (Action == AA_Passing_CFAudited)
|
||||||
|
FDiag << FirstType << SecondType << SrcExpr->getSourceRange();
|
||||||
|
else
|
||||||
FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange();
|
FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange();
|
||||||
|
|
||||||
// If we can fix the conversion, suggest the FixIts.
|
// If we can fix the conversion, suggest the FixIts.
|
||||||
|
|
|
@ -4624,7 +4624,7 @@ InitializationSequence::~InitializationSequence() {
|
||||||
// Perform initialization
|
// Perform initialization
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
static Sema::AssignmentAction
|
static Sema::AssignmentAction
|
||||||
getAssignmentAction(const InitializedEntity &Entity) {
|
getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) {
|
||||||
switch(Entity.getKind()) {
|
switch(Entity.getKind()) {
|
||||||
case InitializedEntity::EK_Variable:
|
case InitializedEntity::EK_Variable:
|
||||||
case InitializedEntity::EK_New:
|
case InitializedEntity::EK_New:
|
||||||
|
@ -4634,13 +4634,19 @@ getAssignmentAction(const InitializedEntity &Entity) {
|
||||||
return Sema::AA_Initializing;
|
return Sema::AA_Initializing;
|
||||||
|
|
||||||
case InitializedEntity::EK_Parameter:
|
case InitializedEntity::EK_Parameter:
|
||||||
case InitializedEntity::EK_Parameter_CF_Audited:
|
|
||||||
if (Entity.getDecl() &&
|
if (Entity.getDecl() &&
|
||||||
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
|
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
|
||||||
return Sema::AA_Sending;
|
return Sema::AA_Sending;
|
||||||
|
|
||||||
return Sema::AA_Passing;
|
return Sema::AA_Passing;
|
||||||
|
|
||||||
|
case InitializedEntity::EK_Parameter_CF_Audited:
|
||||||
|
if (Entity.getDecl() &&
|
||||||
|
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
|
||||||
|
return Sema::AA_Sending;
|
||||||
|
|
||||||
|
return !Diagnose ? Sema::AA_Passing : Sema::AA_Passing_CFAudited;
|
||||||
|
|
||||||
case InitializedEntity::EK_Result:
|
case InitializedEntity::EK_Result:
|
||||||
return Sema::AA_Returning;
|
return Sema::AA_Returning;
|
||||||
|
|
||||||
|
@ -6000,7 +6006,7 @@ InitializationSequence::Perform(Sema &S,
|
||||||
if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
|
if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
|
||||||
Step->Type, SourceType,
|
Step->Type, SourceType,
|
||||||
CurInit.get(),
|
CurInit.get(),
|
||||||
getAssignmentAction(Entity),
|
getAssignmentAction(Entity, true),
|
||||||
&Complained)) {
|
&Complained)) {
|
||||||
PrintInitLocationNote(S, Entity);
|
PrintInitLocationNote(S, Entity);
|
||||||
return ExprError();
|
return ExprError();
|
||||||
|
|
|
@ -45,3 +45,15 @@ void test2() {
|
||||||
x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
|
x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
|
||||||
x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
|
x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rdar://14569171
|
||||||
|
@interface NSString @end
|
||||||
|
typedef signed int SInt32;
|
||||||
|
#pragma clang arc_cf_code_audited begin
|
||||||
|
extern SInt32 CFStringGetIntValue(CFStringRef str); // expected-note {{passing argument to parameter 'str' here}}
|
||||||
|
#pragma clang arc_cf_code_audited end
|
||||||
|
|
||||||
|
void test3() {
|
||||||
|
NSString* answer = @"42";
|
||||||
|
int ans = CFStringGetIntValue(answer); // expected-error {{incompatible pointer types passing retainable parameter of type 'NSString *__strong'to a CF function expecting 'CFStringRef'}}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue