| Daniel Dunbar | a572887 | 2009-12-15 20:14:24 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s | 
| Sebastian Redl | ddf7e99 | 2009-02-08 10:28:44 +0000 | [diff] [blame] | 2 |  | 
| Chris Lattner | 0442108 | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 3 | void f(int i, int j, int k = 3); | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 4 | void f(int i, int j, int k); | 
| Chris Lattner | 0442108 | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 5 | void f(int i, int j = 2, int k); | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 6 | void f(int i, int j, int k); | 
| Chris Lattner | 0442108 | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 7 | void f(int i = 1, int j, int k); | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 8 | void f(int i, int j, int k); | 
| Chris Lattner | 0442108 | 2008-04-08 04:40:51 +0000 | [diff] [blame] | 9 |  | 
|  | 10 | void i() | 
|  | 11 | { | 
|  | 12 | f(); | 
|  | 13 | f(0); | 
|  | 14 | f(0, 1); | 
|  | 15 | f(0, 1, 2); | 
|  | 16 | } | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 17 |  | 
|  | 18 |  | 
| Chris Lattner | d84aac1 | 2010-02-22 00:40:25 +0000 | [diff] [blame] | 19 | int f1(int i,          // expected-note {{previous declaration is here}} | 
|  | 20 | int i, int j) { // expected-error {{redefinition of parameter 'i'}} | 
| Chris Lattner | 8123a95 | 2008-04-10 02:22:51 +0000 | [diff] [blame] | 21 | i = 17; | 
|  | 22 | return j; | 
|  | 23 | } | 
|  | 24 |  | 
|  | 25 | int x; | 
|  | 26 | void g(int x, int y = x); // expected-error {{default argument references parameter 'x'}} | 
|  | 27 |  | 
| Chris Lattner | 9e97955 | 2008-04-12 23:52:44 +0000 | [diff] [blame] | 28 | void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}} | 
| Douglas Gregor | 6d6eb57 | 2008-05-07 04:49:29 +0000 | [diff] [blame] | 29 |  | 
| Douglas Gregor | 30c5436 | 2008-11-03 22:47:57 +0000 | [diff] [blame] | 30 | class X { | 
| Richard Smith | a85cf39 | 2012-04-05 01:13:04 +0000 | [diff] [blame] | 31 | void f(X* x = this); // expected-error{{invalid use of 'this' outside of a non-static member function}} | 
| Douglas Gregor | 3996f23 | 2008-11-04 13:41:56 +0000 | [diff] [blame] | 32 |  | 
|  | 33 | void g() { | 
|  | 34 | int f(X* x = this); // expected-error{{default argument references 'this'}} | 
|  | 35 | } | 
| Douglas Gregor | 30c5436 | 2008-11-03 22:47:57 +0000 | [diff] [blame] | 36 | }; | 
| Douglas Gregor | 69497c3 | 2008-12-16 00:08:34 +0000 | [diff] [blame] | 37 |  | 
|  | 38 | // C++ [dcl.fct.default]p6 | 
|  | 39 | class C { | 
|  | 40 | static int x; | 
|  | 41 | void f(int i = 3); // expected-note{{previous definition is here}} | 
|  | 42 | void g(int i, int j = x); | 
|  | 43 |  | 
|  | 44 | void h(); | 
|  | 45 | }; | 
|  | 46 | void C::f(int i = 3) // expected-error{{redefinition of default argument}} | 
|  | 47 | { } | 
|  | 48 |  | 
|  | 49 | void C::g(int i = 88, int j) {} | 
|  | 50 |  | 
|  | 51 | void C::h() { | 
|  | 52 | g(); // okay | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | // C++ [dcl.fct.default]p9 | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 56 | struct Y { | 
| Douglas Gregor | 69497c3 | 2008-12-16 00:08:34 +0000 | [diff] [blame] | 57 | int a; | 
| Richard Smith | a85cf39 | 2012-04-05 01:13:04 +0000 | [diff] [blame] | 58 | int mem1(int i = a); // expected-error{{invalid use of non-static data member 'a'}} | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 59 | int mem2(int i = b); // OK; use Y::b | 
| Douglas Gregor | 0a59acb | 2008-12-16 00:38:16 +0000 | [diff] [blame] | 60 | int mem3(int i); | 
|  | 61 | int mem4(int i); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 62 |  | 
|  | 63 | struct Nested { | 
|  | 64 | int mem5(int i = b, // OK; use Y::b | 
|  | 65 | int j = c, // OK; use Y::Nested::c | 
|  | 66 | int k = j, // expected-error{{default argument references parameter 'j'}} | 
| Richard Smith | a85cf39 | 2012-04-05 01:13:04 +0000 | [diff] [blame] | 67 | int l = a,  // expected-error{{invalid use of non-static data member 'a'}} | 
|  | 68 | Nested* self = this, // expected-error{{invalid use of 'this' outside of a non-static member function}} | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 69 | int m); // expected-error{{missing default argument on parameter 'm'}} | 
|  | 70 | static int c; | 
| Douglas Gregor | d54eb44 | 2010-10-12 16:25:54 +0000 | [diff] [blame] | 71 | Nested(int i = 42); | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 72 | }; | 
|  | 73 |  | 
| Douglas Gregor | d54eb44 | 2010-10-12 16:25:54 +0000 | [diff] [blame] | 74 | int mem7(Nested n = Nested()); | 
|  | 75 |  | 
| Douglas Gregor | 69497c3 | 2008-12-16 00:08:34 +0000 | [diff] [blame] | 76 | static int b; | 
|  | 77 | }; | 
| Douglas Gregor | 0a59acb | 2008-12-16 00:38:16 +0000 | [diff] [blame] | 78 |  | 
|  | 79 | int Y::mem3(int i = b) { return i; } // OK; use X::b | 
|  | 80 |  | 
| Richard Smith | a85cf39 | 2012-04-05 01:13:04 +0000 | [diff] [blame] | 81 | int Y::mem4(int i = a) // expected-error{{invalid use of non-static data member 'a'}} | 
| Douglas Gregor | 0a59acb | 2008-12-16 00:38:16 +0000 | [diff] [blame] | 82 | { return i; } | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 83 |  | 
|  | 84 |  | 
|  | 85 | // Try to verify that default arguments interact properly with copy | 
|  | 86 | // constructors. | 
|  | 87 | class Z { | 
|  | 88 | public: | 
| John McCall | b1622a1 | 2010-01-06 09:43:14 +0000 | [diff] [blame] | 89 | Z(Z&, int i = 17); // expected-note 3 {{candidate constructor}} | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 90 |  | 
|  | 91 | void f(Z& z) { | 
|  | 92 | Z z2;    // expected-error{{no matching constructor for initialization}} | 
|  | 93 | Z z3(z); | 
|  | 94 | } | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 95 |  | 
|  | 96 | void test_Z(const Z& z) { | 
| John McCall | 7c2342d | 2010-03-10 11:27:22 +0000 | [diff] [blame] | 97 | Z z2(z); // expected-error{{no matching constructor for initialization of 'Z'}} | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 98 | } | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 99 | }; | 
|  | 100 |  | 
|  | 101 | void test_Z(const Z& z) { | 
| John McCall | 7c2342d | 2010-03-10 11:27:22 +0000 | [diff] [blame] | 102 | Z z2(z); // expected-error{{no matching constructor for initialization of 'Z'}} | 
| Douglas Gregor | 72b505b | 2008-12-16 21:30:33 +0000 | [diff] [blame] | 103 | } | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 104 |  | 
|  | 105 | struct ZZ { | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 106 | static ZZ g(int = 17); | 
|  | 107 |  | 
| Douglas Gregor | a41a8c5 | 2010-04-22 00:20:18 +0000 | [diff] [blame] | 108 | void f(ZZ z = g()); // expected-error{{no matching constructor for initialization}} \ | 
|  | 109 | // expected-note{{passing argument to parameter 'z' here}} | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 110 |  | 
| John McCall | b1622a1 | 2010-01-06 09:43:14 +0000 | [diff] [blame] | 111 | ZZ(ZZ&, int = 17); // expected-note{{candidate constructor}} | 
| Douglas Gregor | 61366e9 | 2008-12-24 00:01:03 +0000 | [diff] [blame] | 112 | }; | 
| Anders Carlsson | 5e300d1 | 2009-06-12 16:51:40 +0000 | [diff] [blame] | 113 |  | 
|  | 114 | // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325 | 
|  | 115 | class C2 { | 
|  | 116 | static void g(int = f()); // expected-error{{use of default argument to function 'f' that is declared later in class 'C2'}} | 
|  | 117 | static int f(int = 10); // expected-note{{default argument declared here}} | 
|  | 118 | }; | 
| Eli Friedman | d33133c | 2009-07-22 21:45:50 +0000 | [diff] [blame] | 119 |  | 
|  | 120 | // Make sure we actually parse the default argument for an inline definition | 
|  | 121 | class XX { | 
|  | 122 | void A(int length = -1 ) {  } | 
|  | 123 | void B() { A(); } | 
|  | 124 | }; |