John McCall cbc038a6c3 ANSI C requires that a call to an unprototyped function type succeed
if the definition has a non-variadic prototype with compatible
parameters.  Therefore, the default rule for such calls must be to
use a non-variadic convention.  Achieve this by casting the callee to
the function type with which it is required to be compatible, unless
the target specifically opts out and insists that unprototyped calls
should use the variadic rules.  The only case of that I'm aware of is
the x86-64 convention, which passes arguments the same way in both
cases but also sets a small amount of extra information;  here we seek
to maintain compatibility with GCC, which does set this when calling
an unprototyped function.

Addresses PR10810 and PR10713.

llvm-svn: 140241
2011-09-21 08:08:30 +00:00

68 lines
1.4 KiB
C

// RUN: %clang_cc1 %s -triple i386-unknown-unknown -emit-llvm -o - -verify | FileCheck %s
int g();
int foo(int i) {
return g(i);
}
int g(int i) {
return g(i);
}
// rdar://6110827
typedef void T(void);
void test3(T f) {
f();
}
int a(int);
int a() {return 1;}
void f0() {}
// CHECK: define void @f0()
void f1();
void f2(void) {
// CHECK: call void bitcast (void ()* @f1 to void (i32, i32, i32)*)(i32 1, i32 2, i32 3)
f1(1, 2, 3);
}
// CHECK: define void @f1()
void f1() {}
// CHECK: define {{.*}} @f3{{\(\)|\(.*sret.*\)}}
struct foo { int X, Y, Z; } f3() {
while (1) {}
}
// PR4423 - This shouldn't crash in codegen
void f4() {}
void f5() { f4(42); } //expected-warning {{too many arguments}}
// Qualifiers on parameter types shouldn't make a difference.
static void f6(const float f, const float g) {
}
void f7(float f, float g) {
f6(f, g);
// CHECK: define void @f7(float{{.*}}, float{{.*}})
// CHECK: call void @f6(float{{.*}}, float{{.*}})
}
// PR6911 - incomplete function types
struct Incomplete;
void f8_callback(struct Incomplete);
void f8_user(void (*callback)(struct Incomplete));
void f8_test() {
f8_user(&f8_callback);
// CHECK: define void @f8_test()
// CHECK: call void @f8_user({{.*}}* bitcast (void ()* @f8_callback to {{.*}}*))
// CHECK: declare void @f8_user({{.*}}*)
// CHECK: declare void @f8_callback()
}
// PR10204: don't crash
static void test9_helper(void) {}
void test9() {
(void) test9_helper;
}