================ @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 %s -fsyntax-only -Wextra -verify + + +int t(int array[static 12]); +int u(int i); +const int v(int i); /* expected-warning {{'const' type qualifier on return type has no effec}} */ +int x(long); + +typedef int (f1)(long); +typedef int (f2)(void*); +typedef int (f3)(); +typedef void (f4)(); +typedef void (f5)(void); +typedef int (f6)(long, int); +typedef int (f7)(long,...); +typedef int (f8)(int *); +typedef int (f9)(const int); +typedef int (f10)(int); + +f1 *a; +f2 *b; +f3 *c; +f4 *d; +f5 *e; +f6 *f; +f7 *g; +f8 *h; +f9 *i; +f10 *j; + +void foo(void) { + a = (f1 *)x; + b = (f2 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f2 *' (aka 'int (*)(void *)') converts to incompatible function type}} */ + c = (f3 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f3 *' (aka 'int (*)()') converts to incompatible function type}} */ + d = (f4 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f4 *' (aka 'void (*)()') converts to incompatible function type}} */ + e = (f5 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f5 *' (aka 'void (*)(void)') converts to incompatible function type}} */ + f = (f6 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f6 *' (aka 'int (*)(long, int)') converts to incompatible function type}} */ + g = (f7 *)x; /* expected-warning {{cast from 'int (*)(long)' to 'f7 *' (aka 'int (*)(long, ...)') converts to incompatible function type}} */ + h = (f8 *)t; + i = (f9 *)u; + j = (f10 *)v; /* expected-warning {{cast from 'const int (*)(int)' to 'f10 *' (aka 'int (*)(int)') converts to incompatible function type}} */ ---------------- AaronBallman wrote:
I think the diagnostic here is incorrect. C23 6.7.6.3p4: If, in the declaration "T D1", D1 has the form D ( parameter-type-listopt ) attribute-specifier-sequenceopt and the type specified for ident in the declaration "T D" is "derived-declarator-type-list T", then the type specified for ident is "derived-declarator-type-list function returning the unqualified, non-atomic version of T". The optional attribute specifier sequence appertains to the function type. So the type of the function does not include the qualifiers on the return type, which means that `const int f(void)` and `int f(void)` should result in the same type. We get this wrong: https://godbolt.org/z/xvh449xrd I think this is a more general problem with how we model the function type: https://godbolt.org/z/G3vxjW9dh https://github.com/llvm/llvm-project/pull/77178 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits