512 lines · cpp
1// RUN: %clang_cc1 -std=c++23 -triple x86_64-linux-gnu -fcxx-exceptions -ast-dump %s \2// RUN: | FileCheck -strict-whitespace %s3 4namespace P2718R0 {5 6// Test basic7struct A {8 int a[3] = {1, 2, 3};9 A() {}10 ~A() {}11 const int *begin() const { return a; }12 const int *end() const { return a + 3; }13 A& r() { return *this; }14 A g() { return A(); }15};16 17A g() { return A(); }18const A &f1(const A &t) { return t; }19 20void test1() {21 [[maybe_unused]] int sum = 0;22 // CHECK: FunctionDecl {{.*}} test1 'void ()'23 // CHECK: | `-CXXForRangeStmt {{.*}}24 // CHECK-NEXT: | |-<<<NULL>>>25 // CHECK-NEXT: | |-DeclStmt {{.*}}26 // CHECK-NEXT: | | `-VarDecl {{.*}} implicit used __range1 'const A &' cinit27 // CHECK-NEXT: | | `-ExprWithCleanups {{.*}} 'const A' lvalue28 // CHECK-NEXT: | | `-CallExpr {{.*}} 'const A' lvalue29 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const A &(*)(const A &)' <FunctionToPointerDecay>30 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const A &(const A &)' lvalue Function {{.*}} 'f1' 'const A &(const A &)'31 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'const A &'32 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>33 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})34 // CHECK-NEXT: | | `-CallExpr {{.*}} 'A'35 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'A (*)()' <FunctionToPointerDecay>36 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'A ()' lvalue Function {{.*}} 'g' 'A ()'37 for (auto e : f1(g()))38 sum += e;39}40 41struct B : A {};42int (&f(const A *))[3];43const A *g(const A &);44void bar(int) {}45 46void test2() {47 // CHECK: FunctionDecl {{.*}} test2 'void ()'48 // CHECK: | `-CXXForRangeStmt {{.*}}49 // CHECK-NEXT: | |-<<<NULL>>>50 // CHECK-NEXT: | |-DeclStmt {{.*}}51 // CHECK-NEXT: | | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit52 // CHECK-NEXT: | | `-ExprWithCleanups {{.*}} 'int[3]' lvalue53 // CHECK-NEXT: | | `-CallExpr {{.*}} 'int[3]' lvalue54 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'int (&(*)(const A *))[3]' <FunctionToPointerDecay>55 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'int (&(const A *))[3]' lvalue Function {{.*}} 'f' 'int (&(const A *))[3]'56 // CHECK-NEXT: | | `-CallExpr {{.*}} 'const A *'57 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const A *(*)(const A &)' <FunctionToPointerDecay>58 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const A *(const A &)' lvalue Function {{.*}} 'g' 'const A *(const A &)'59 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A' lvalue <DerivedToBase (A)>60 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const B' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'61 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const B' <NoOp>62 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'B' (CXXTemporary {{.*}})63 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'B' 'void () noexcept(false)' zeroing64 for (auto e : f(g(B())))65 bar(e);66}67 68// Test discard statement.69struct LockGuard {70 LockGuard() {}71 ~LockGuard() {}72};73 74void test3() {75 int v[] = {42, 17, 13};76 77 // CHECK: FunctionDecl {{.*}} test3 'void ()'78 // CHECK: -CXXForRangeStmt {{.*}}79 // CHECK-NEXT: |-<<<NULL>>>80 // CHECK-NEXT: |-DeclStmt {{.*}}81 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit82 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue83 // CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','84 // CHECK-NEXT: | |-CXXStaticCastExpr {{.*}} 'void' static_cast<void> <ToVoid>85 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'86 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})87 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'88 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'89 for ([[maybe_unused]] int x : static_cast<void>(LockGuard()), v)90 LockGuard guard;91 92 // CHECK: -CXXForRangeStmt {{.*}}93 // CHECK-NEXT: |-<<<NULL>>>94 // CHECK-NEXT: |-DeclStmt {{.*}}95 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit96 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue97 // CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','98 // CHECK-NEXT: | |-CStyleCastExpr {{.*}} 'void' <ToVoid>99 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'100 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})101 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'102 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'103 for ([[maybe_unused]] int x : (void)LockGuard(), v)104 LockGuard guard;105 106 // CHECK: -CXXForRangeStmt {{.*}}107 // CHECK-NEXT: |-<<<NULL>>>108 // CHECK-NEXT: |-DeclStmt {{.*}}109 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit110 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue111 // CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','112 // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'113 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})114 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'115 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'116 for ([[maybe_unused]] int x : LockGuard(), v)117 LockGuard guard;118}119 120// Test default arg121int (&default_arg_fn(const A & = A()))[3];122void test4() {123 124 // CHECK: FunctionDecl {{.*}} test4 'void ()'125 // CHECK: -CXXForRangeStmt {{.*}}126 // CHECK-NEXT: |-<<<NULL>>>127 // CHECK-NEXT: |-DeclStmt {{.*}}128 // CHECK-NEXT: | `-VarDecl{{.*}} implicit used __range1 'int (&)[3]' cinit129 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue130 // CHECK-NEXT: | `-CallExpr {{.*}} 'int[3]' lvalue131 // CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'int (&(*)(const A &))[3]' <FunctionToPointerDecay>132 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int (&(const A &))[3]' lvalue Function {{.*}} 'default_arg_fn' 'int (&(const A &))[3]'133 // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const A' lvalue has rewritten init134 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'135 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>136 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})137 // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'A' 'void ()'138 for (auto e : default_arg_fn())139 bar(e);140}141 142struct DefaultA {143 DefaultA() {}144 ~DefaultA() {}145};146 147A foo(const A&, const DefaultA &Default = DefaultA()) {148 return A();149}150 151void test5() {152 // CHECK: FunctionDecl {{.*}} test5 'void ()'153 // CHECK: -CXXForRangeStmt {{.*}}154 // CHECK-NEXT: |-<<<NULL>>>155 // CHECK-NEXT: |-DeclStmt {{.*}}156 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit157 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue158 // CHECK-NEXT: | `-CallExpr {{.*}} 'int[3]' lvalue159 // CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'int (&(*)(const A &))[3]' <FunctionToPointerDecay>160 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int (&(const A &))[3]' lvalue Function {{.*}} 'default_arg_fn' 'int (&(const A &))[3]'161 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'162 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>163 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A'164 // CHECK-NEXT: | `-CallExpr {{.*}} 'A'165 // CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'A (*)(const A &, const DefaultA &)' <FunctionToPointerDecay>166 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'A (const A &, const DefaultA &)' lvalue Function {{.*}} 'foo' 'A (const A &, const DefaultA &)'167 // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'168 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>169 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'A'170 // CHECK-NEXT: | | `-CallExpr {{.*}} 'A'171 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'A (*)(const A &, const DefaultA &)' <FunctionToPointerDecay>172 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'A (const A &, const DefaultA &)' lvalue Function {{.*}} 'foo' 'A (const A &, const DefaultA &)'173 // CHECK-NEXT: | | |-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'174 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>175 // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'A'176 // CHECK-NEXT: | | | `-CallExpr {{.*}} 'A'177 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'A (*)(const A &, const DefaultA &)' <FunctionToPointerDecay>178 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'A (const A &, const DefaultA &)' lvalue Function {{.*}} 'foo' 'A (const A &, const DefaultA &)'179 // CHECK-NEXT: | | | |-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'180 // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>181 // CHECK-NEXT: | | | | `-CXXBindTemporaryExpr {{.*}} 'A'182 // CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'A' 'void ()'183 // CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init184 // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'185 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>186 // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})187 // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'188 // CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init189 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'190 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>191 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})192 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'193 // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init194 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'195 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>196 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})197 // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'198 for (auto e : default_arg_fn(foo(foo(foo(A())))))199 bar(e);200}201 202struct C : public A {203 C() {}204 C(int, const C &, const DefaultA & = DefaultA()) {}205};206 207void test6() {208 // CHECK: FunctionDecl {{.*}} test6 'void ()'209 // CHECK: -CXXForRangeStmt {{.*}}210 // CHECK-NEXT: |-<<<NULL>>>211 // CHECK-NEXT: |-DeclStmt {{.*}}212 // CHECK-NEXT: | `-VarDecl {{.*}} col:17 implicit used __range1 'C &&' cinit213 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'C' xvalue214 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'C' xvalue extended by Var {{.*}} '__range1' 'C &&'215 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'C'216 // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void (int, const C &, const DefaultA &)'217 // CHECK-NEXT: | |-IntegerLiteral {{.*}}'int' 0218 // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'const C' lvalue extended by Var {{.*}} '__range1' 'C &&'219 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const C' <NoOp>220 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'C'221 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void (int, const C &, const DefaultA &)'222 // CHECK-NEXT: | | |-IntegerLiteral {{.*}} 'int' 0223 // CHECK-NEXT: | | |-MaterializeTemporaryExpr {{.*}} 'const C' lvalue extended by Var {{.*}} '__range1' 'C &&'224 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const C' <NoOp>225 // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'C'226 // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void (int, const C &, const DefaultA &)'227 // CHECK-NEXT: | | | |-IntegerLiteral {{.*}} 'int' 0228 // CHECK-NEXT: | | | |-MaterializeTemporaryExpr {{.*}} 'const C' lvalue extended by Var {{.*}} '__range1' 'C &&'229 // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const C' <NoOp>230 // CHECK-NEXT: | | | | `-CXXBindTemporaryExpr {{.*}} 'C'231 // CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void ()'232 // CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init233 // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'234 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>235 // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})236 // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'237 // CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init238 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'239 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>240 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})241 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'242 // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init243 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'244 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>245 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})246 // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'247 for (auto e : C(0, C(0, C(0, C()))))248 bar(e);249}250 251// Test member call252void test7() {253 // CHECK: FunctionDecl {{.*}} test7 'void ()'254 // CHECK: -CXXForRangeStmt {{.*}}255 // CHECK-NEXT: |-<<<NULL>>>256 // CHECK-NEXT: |-DeclStmt {{.*}}257 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'A &&' cinit258 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'A' xvalue259 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'260 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})261 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'262 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}263 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue264 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}265 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'266 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})267 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'268 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}269 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue270 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}271 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'272 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})273 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'274 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}275 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue276 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}277 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'278 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})279 // CHECK-NEXT: | `-CallExpr {{.*}} 'A'280 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'A (*)()' <FunctionToPointerDecay>281 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'A ()' lvalue Function {{.*}} 'g' 'A ()'282 for (auto e : g().r().g().r().g().r().g())283 bar(e);284}285 286// Test basic && dependent context287template <typename T> T dg() { return T(); }288template <typename T> const T &df1(const T &t) { return t; }289 290void test8() {291 [[maybe_unused]] int sum = 0;292 // CHECK: FunctionDecl {{.*}} test8 'void ()'293 // CHECK: -CXXForRangeStmt {{.*}}294 // CHECK-NEXT: |-<<<NULL>>>295 // CHECK-NEXT: |-DeclStmt {{.*}}296 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'const P2718R0::A &' cinit297 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'const P2718R0::A' lvalue298 // CHECK-NEXT: | `-CallExpr {{.*}} 'const P2718R0::A' lvalue299 // CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'const P2718R0::A &(*)(const P2718R0::A &)' <FunctionToPointerDecay>300 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const P2718R0::A &(const P2718R0::A &)' lvalue Function {{.*}} 'df1' 'const P2718R0::A &(const P2718R0::A &)' (FunctionTemplate {{.*}} 'df1')301 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'const P2718R0::A &'302 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const P2718R0::A' <NoOp>303 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'P2718R0::A' (CXXTemporary {{.*}})304 // CHECK-NEXT: | `-CallExpr {{.*}} 'P2718R0::A'305 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'P2718R0::A (*)()' <FunctionToPointerDecay>306 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'P2718R0::A ()' lvalue Function {{.*}} 'dg' 'P2718R0::A ()' (FunctionTemplate {{.*}} 'dg')307 for (auto e : df1(dg<A>()))308 sum += e;309}310 311template <typename T> int (&df2(const T *))[3];312const A *dg2(const A &);313 314void test9() {315 // CHECK: FunctionDecl {{.*}} test9 'void ()'316 // CHECK: -CXXForRangeStmt {{.*}}317 // CHECK-NEXT: |-<<<NULL>>>318 // CHECK-NEXT: |-DeclStmt {{.*}}319 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit320 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue321 // CHECK-NEXT: | `-CallExpr {{.*}} 'int[3]' lvalue322 // CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'int (&(*)(const P2718R0::A *))[3]' <FunctionToPointerDecay>323 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int (&(const P2718R0::A *))[3]' lvalue Function {{.*}} 'df2' 'int (&(const P2718R0::A *))[3]' (FunctionTemplate {{.*}} 'df2')324 // CHECK-NEXT: | `-CallExpr {{.*}} 'const A *'325 // CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'const A *(*)(const A &)' <FunctionToPointerDecay>326 // CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const A *(const A &)' lvalue Function {{.*}} 'dg2' 'const A *(const A &)'327 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A' lvalue <DerivedToBase (A)>328 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const B' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'329 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const B' <NoOp>330 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'B' (CXXTemporary {{.*}})331 // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'B' 'void () noexcept(false)' zeroing332 for (auto e : df2(dg2(B())))333 bar(e);334}335 336// Test discard statement && dependent context337void test10() {338 int v[] = {42, 17, 13};339 340 // CHECK: FunctionDecl {{.*}} test10 'void ()'341 // CHECK: -CXXForRangeStmt {{.*}}342 // CHECK-NEXT: |-<<<NULL>>>343 // CHECK-NEXT: |-DeclStmt {{.*}}344 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit345 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue346 // CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','347 // CHECK-NEXT: | |-CXXStaticCastExpr {{.*}} 'void' static_cast<void> <ToVoid>348 // CHECK-NEXT: | | `-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue349 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>350 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')351 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'352 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>353 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})354 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'355 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'356 for ([[maybe_unused]] int x : static_cast<void>(df1(LockGuard())), v)357 LockGuard guard;358 359 // CHECK: -CXXForRangeStmt {{.*}}360 // CHECK-NEXT: |-<<<NULL>>>361 // CHECK-NEXT: |-DeclStmt {{.*}}362 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit363 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue364 // CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','365 // CHECK-NEXT: | |-CStyleCastExpr {{.*}} 'void' <ToVoid>366 // CHECK-NEXT: | | `-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue367 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>368 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')369 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'370 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>371 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})372 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'373 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'374 for ([[maybe_unused]] int x : (void)df1(LockGuard()), v)375 LockGuard guard;376 377 // CHECK: -CXXForRangeStmt {{.*}}378 // CHECK-NEXT: |-<<<NULL>>>379 // CHECK-NEXT: |-DeclStmt {{.*}}380 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit381 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue382 // CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','383 // CHECK-NEXT: | |-BinaryOperator {{.*}} 'const P2718R0::LockGuard' lvalue ','384 // CHECK-NEXT: | | |-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue385 // CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>386 // CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')387 // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'388 // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>389 // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})390 // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'391 // CHECK-NEXT: | | `-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue392 // CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>393 // CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')394 // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'395 // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>396 // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})397 // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'398 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'399 for ([[maybe_unused]] int x : df1(LockGuard()), df1(LockGuard()), v)400 LockGuard guard;401}402 403// Test default argument && dependent context404template <typename T> int (&default_arg_fn2(const T & = T()))[3];405void test11() {406 for (auto e : default_arg_fn2<A>())407 bar(e);408}409 410template <typename T> A foo2(const T&, const DefaultA &Default = DefaultA());411 412void test12() {413 for (auto e : default_arg_fn2(foo2(foo2(foo2(A())))))414 bar(e);415}416 417// Test member call && dependent context418void test13() {419 420 // CHECK: FunctionDecl {{.*}} test13 'void ()'421 // CHECK: -CXXForRangeStmt {{.*}}422 // CHECK-NEXT: |-<<<NULL>>>423 // CHECK-NEXT: |-DeclStmt {{.*}}424 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'A &&' cinit425 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'A' xvalue426 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'427 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})428 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'429 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}430 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue431 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}432 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'433 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})434 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'435 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}436 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue437 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}438 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'439 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})440 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'441 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}442 // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue443 // CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}444 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'445 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'P2718R0::A' (CXXTemporary {{.*}})446 // CHECK-NEXT: | `-CallExpr {{.*}} 'P2718R0::A'447 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'P2718R0::A (*)()' <FunctionToPointerDecay>448 // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'P2718R0::A ()' lvalue Function {{.*}} 'dg' 'P2718R0::A ()' (FunctionTemplate {{.*}} 'dg')449 for (auto e : dg<A>().r().g().r().g().r().g())450 bar(e);451}452 453extern "C" void exit(int);454 455struct A14 {456 int arr[1];457 ~A14() noexcept(false) { throw 42; }458};459 460struct B14 {461 int x;462 const A14 &a = A14{{0}};463 const int *begin() { return a.arr; }464 const int *end() { return &a.arr[1]; }465};466 467void test14() {468 // The ExprWithCleanups in CXXDefaultInitExpr will be ignored.469 470 // CHECK: FunctionDecl {{.*}} test14 'void ()'471 // CHECK: -CXXForRangeStmt {{.*}}472 // CHECK-NEXT: |-<<<NULL>>>473 // CHECK-NEXT: |-DeclStmt {{.*}}474 // CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'const int (&)[1]' cinit475 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'const int[1]' lvalue476 // CHECK-NEXT: | `-MemberExpr {{.*}} 'const int[1]' lvalue .arr {{.*}}477 // CHECK-NEXT: | `-MemberExpr {{.*}} 'const A14' lvalue .a {{.*}}478 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'B14' xvalue extended by Var {{.*}} '__range1' 'const int (&)[1]'479 // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'B14' functional cast to B14 <NoOp>480 // CHECK-NEXT: | `-InitListExpr {{.*}} 'B14'481 // CHECK-NEXT: | |-IntegerLiteral {{.*}} 'int' 0482 // CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} 'const A14' lvalue has rewritten init483 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A14' lvalue extended by Var {{.*}} '__range1' 'const int (&)[1]'484 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A14' <NoOp>485 // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'A14' functional cast to A14 <NoOp>486 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A14' (CXXTemporary {{.*}})487 // CHECK-NEXT: | `-InitListExpr {{.*}} 'A14'488 // CHECK-NEXT: | `-InitListExpr {{.*}} 'int[1]'489 // CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 0490 for (auto &&x : B14{0}.a.arr) { exit(0); }491 492 // CHECK: -CXXForRangeStmt {{.*}}493 // CHECK-NEXT: |-<<<NULL>>>494 // CHECK-NEXT: |-DeclStmt {{.*}}495 // CHECK-NEXT: | `-VarDecl {{.*}} col:19 implicit used __range1 'B14 &&' cinit496 // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'B14' xvalue497 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'B14' xvalue extended by Var {{.*}} '__range1' 'B14 &&'498 // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'B14' functional cast to B14 <NoOp>499 // CHECK-NEXT: | `-InitListExpr {{.*}} 'B14'500 // CHECK-NEXT: | |-IntegerLiteral {{.*}} 'int' 0501 // CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} 'const A14' lvalue has rewritten init502 // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A14' lvalue extended by Var {{.*}} '__range1' 'B14 &&'503 // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A14' <NoOp>504 // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'A14' functional cast to A14 <NoOp>505 // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A14' (CXXTemporary {{.*}})506 // CHECK-NEXT: | `-InitListExpr {{.*}} 'A14'507 // CHECK-NEXT: | `-InitListExpr {{.*}} 'int[1]'508 // CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 0509 for (auto &&x : B14{0}) { exit(0); }510}511} // namespace P2718R0512