1 // RUN: %clang_cc1 -std=c++2b -fsyntax-only                    -verify=cxx2b,new %s
2 // RUN: %clang_cc1 -std=c++2b -fsyntax-only -fms-compatibility -verify=cxx2b,old %s
3 // RUN: %clang_cc1 -std=c++20 -fsyntax-only                    -verify=cxx20,old %s
4 
5 // FIXME: This is a test for a temporary workaround where we disable simpler implicit moves
6 //        in the STL when compiling with -fms-compatibility, because of issues with the
7 //        implementation there.
8 //        Feel free to delete this file when the workaround is not needed anymore.
9 
10 #if __INCLUDE_LEVEL__ == 0
11 
12 #if __cpluscplus > 202002L && __cpp_implicit_move < 202011L
13 #error "__cpp_implicit_move not defined correctly"
14 #endif
15 
16 struct nocopy {
17   nocopy(nocopy &&);
18 };
19 
mt1(int && x)20 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)21 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
mt3(nocopy x)22 nocopy mt3(nocopy x) { return x; }
23 
24 namespace {
mt1(int && x)25 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)26 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
mt3(nocopy x)27 nocopy mt3(nocopy x) { return x; }
28 } // namespace
29 
30 namespace foo {
mt1(int && x)31 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)32 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
33 namespace std {
mt1(int && x)34 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)35 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
mt3(nocopy x)36 nocopy mt3(nocopy x) { return x; }
37 } // namespace std
38 } // namespace foo
39 
40 namespace std {
41 
mt1(int && x)42 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)43 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
mt3(nocopy x)44 nocopy mt3(nocopy x) { return x; }
45 
46 namespace {
mt1(int && x)47 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)48 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
mt3(nocopy x)49 nocopy mt3(nocopy x) { return x; }
50 } // namespace
51 
52 namespace foo {
mt1(int && x)53 int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
mt2(int && x)54 int &mt2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
mt3(nocopy x)55 nocopy mt3(nocopy x) { return x; }
56 } // namespace foo
57 
58 } // namespace std
59 
60 #include __FILE__
61 
62 #define SYSTEM
63 #include __FILE__
64 
65 #elif !defined(SYSTEM)
66 
ut1(int && x)67 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)68 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)69 nocopy ut3(nocopy x) { return x; }
70 
71 namespace {
ut1(int && x)72 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)73 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)74 nocopy ut3(nocopy x) { return x; }
75 } // namespace
76 
77 namespace foo {
ut1(int && x)78 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)79 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)80 nocopy ut3(nocopy x) { return x; }
81 namespace std {
ut1(int && x)82 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)83 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)84 nocopy ut3(nocopy x) { return x; }
85 } // namespace std
86 } // namespace foo
87 
88 namespace std {
89 
ut1(int && x)90 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)91 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)92 nocopy ut3(nocopy x) { return x; }
93 
94 namespace {
ut1(int && x)95 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)96 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)97 nocopy ut3(nocopy x) { return x; }
98 } // namespace
99 
100 namespace foo {
ut1(int && x)101 int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
ut2(int && x)102 int &ut2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
ut3(nocopy x)103 nocopy ut3(nocopy x) { return x; }
104 } // namespace foo
105 
106 } // namespace std
107 
108 #else
109 
110 #pragma GCC system_header
111 
st1(int && x)112 int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
st2(int && x)113 int &st2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
st3(nocopy x)114 nocopy st3(nocopy x) { return x; }
115 
116 namespace {
st1(int && x)117 int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
st2(int && x)118 int &st2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
st3(nocopy x)119 nocopy st3(nocopy x) { return x; }
120 } // namespace
121 
122 namespace foo {
st1(int && x)123 int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
st2(int && x)124 int &st2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
st3(nocopy x)125 nocopy st3(nocopy x) { return x; }
126 namespace std {
st1(int && x)127 int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
st2(int && x)128 int &st2(int &&x) { return x; }  // cxx2b-error {{cannot bind to a temporary}}
st3(nocopy x)129 nocopy st3(nocopy x) { return x; }
130 } // namespace std
131 } // namespace foo
132 
133 namespace std {
134 
st1(int && x)135 int &&st1(int &&x) { return x; } // old-error {{cannot bind to lvalue}}
st2(int && x)136 int &st2(int &&x) { return x; }  // new-error {{cannot bind to a temporary}}
st3(nocopy x)137 nocopy st3(nocopy x) { return x; }
138 
139 namespace {
st1(int && x)140 int &&st1(int &&x) { return x; } // old-error {{cannot bind to lvalue}}
st2(int && x)141 int &st2(int &&x) { return x; }  // new-error {{cannot bind to a temporary}}
st3(nocopy x)142 nocopy st3(nocopy x) { return x; }
143 } // namespace
144 
145 namespace foo {
st1(int && x)146 int &&st1(int &&x) { return x; } // old-error {{cannot bind to lvalue}}
st2(int && x)147 int &st2(int &&x) { return x; }  // new-error {{cannot bind to a temporary}}
st3(nocopy x)148 nocopy st3(nocopy x) { return x; }
149 } // namespace foo
150 
151 } // namespace std
152 
153 #endif
154