1 // RUN: %clang_cc1 -std=c++03 -verify %s
2 // RUN: %clang_cc1 -std=c++11 -verify %s
3 
4 __builtin_va_list ap;
5 
6 class string;
f(const string & s,...)7 void f(const string& s, ...) {  // expected-note {{parameter of type 'const string &' is declared here}}
8   __builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}}
9 }
10 
g(register int i,...)11 void g(register int i, ...) { // expected-warning 0-1{{deprecated}}
12   __builtin_va_start(ap, i); // UB in C, OK in C++
13 }
14 
15 // Don't crash when there is no last parameter.
no_params(...)16 void no_params(...) {
17   int a;
18   __builtin_va_start(ap, a); // expected-warning {{second argument to 'va_start' is not the last named parameter}}
19 }
20 
21 // Reject this. The __builtin_va_start would execute in Foo's non-variadic
22 // default ctor.
record_context(int a,...)23 void record_context(int a, ...) {
24   struct Foo {
25     // expected-error@+2 {{'va_start' cannot be used outside a function}}
26     // expected-error@+1 {{default argument references parameter 'a'}}
27     void meth(int a, int b = (__builtin_va_start(ap, a), 0)) {}
28   };
29 }
30 
31 #if __cplusplus >= 201103L
32 // We used to have bugs identifying the correct enclosing function scope in a
33 // lambda.
34 
fixed_lambda_varargs_function(int a,...)35 void fixed_lambda_varargs_function(int a, ...) {
36   [](int b) {
37     __builtin_va_start(ap, b); // expected-error {{'va_start' used in function with fixed args}}
38   }(42);
39 }
varargs_lambda_fixed_function(int a)40 void varargs_lambda_fixed_function(int a) {
41   [](int b, ...) {
42     __builtin_va_start(ap, b); // correct
43   }(42);
44 }
45 
__anon862693f90302(int f) 46 auto fixed_lambda_global = [](int f) {
47   __builtin_va_start(ap, f); // expected-error {{'va_start' used in function with fixed args}}
48 };
__anon862693f90402(int f, ...) 49 auto varargs_lambda_global = [](int f, ...) {
50   __builtin_va_start(ap, f); // correct
51 };
52 
record_member_init(int a,...)53 void record_member_init(int a, ...) {
54   struct Foo {
55     int a = 0;
56     // expected-error@+1 {{'va_start' cannot be used outside a function}}
57     int b = (__builtin_va_start(ap, a), 0);
58   };
59 }
60 #endif
61