blob: f2f53dc2001fd0e04b15c9a5d2fe04ad66892606 [file] [log] [blame]
Reid Klecknerf1deb832017-05-04 19:51:05 +00001// RUN: %clang_cc1 -std=c++03 -verify %s
2// RUN: %clang_cc1 -std=c++11 -verify %s
3
4__builtin_va_list ap;
Aaron Ballman1de59c52016-04-24 13:30:21 +00005
6class string;
7void f(const string& s, ...) { // expected-note {{parameter of type 'const string &' is declared here}}
Aaron Ballman1de59c52016-04-24 13:30:21 +00008 __builtin_va_start(ap, s); // expected-warning {{passing an object of reference type to 'va_start' has undefined behavior}}
9}
10
Richard Smith4d629b82017-11-01 23:38:37 +000011void g(register int i, ...) { // expected-warning 0-1{{deprecated}}
Reid Klecknerf1deb832017-05-04 19:51:05 +000012 __builtin_va_start(ap, i); // UB in C, OK in C++
Aaron Ballman1de59c52016-04-24 13:30:21 +000013}
Reid Klecknerf1deb832017-05-04 19:51:05 +000014
15// Don't crash when there is no last parameter.
16void 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.
23void 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
34void 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}
39void varargs_lambda_fixed_function(int a) {
40 [](int b, ...) {
41 __builtin_va_start(ap, b); // correct
42 }(42);
43}
44
45auto fixed_lambda_global = [](int f) {
46 __builtin_va_start(ap, f); // expected-error {{'va_start' used in function with fixed args}}
47};
48auto varargs_lambda_global = [](int f, ...) {
49 __builtin_va_start(ap, f); // correct
50};
51
52void 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