171 lines · cpp
1// RUN: %clang_cc1 -fnamed-loops -std=c++23 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fnamed-loops -std=c++23 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter3// expected-no-diagnostics4 5struct Tracker {6 bool& destroyed;7 constexpr Tracker(bool& destroyed) : destroyed{destroyed} {}8 constexpr ~Tracker() { destroyed = true; }9};10 11constexpr int f1() {12 a: for (;;) {13 for (;;) {14 break a;15 }16 }17 return 1;18}19static_assert(f1() == 1);20 21constexpr int f2() {22 int x{};23 a: for (int i = 0; i < 10; i++) {24 b: for (int j = 0; j < 10; j++) {25 x += j;26 if (i == 2 && j == 2) break a;27 }28 }29 return x;30}31static_assert(f2() == 93);32 33constexpr int f3() {34 int x{};35 a: for (int i = 0; i < 10; i++) {36 x += i;37 continue a;38 }39 return x;40}41static_assert(f3() == 45);42 43constexpr int f4() {44 int x{};45 a: for (int i = 1; i < 10; i++) {46 x += i;47 break a;48 }49 return x;50}51static_assert(f4() == 1);52 53constexpr bool f5(bool should_break) {54 bool destroyed = false;55 a: while (!destroyed) {56 while (true) {57 Tracker _{destroyed};58 if (should_break) break a;59 continue a;60 }61 }62 return destroyed;63}64static_assert(f5(true));65static_assert(f5(false));66 67constexpr bool f6(bool should_break) {68 bool destroyed = false;69 a: while (!destroyed) {70 while (true) {71 while (true) {72 Tracker _{destroyed};73 while (true) {74 while (true) {75 if (should_break) break a;76 continue a;77 }78 }79 }80 }81 }82 return destroyed;83}84static_assert(f6(true));85static_assert(f6(false));86 87constexpr int f7(bool should_break) {88 int x = 100;89 a: for (int i = 0; i < 10; i++) {90 b: switch (1) {91 case 1:92 x += i;93 if (should_break) break a;94 break b;95 }96 }97 return x;98}99static_assert(f7(true) == 100);100static_assert(f7(false) == 145);101 102constexpr bool f8() {103 a: switch (1) {104 case 1: {105 while (true) {106 switch (1) {107 case 1: break a;108 }109 }110 }111 }112 return true;113}114static_assert(f8());115 116constexpr bool f9() {117 a: do {118 while (true) {119 break a;120 }121 } while (true);122 return true;123}124static_assert(f9());125 126constexpr int f10(bool should_break) {127 int a[10]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};128 int x{};129 a: for (int v : a) {130 for (int i = 0; i < 3; i++) {131 x += v;132 if (should_break && v == 5) break a;133 }134 }135 return x;136}137 138static_assert(f10(true) == 35);139static_assert(f10(false) == 165);140 141constexpr bool f11() {142 struct X {143 int a[10]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};144 Tracker t;145 constexpr X(bool& b) : t{b} {}146 };147 148 bool destroyed = false;149 a: for (int v : X(destroyed).a) {150 for (int i = 0; i < 3; i++) {151 if (v == 5) break a;152 }153 }154 return destroyed;155}156static_assert(f11());157 158template <typename T>159constexpr T f12() {160 T x{};161 a: for (T i = 0; i < 10; i++) {162 b: for (T j = 0; j < 10; j++) {163 x += j;164 if (i == 2 && j == 2) break a;165 }166 }167 return x;168}169static_assert(f12<int>() == 93);170static_assert(f12<unsigned>() == 93u);171