
This builtin is supported by GCC and is a way to improve diagnostic behavior for va_start in C23 mode. C23 no longer requires a second argument to the va_start macro in support of variadic functions with no leading parameters. However, we still want to diagnose passing more than two arguments, or diagnose when passing something other than the last parameter in the variadic function. This also updates the freestanding <stdarg.h> header to use the new builtin, same as how GCC works. Fixes #124031
35 lines
947 B
C
35 lines
947 B
C
// RUN: %clang_cc1 -triple i386-unknown-unknown -std=c2y -emit-llvm -o - %s | FileCheck %s
|
|
|
|
// PR6433 - Don't crash on va_arg(typedef).
|
|
typedef double gdouble;
|
|
void focus_changed_cb (void) {
|
|
__builtin_va_list pa;
|
|
double mfloat;
|
|
mfloat = __builtin_va_arg((pa), gdouble);
|
|
}
|
|
|
|
void vararg(int, ...);
|
|
void function_as_vararg(void) {
|
|
// CHECK: define {{.*}}function_as_vararg
|
|
// CHECK-NOT: llvm.trap
|
|
vararg(0, focus_changed_cb);
|
|
}
|
|
|
|
void vla(int n, ...)
|
|
{
|
|
__builtin_va_list ap;
|
|
void *p;
|
|
p = __builtin_va_arg(ap, typeof (int (*)[++n])); // CHECK: add nsw i32 {{.*}}, 1
|
|
}
|
|
|
|
// Ensure that __builtin_va_start(list, 0) and __builtin_c23_va_start(list)
|
|
// have the same codegen.
|
|
void noargs(...) {
|
|
__builtin_va_list list;
|
|
// CHECK: %list = alloca ptr
|
|
__builtin_va_start(list, 0);
|
|
// CHECK-NEXT: call void @llvm.va_start.p0(ptr %list)
|
|
__builtin_c23_va_start(list);
|
|
// CHECK-NEXT: call void @llvm.va_start.p0(ptr %list)
|
|
}
|