mirror of https://github.com/microsoft/clang.git
[Sema] Create a separate group for incompatible function pointer warning
Give incompatible function pointer warning its own diagnostic group but still leave it as a subgroup of incompatible-pointer-types. This is in preparation to promote -Wincompatible-function-pointer-types to error on darwin. Differential Revision: https://reviews.llvm.org/D22248 rdar://problem/12907612 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@275907 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
238b19c335
commit
5de4c509d1
|
@ -225,9 +225,12 @@ def GNUIncludeNext : DiagGroup<"gnu-include-next">;
|
||||||
def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
|
def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
|
||||||
def IncompatiblePointerTypesDiscardsQualifiers
|
def IncompatiblePointerTypesDiscardsQualifiers
|
||||||
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
|
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
|
||||||
|
def IncompatibleFunctionPointerTypes
|
||||||
|
: DiagGroup<"incompatible-function-pointer-types">;
|
||||||
def IncompatiblePointerTypes
|
def IncompatiblePointerTypes
|
||||||
: DiagGroup<"incompatible-pointer-types",
|
: DiagGroup<"incompatible-pointer-types",
|
||||||
[IncompatiblePointerTypesDiscardsQualifiers]>;
|
[IncompatiblePointerTypesDiscardsQualifiers,
|
||||||
|
IncompatibleFunctionPointerTypes]>;
|
||||||
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
|
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
|
||||||
def NonModularIncludeInFrameworkModule
|
def NonModularIncludeInFrameworkModule
|
||||||
: DiagGroup<"non-modular-include-in-framework-module">;
|
: DiagGroup<"non-modular-include-in-framework-module">;
|
||||||
|
|
|
@ -6351,6 +6351,24 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
|
||||||
"; remove *|"
|
"; remove *|"
|
||||||
"; remove &}3">,
|
"; remove &}3">,
|
||||||
InGroup<IncompatiblePointerTypes>;
|
InGroup<IncompatiblePointerTypes>;
|
||||||
|
def ext_typecheck_convert_incompatible_function_pointer : ExtWarn<
|
||||||
|
"incompatible function pointer types "
|
||||||
|
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
|
||||||
|
"|%diff{passing $ to parameter of type $|"
|
||||||
|
"passing to parameter of different type}0,1"
|
||||||
|
"|%diff{returning $ from a function with result type $|"
|
||||||
|
"returning from function with different return type}0,1"
|
||||||
|
"|%diff{converting $ to type $|converting between types}0,1"
|
||||||
|
"|%diff{initializing $ with an expression of type $|"
|
||||||
|
"initializing with expression of different type}0,1"
|
||||||
|
"|%diff{sending $ to parameter of type $|"
|
||||||
|
"sending to parameter of different type}0,1"
|
||||||
|
"|%diff{casting $ to type $|casting between types}0,1}2"
|
||||||
|
"%select{|; dereference with *|"
|
||||||
|
"; take the address with &|"
|
||||||
|
"; remove *|"
|
||||||
|
"; remove &}3">,
|
||||||
|
InGroup<IncompatibleFunctionPointerTypes>;
|
||||||
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
|
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
|
||||||
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
|
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
|
||||||
"|%diff{passing $ to parameter of type $|"
|
"|%diff{passing $ to parameter of type $|"
|
||||||
|
|
|
@ -12423,10 +12423,14 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
||||||
MayHaveConvFixit = true;
|
MayHaveConvFixit = true;
|
||||||
break;
|
break;
|
||||||
case IncompatiblePointer:
|
case IncompatiblePointer:
|
||||||
DiagKind =
|
if (Action == AA_Passing_CFAudited)
|
||||||
(Action == AA_Passing_CFAudited ?
|
DiagKind = diag::err_arc_typecheck_convert_incompatible_pointer;
|
||||||
diag::err_arc_typecheck_convert_incompatible_pointer :
|
else if (SrcType->isFunctionPointerType() &&
|
||||||
diag::ext_typecheck_convert_incompatible_pointer);
|
DstType->isFunctionPointerType())
|
||||||
|
DiagKind = diag::ext_typecheck_convert_incompatible_function_pointer;
|
||||||
|
else
|
||||||
|
DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
|
||||||
|
|
||||||
CheckInferredResultType = DstType->isObjCObjectPointerType() &&
|
CheckInferredResultType = DstType->isObjCObjectPointerType() &&
|
||||||
SrcType->isObjCObjectPointerType();
|
SrcType->isObjCObjectPointerType();
|
||||||
if (Hint.isNull() && !CheckInferredResultType) {
|
if (Hint.isNull() && !CheckInferredResultType) {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-pointer-types -verify
|
||||||
|
// RUN: %clang_cc1 -fsyntax-only %s -Wincompatible-function-pointer-types -verify
|
||||||
|
|
||||||
|
// This test ensures that the subgroup of -Wincompatible-pointer-types warnings
|
||||||
|
// that concern function pointers can be promoted (or not promoted) to an error
|
||||||
|
// *separately* from the other -Wincompatible-pointer-type warnings.
|
||||||
|
typedef int (*MyFnTyA)(int *, char *);
|
||||||
|
|
||||||
|
int bar(char *a, int *b) { return 0; }
|
||||||
|
int foo(MyFnTyA x) { return 0; } // expected-note {{passing argument to parameter 'x' here}}
|
||||||
|
|
||||||
|
void baz() {
|
||||||
|
foo(&bar); // expected-warning {{incompatible function pointer types passing 'int (*)(char *, int *)' to parameter of type 'MyFnTyA' (aka 'int (*)(int *, char *)')}}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ void foo(void);
|
||||||
void foo_noret(void) __attribute__((noreturn));
|
void foo_noret(void) __attribute__((noreturn));
|
||||||
|
|
||||||
void test() {
|
void test() {
|
||||||
Fn_noret fn2 = &foo; // expected-warning {{incompatible pointer types initializing 'Fn_noret'}}
|
Fn_noret fn2 = &foo; // expected-warning {{incompatible function pointer types initializing 'Fn_noret'}}
|
||||||
Fn_noret fn3 = &foo_noret;
|
Fn_noret fn3 = &foo_noret;
|
||||||
Fn_ret fn4 = &foo_noret;
|
Fn_ret fn4 = &foo_noret;
|
||||||
Fn_ret fn5 = &foo;
|
Fn_ret fn5 = &foo;
|
||||||
|
|
|
@ -109,7 +109,7 @@ void fn_type_conversions() {
|
||||||
void (*ambiguous)(int *) = &foo; // expected-error{{initializing 'void (*)(int *)' with an expression of incompatible type '<overloaded function type>'}} expected-note@105{{candidate function}} expected-note@106{{candidate function}}
|
void (*ambiguous)(int *) = &foo; // expected-error{{initializing 'void (*)(int *)' with an expression of incompatible type '<overloaded function type>'}} expected-note@105{{candidate function}} expected-note@106{{candidate function}}
|
||||||
void *vp_ambiguous = &foo; // expected-error{{initializing 'void *' with an expression of incompatible type '<overloaded function type>'}} expected-note@105{{candidate function}} expected-note@106{{candidate function}}
|
void *vp_ambiguous = &foo; // expected-error{{initializing 'void *' with an expression of incompatible type '<overloaded function type>'}} expected-note@105{{candidate function}} expected-note@106{{candidate function}}
|
||||||
|
|
||||||
void (*specific1)(int *) = (void (*)(void *))&foo; // expected-warning{{incompatible pointer types initializing 'void (*)(int *)' with an expression of type 'void (*)(void *)'}}
|
void (*specific1)(int *) = (void (*)(void *))&foo; // expected-warning{{incompatible function pointer types initializing 'void (*)(int *)' with an expression of type 'void (*)(void *)'}}
|
||||||
void *specific2 = (void (*)(void *))&foo;
|
void *specific2 = (void (*)(void *))&foo;
|
||||||
|
|
||||||
void disabled(void *c) __attribute__((overloadable, enable_if(0, "")));
|
void disabled(void *c) __attribute__((overloadable, enable_if(0, "")));
|
||||||
|
|
Loading…
Reference in New Issue