summaryrefslogtreecommitdiff
path: root/test/Sema
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-08-27 23:08:25 +0000
committerReid Kleckner <reid@kleckner.net>2013-08-27 23:08:25 +0000
commitef072033876e295ec5d3402f8730a3ae358ad815 (patch)
treec13128c478d6635eb264c1f2f357a12a4ca53b58 /test/Sema
parenta7f6a94c1bae840c51351cd37cc247ae75f8e649 (diff)
downloadclang-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.c4
-rw-r--r--test/Sema/mrtd.c40
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, ...);