Reid Kleckner | f1deb83 | 2017-05-04 19:51:05 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++03 -verify %s |
| 2 | // RUN: %clang_cc1 -std=c++11 -verify %s |
| 3 | |
| 4 | __builtin_va_list ap; |
Aaron Ballman | 1de59c5 | 2016-04-24 13:30:21 +0000 | [diff] [blame] | 5 | |
| 6 | class string; |
| 7 | void f(const string& s, ...) { // expected-note {{parameter of type 'const string &' is declared here}} |
Aaron Ballman | 1de59c5 | 2016-04-24 13:30:21 +0000 | [diff] [blame] | 8 | __builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}} |
| 9 | } |
| 10 | |
Richard Smith | 4d629b8 | 2017-11-01 23:38:37 +0000 | [diff] [blame] | 11 | void g(register int i, ...) { // expected-warning 0-1{{deprecated}} |
Reid Kleckner | f1deb83 | 2017-05-04 19:51:05 +0000 | [diff] [blame] | 12 | __builtin_va_start(ap, i); // UB in C, OK in C++ |
Aaron Ballman | 1de59c5 | 2016-04-24 13:30:21 +0000 | [diff] [blame] | 13 | } |
Reid Kleckner | f1deb83 | 2017-05-04 19:51:05 +0000 | [diff] [blame] | 14 | |
| 15 | // Don't crash when there is no last parameter. |
| 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. |
| 23 | void record_context(int a, ...) { |
| 24 | struct Foo { |
| 25 | // expected-error@+1 {{'va_start' cannot be used outside a function}} |
| 26 | void meth(int a, int b = (__builtin_va_start(ap, a), 0)) {} |
| 27 | }; |
| 28 | } |
| 29 | |
| 30 | #if __cplusplus >= 201103L |
| 31 | // We used to have bugs identifying the correct enclosing function scope in a |
| 32 | // lambda. |
| 33 | |
| 34 | void fixed_lambda_varargs_function(int a, ...) { |
| 35 | [](int b) { |
| 36 | __builtin_va_start(ap, b); // expected-error {{'va_start' used in function with fixed args}} |
| 37 | }(42); |
| 38 | } |
| 39 | void varargs_lambda_fixed_function(int a) { |
| 40 | [](int b, ...) { |
| 41 | __builtin_va_start(ap, b); // correct |
| 42 | }(42); |
| 43 | } |
| 44 | |
| 45 | auto fixed_lambda_global = [](int f) { |
| 46 | __builtin_va_start(ap, f); // expected-error {{'va_start' used in function with fixed args}} |
| 47 | }; |
| 48 | auto varargs_lambda_global = [](int f, ...) { |
| 49 | __builtin_va_start(ap, f); // correct |
| 50 | }; |
| 51 | |
| 52 | void record_member_init(int a, ...) { |
| 53 | struct Foo { |
| 54 | int a = 0; |
| 55 | // expected-error@+1 {{'va_start' cannot be used outside a function}} |
| 56 | int b = (__builtin_va_start(ap, a), 0); |
| 57 | }; |
| 58 | } |
| 59 | #endif |