|
| 1 | +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=windows |
| 2 | +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=windows |
| 3 | +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -verify=linux |
| 4 | +// RUN: %clang_cc1 %s -triple x86_64-pc-linux -fsyntax-only -Wcast-function-type -Wno-cast-function-type-strict -x c++ -verify=linux,linux-cpp |
| 5 | +// RUN: %clang_cc1 %s -triple x86_64-windows -fsyntax-only -Wcast-function-type -Wcast-function-type-strict -x c++ -verify=strict |
| 6 | +// windows-no-diagnostics |
| 7 | + |
| 8 | +// On Windows targets, this is expected to compile fine, and on non-Windows |
| 9 | +// targets, this should diagnose the mismatch. This is to allow for idiomatic |
| 10 | +// use of GetProcAddress, similar to what we do for dlsym. On non-Windows |
| 11 | +// targets, this should be diagnosed. |
| 12 | +typedef int (*FARPROC1)(); |
| 13 | +typedef unsigned long long (*FARPROC2)(); |
| 14 | + |
| 15 | +FARPROC1 GetProcAddress1(void); |
| 16 | +FARPROC2 GetProcAddress2(void); |
| 17 | + |
| 18 | +typedef int (*test1_type)(int); |
| 19 | +typedef float(*test2_type)(); |
| 20 | + |
| 21 | +void test(void) { |
| 22 | + // This does not diagnose on Linux in C mode because FARPROC1 has a matching |
| 23 | + // return type to test1_type, but FARPROC1 has no prototype and so checking |
| 24 | + // is disabled for further compatibility issues. In C++ mode, all functions |
| 25 | + // have a prototype and so the check happens. |
| 26 | + test1_type t1 = (test1_type)GetProcAddress1(); |
| 27 | + // linux-cpp-warning@-1 {{cast from 'FARPROC1' (aka 'int (*)()') to 'test1_type' (aka 'int (*)(int)') converts to incompatible function type}} |
| 28 | + // strict-warning@-2 {{cast from 'FARPROC1' (aka 'int (*)()') to 'test1_type' (aka 'int (*)(int)') converts to incompatible function type}} |
| 29 | + |
| 30 | + // This case is diagnosed in both C and C++ modes on Linux because the return |
| 31 | + // type of FARPROC2 does not match the return type of test2_type. |
| 32 | + test2_type t2 = (test2_type)GetProcAddress2(); |
| 33 | + // linux-warning@-1 {{cast from 'FARPROC2' (aka 'unsigned long long (*)()') to 'test2_type' (aka 'float (*)()') converts to incompatible function type}} |
| 34 | + // strict-warning@-2 {{cast from 'FARPROC2' (aka 'unsigned long long (*)()') to 'test2_type' (aka 'float (*)()') converts to incompatible function type}} |
| 35 | +} |
| 36 | + |
0 commit comments