diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-08-27 23:08:25 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-08-27 23:08:25 +0000 |
commit | ef072033876e295ec5d3402f8730a3ae358ad815 (patch) | |
tree | c13128c478d6635eb264c1f2f357a12a4ca53b58 /test/Sema | |
parent | a7f6a94c1bae840c51351cd37cc247ae75f8e649 (diff) | |
download | clang-ef072033876e295ec5d3402f8730a3ae358ad815.tar.gz |
Delete CC_Default and use the target default CC everywhere
Summary:
Makes functions with implicit calling convention compatible with
function types with a matching explicit calling convention. This fixes
things like calls to qsort(), which has an explicit __cdecl attribute on
the comparator in Windows headers.
Clang will now infer the calling convention from the declarator. There
are two cases when the CC must be adjusted during redeclaration:
1. When defining a non-inline static method.
2. When redeclaring a function with an implicit or mismatched
convention.
Fixes PR13457, and allows clang to compile CommandLine.cpp for the
Microsoft C++ ABI.
Excellent test cases provided by Alexander Zinenko!
Reviewers: rsmith
Differential Revision: http://llvm-reviews.chandlerc.com/D1231
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189412 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Sema')
-rw-r--r-- | test/Sema/callingconv.c | 4 | ||||
-rw-r--r-- | test/Sema/mrtd.c | 40 |
2 files changed, 44 insertions, 0 deletions
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c index ea91675c19..b9adf791b5 100644 --- a/test/Sema/callingconv.c +++ b/test/Sema/callingconv.c @@ -56,3 +56,7 @@ PROC __attribute__((cdecl)) ctest4(const char *x) {} void __attribute__((pnaclcall)) pnaclfunc(float *a) {} // expected-warning {{calling convention 'pnaclcall' ignored for this target}} void __attribute__((intel_ocl_bicc)) inteloclbifunc(float *a) {} + +typedef void typedef_fun_t(int); +typedef_fun_t typedef_fun; // expected-note {{previous declaration is here}} +void __attribute__((stdcall)) typedef_fun(int x) { } // expected-error {{function declared 'stdcall' here was previously declared without calling convention}} diff --git a/test/Sema/mrtd.c b/test/Sema/mrtd.c new file mode 100644 index 0000000000..653413b012 --- /dev/null +++ b/test/Sema/mrtd.c @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -DMRTD -mrtd -triple i386-unknown-unknown -verify %s +// RUN: %clang_cc1 -triple i386-unknown-unknown -verify %s + +#ifndef MRTD +// expected-note@+5 {{previous declaration is here}} +// expected-error@+5 {{function declared 'stdcall' here was previously declared without calling convention}} +// expected-note@+5 {{previous declaration is here}} +// expected-error@+5 {{function declared 'stdcall' here was previously declared without calling convention}} +#endif +void nonvariadic1(int a, int b, int c); +void __attribute__((stdcall)) nonvariadic1(int a, int b, int c); +void nonvariadic2(int a, int b, int c); +void __attribute__((stdcall)) nonvariadic2(int a, int b, int c) { } + +// expected-note@+2 {{previous declaration is here}} +// expected-error@+2 {{function declared 'stdcall' here was previously declared without calling convention}} +void variadic(int a, ...); +void __attribute__((stdcall)) variadic(int a, ...); + +#ifdef MRTD +// expected-note@+3 {{previous definition is here}} +// expected-error@+3 {{redefinition of 'a' with a different type: 'void ((*))(int, int) __attribute__((cdecl))' vs 'void (*)(int, int) __attribute__((stdcall))'}} +#endif +extern void (*a)(int, int); +__attribute__((cdecl)) extern void (*a)(int, int); + +extern void (*b)(int, ...); +__attribute__((cdecl)) extern void (*b)(int, ...); + +#ifndef MRTD +// expected-note@+3 {{previous definition is here}} +// expected-error@+3 {{redefinition of 'c' with a different type: 'void ((*))(int, int) __attribute__((stdcall))' vs 'void (*)(int, int)'}} +#endif +extern void (*c)(int, int); +__attribute__((stdcall)) extern void (*c)(int, int); + +// expected-note@+2 {{previous definition is here}} +// expected-error@+2 {{redefinition of 'd' with a different type: 'void ((*))(int, ...) __attribute__((stdcall))' vs 'void (*)(int, ...)'}} +extern void (*d)(int, ...); +__attribute__((stdcall)) extern void (*d)(int, ...); |