"too many %select{|||execution configuration }0arguments to "
"%select{function|block|method|kernel function}0 call, "
"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<
"%0 declared here">;
def note_defined_here : Note<"%0 defined here">;
AA_Converting,
AA_Initializing,
AA_Sending,
- AA_Casting
+ AA_Casting,
+ AA_Passing_CFAudited
};
/// C++ Overloading.
FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
(!Param || !Param->hasAttr<CFConsumedAttr>()))
Arg = stripARCUnbridgedCast(Arg);
- else if (FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
+ else if (getLangOpts().ObjCAutoRefCount &&
+ FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() &&
(!Param || !Param->hasAttr<CFConsumedAttr>()))
CFAudited = true;
break;
case IncompatiblePointer:
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() &&
SrcType->isObjCObjectPointerType();
if (Hint.isNull() && !CheckInferredResultType) {
case AA_Returning:
case AA_Passing:
+ case AA_Passing_CFAudited:
case AA_Converting:
case AA_Sending:
case AA_Casting:
}
PartialDiagnostic FDiag = PDiag(DiagKind);
- FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange();
+ if (Action == AA_Passing_CFAudited)
+ FDiag << FirstType << SecondType << SrcExpr->getSourceRange();
+ else
+ FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange();
// If we can fix the conversion, suggest the FixIts.
assert(ConvHints.isNull() || Hint.isNull());
// Perform initialization
//===----------------------------------------------------------------------===//
static Sema::AssignmentAction
-getAssignmentAction(const InitializedEntity &Entity) {
+getAssignmentAction(const InitializedEntity &Entity, bool Diagnose = false) {
switch(Entity.getKind()) {
case InitializedEntity::EK_Variable:
case InitializedEntity::EK_New:
return Sema::AA_Initializing;
case InitializedEntity::EK_Parameter:
- case InitializedEntity::EK_Parameter_CF_Audited:
if (Entity.getDecl() &&
isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext()))
return Sema::AA_Sending;
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:
return Sema::AA_Returning;
if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
Step->Type, SourceType,
CurInit.get(),
- getAssignmentAction(Entity),
+ getAssignmentAction(Entity, true),
&Complained)) {
PrintInitLocationNote(S, Entity);
return ExprError();
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}}
}
+
+// 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'}}
+}