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 IncompatiblePointerTypesDiscardsQualifiers
|
||||
: DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
|
||||
def IncompatibleFunctionPointerTypes
|
||||
: DiagGroup<"incompatible-function-pointer-types">;
|
||||
def IncompatiblePointerTypes
|
||||
: DiagGroup<"incompatible-pointer-types",
|
||||
[IncompatiblePointerTypesDiscardsQualifiers]>;
|
||||
[IncompatiblePointerTypesDiscardsQualifiers,
|
||||
IncompatibleFunctionPointerTypes]>;
|
||||
def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
|
||||
def NonModularIncludeInFrameworkModule
|
||||
: DiagGroup<"non-modular-include-in-framework-module">;
|
||||
|
|
|
@ -6351,6 +6351,24 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
|
|||
"; remove *|"
|
||||
"; remove &}3">,
|
||||
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<
|
||||
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
|
||||
"|%diff{passing $ to parameter of type $|"
|
||||
|
|
|
@ -12423,10 +12423,14 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
MayHaveConvFixit = true;
|
||||
break;
|
||||
case IncompatiblePointer:
|
||||
DiagKind =
|
||||
(Action == AA_Passing_CFAudited ?
|
||||
diag::err_arc_typecheck_convert_incompatible_pointer :
|
||||
diag::ext_typecheck_convert_incompatible_pointer);
|
||||
if (Action == AA_Passing_CFAudited)
|
||||
DiagKind = diag::err_arc_typecheck_convert_incompatible_pointer;
|
||||
else if (SrcType->isFunctionPointerType() &&
|
||||
DstType->isFunctionPointerType())
|
||||
DiagKind = diag::ext_typecheck_convert_incompatible_function_pointer;
|
||||
else
|
||||
DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
|
||||
|
||||
CheckInferredResultType = DstType->isObjCObjectPointerType() &&
|
||||
SrcType->isObjCObjectPointerType();
|
||||
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 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_ret fn4 = &foo_noret;
|
||||
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 *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 disabled(void *c) __attribute__((overloadable, enable_if(0, "")));
|
||||
|
|
Loading…
Reference in New Issue