Skip to content

Commit 2c64707

Browse files
committed
Work around a C++20 compiler's range-for scoped variable bug/ICE
1 parent 4d034f3 commit 2c64707

16 files changed

+72
-49
lines changed

regression-tests/test-results/mixed-bounds-safety-with-assert-2.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ auto add_42_to_subrange(auto& rng, cpp2::in<int> start, cpp2::in<int> end) -> vo
3131
std::vector<int> v {1, 2, 3, 4, 5};
3232
add_42_to_subrange(v, 1, 3);
3333

34-
for ( auto const& cpp2_range = v; auto const& i : cpp2_range )
35-
std::cout << i << "\n";
34+
{ auto const& cpp2_range = v; for ( auto const& i : cpp2_range )
35+
std::cout << i << "\n";}
36+
#line 8 "mixed-bounds-safety-with-assert-2.cpp2"
3637
}
3738

3839
auto add_42_to_subrange(auto& rng, cpp2::in<int> start, cpp2::in<int> end) -> void
@@ -41,11 +42,12 @@ auto add_42_to_subrange(auto& rng, cpp2::in<int> start, cpp2::in<int> end) -> vo
4142
cpp2::Bounds.expects(cpp2::cmp_less_eq(end,CPP2_UFCS_0(ssize, rng)), "");
4243

4344
auto count {0};
44-
for ( auto&& cpp2_range = rng;
45+
{ auto&& cpp2_range = rng; for (
4546

4647
auto& i : cpp2_range ) { do
4748
if ([_0 = start, _1 = count, _2 = end]{ return cpp2::cmp_less_eq(_0,_1) && cpp2::cmp_less_eq(_1,_2); }()) {
4849
i += 42;
49-
} while (false); ++count; }
50+
} while (false); ++count; }}
51+
#line 22 "mixed-bounds-safety-with-assert-2.cpp2"
5052
}
5153

regression-tests/test-results/mixed-bounds-safety-with-assert.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ auto print_subrange(auto const& rng, cpp2::in<int> start, cpp2::in<int> end) ->
3838
cpp2::Bounds.expects(cpp2::cmp_less_eq(end,CPP2_UFCS_0(ssize, rng)), "");
3939

4040
auto count {0};
41-
for ( auto const& cpp2_range = rng;
41+
{ auto const& cpp2_range = rng; for (
4242

4343
auto const& i : cpp2_range ) { do
4444
if (cpp2::cmp_less_eq(start,count) && cpp2::cmp_less_eq(count,end)) {
4545
std::cout << i << "\n";
46-
} while (false); ++count; }
46+
} while (false); ++count; }}
47+
#line 18 "mixed-bounds-safety-with-assert.cpp2"
4748
}
4849

regression-tests/test-results/mixed-fixed-type-aliases.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ auto test(auto const& x) -> void{
4444
cpp2::u16 z {42};
4545
test(std::move(z));
4646

47-
for ( auto const& cpp2_range = args; auto const& arg : cpp2_range )
48-
std::cout << arg << "\n";
47+
{ auto const& cpp2_range = args; for ( auto const& arg : cpp2_range )
48+
std::cout << arg << "\n";}
49+
#line 24 "mixed-fixed-type-aliases.cpp2"
4950
}
5051

regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@
4343
std::move(callback)
4444
);
4545

46-
for ( auto const& cpp2_range = view; auto const& str : cpp2_range ) {
46+
{ auto const& cpp2_range = view; for ( auto const& str : cpp2_range ) {
4747
std::cout << str << "\n";
48-
}
48+
}}
49+
#line 30 "mixed-function-expression-and-std-for-each.cpp2"
4950
}
5051

regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
auto callback {[](auto& x) -> void { x += "-ish"; }};
3737
std::ranges::for_each(view, std::move(callback));
3838

39-
for ( auto const& cpp2_range = view; auto const& str : cpp2_range )
40-
std::cout << str << "\n";
39+
{ auto const& cpp2_range = view; for ( auto const& str : cpp2_range )
40+
std::cout << str << "\n";}
41+
#line 22 "mixed-function-expression-and-std-ranges-for-each-with-capture.cpp2"
4142
}
4243

regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
auto callback {[](auto& x) -> void { x += "-ish"; }};
3636
std::ranges::for_each(view, std::move(callback));
3737

38-
for ( auto const& cpp2_range = view; auto const& str : cpp2_range )
39-
std::cout << str << "\n";
38+
{ auto const& cpp2_range = view; for ( auto const& str : cpp2_range )
39+
std::cout << str << "\n";}
40+
#line 21 "mixed-function-expression-and-std-ranges-for-each.cpp2"
4041
}
4142

regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
auto callback {[](auto& x) -> void { x += "-ish"; }};
3838
std::ranges::for_each(view, std::move(callback));
3939

40-
for ( auto const& cpp2_range = view; auto const& str : cpp2_range )
41-
std::cout << str << "\n";
40+
{ auto const& cpp2_range = view; for ( auto const& str : cpp2_range )
41+
std::cout << str << "\n";}
42+
#line 23 "mixed-function-expression-with-pointer-capture.cpp2"
4243
}
4344

regression-tests/test-results/mixed-function-expression-with-repeated-capture.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
auto callback {[](auto& x) -> void { x += "-ish"; }};
3737
std::ranges::for_each(view, std::move(callback));
3838

39-
for ( auto const& cpp2_range = view; auto const& str : cpp2_range )
40-
std::cout << str << "\n";
39+
{ auto const& cpp2_range = view; for ( auto const& str : cpp2_range )
40+
std::cout << str << "\n";}
41+
#line 22 "mixed-function-expression-with-repeated-capture.cpp2"
4142
}
4243

regression-tests/test-results/mixed-intro-for-with-counter-include-last.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727
{
2828
std::vector<int> v {1, 2, 3, 4, 5};
2929
auto counter {42};
30-
for ( auto const& cpp2_range = v; auto const& i : cpp2_range ) { do {
30+
{ auto const& cpp2_range = v; for ( auto const& i : cpp2_range ) { do {
3131
std::cout << i << " " << counter << "\n";
32-
} while (false); counter *= 2; }
32+
} while (false); counter *= 2; }}
33+
#line 9 "mixed-intro-for-with-counter-include-last.cpp2"
3334
}
3435

regression-tests/test-results/pure2-break-continue.cpp

+20-16
Original file line numberDiff line numberDiff line change
@@ -253,83 +253,87 @@ auto for_continue_inner() -> void
253253
{
254254
std::vector vi {0, 1, 2};
255255
auto counter {0};
256-
for ( auto const& cpp2_range = vi; auto const& i : cpp2_range ) { do {
256+
{ auto const& cpp2_range = vi; for ( auto const& i : cpp2_range ) { do {
257257
std::vector vj {0, 1, 2};
258-
for ( auto const& cpp2_range = vj; auto const& j : cpp2_range ) {
258+
{ auto const& cpp2_range = vj; for ( auto const& j : cpp2_range ) {
259259
#line 166 "pure2-break-continue.cpp2"
260260
{
261261
std::cout << i << j << " ";
262262
if (j==1) {
263263
goto CONTINUE_166_9;
264264
}
265265
std::cout << "inner ";
266-
} CPP2_CONTINUE_BREAK(166_9) }
266+
} CPP2_CONTINUE_BREAK(166_9) }}
267267

268268
#line 174 "pure2-break-continue.cpp2"
269269
std::cout << "outer ";
270-
} while (false); ++counter; }
270+
} while (false); ++counter; }}
271+
#line 176 "pure2-break-continue.cpp2"
271272
}
272273

273274
auto for_continue_outer() -> void
274275
{
275276
std::vector vi {0, 1, 2};
276277
auto counter {0};
277-
for ( auto const& cpp2_range = vi; auto const& i : cpp2_range ) {
278+
{ auto const& cpp2_range = vi; for ( auto const& i : cpp2_range ) {
278279
#line 182 "pure2-break-continue.cpp2"
279280
{ do {
280281
std::vector vj {0, 1, 2};
281-
for ( auto const& cpp2_range = vj; auto const& j : cpp2_range ) {
282+
{ auto const& cpp2_range = vj; for ( auto const& j : cpp2_range ) {
282283
std::cout << i << j << " ";
283284
if (j==1) {
284285
goto CONTINUE_182_5;
285286
}
286287
std::cout << "inner ";
287-
}
288+
}}
288289

290+
#line 192 "pure2-break-continue.cpp2"
289291
std::cout << "outer ";
290-
} while (false); ++counter; } CPP2_CONTINUE_BREAK(182_5) }
292+
} while (false); ++counter; } CPP2_CONTINUE_BREAK(182_5) }}
291293
#line 194 "pure2-break-continue.cpp2"
292294
}
293295

294296
auto for_break_inner() -> void
295297
{
296298
std::vector vi {0, 1, 2};
297299
auto counter {0};
298-
for ( auto const& cpp2_range = vi; auto const& i : cpp2_range ) { do {
300+
{ auto const& cpp2_range = vi; for ( auto const& i : cpp2_range ) { do {
299301
std::vector vj {0, 1, 2};
300-
for ( auto const& cpp2_range = vj; auto const& j : cpp2_range ) {
302+
{ auto const& cpp2_range = vj; for ( auto const& j : cpp2_range ) {
301303
#line 202 "pure2-break-continue.cpp2"
302304
{
303305
std::cout << i << j << " ";
304306
if (j==1) {
305307
goto BREAK_202_9;
306308
}
307309
std::cout << "inner ";
308-
} CPP2_CONTINUE_BREAK(202_9) }
310+
} CPP2_CONTINUE_BREAK(202_9) }}
309311

310312
#line 210 "pure2-break-continue.cpp2"
311313
std::cout << "outer ";
312-
} while (false); ++counter; }
314+
} while (false); ++counter; }}
315+
#line 212 "pure2-break-continue.cpp2"
313316
}
314317

315318
auto for_break_outer() -> void
316319
{
317320
std::vector vi {0, 1, 2};
318321
auto counter {0};
319-
for ( auto const& cpp2_range = vi; auto const& i : cpp2_range ) {
322+
{ auto const& cpp2_range = vi; for ( auto const& i : cpp2_range ) {
320323
#line 218 "pure2-break-continue.cpp2"
321324
{ do {
322325
std::vector vj {0, 1, 2};
323-
for ( auto const& cpp2_range = vj; auto const& j : cpp2_range ) {
326+
{ auto const& cpp2_range = vj; for ( auto const& j : cpp2_range ) {
324327
std::cout << i << j << " ";
325328
if (j==1) {
326329
goto BREAK_218_5;
327330
}
328331
std::cout << "inner ";
329-
}
332+
}}
330333

334+
#line 228 "pure2-break-continue.cpp2"
331335
std::cout << "outer ";
332-
} while (false); ++counter; } CPP2_CONTINUE_BREAK(218_5) }
336+
} while (false); ++counter; } CPP2_CONTINUE_BREAK(218_5) }}
333337
#line 230 "pure2-break-continue.cpp2"
334338
}
335339

regression-tests/test-results/pure2-intro-example-hello-2022.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ auto println(auto const& x, auto const& len) -> void;
3030
"hello", "2022"};
3131
std::span view {vec};
3232

33-
for ( auto&& cpp2_range = view; auto& str : cpp2_range ) {
33+
{ auto&& cpp2_range = view; for ( auto& str : cpp2_range ) {
3434
auto len {decorate(str)};
3535
println(str, len);
36-
}
36+
}}
37+
#line 10 "pure2-intro-example-hello-2022.cpp2"
3738
}
3839

3940
[[nodiscard]] auto decorate(auto& thing) -> int{

regression-tests/test-results/pure2-intro-example-three-loops.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ auto decorate_and_print(auto& thing) -> void{
5252
} while ( cpp2::cmp_greater(*cpp2::assert_not_null(i),1) && [&]{ --*cpp2::assert_not_null(i) ; return true; }() );
5353

5454
std::cout << "\n";
55-
for ( auto&& cpp2_range = words; auto& word : cpp2_range )
56-
decorate_and_print(word);
55+
{ auto&& cpp2_range = words; for ( auto& word : cpp2_range )
56+
decorate_and_print(word);}
5757

58+
#line 28 "pure2-intro-example-three-loops.cpp2"
5859
print(std::string{"end of program"});
5960
}
6061

regression-tests/test-results/pure2-statement-scope-parameters.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ auto const& i = local_int;
2828

2929
// 'in' (read-only) statement scope variable
3030
#line 6 "pure2-statement-scope-parameters.cpp2"
31-
for ( auto const& cpp2_range = args; auto const& arg : cpp2_range ) {
31+
{ auto const& cpp2_range = args; for ( auto const& arg : cpp2_range ) {
3232
std::cout << i << "\n"; // prints 42
33-
}
33+
}}
3434
}
3535
{
3636
auto& i = local_int;

regression-tests/test-results/pure2-type-and-namespace-aliases.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ auto myfunc() -> void{
6161

6262
auto const& v2 = std::move(v);
6363

64-
for ( auto const& cpp2_range = v2; auto const& s : cpp2_range )
65-
std::cout << cpp2::to_string(s) + "\n";
64+
{ auto const& cpp2_range = v2; for ( auto const& s : cpp2_range )
65+
std::cout << cpp2::to_string(s) + "\n";}
66+
#line 24 "pure2-type-and-namespace-aliases.cpp2"
6667
}
6768

6869
auto main() -> int{

regression-tests/test-results/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.2.1 Build 8505:0902
2+
cppfront compiler v0.2.1 Build 8506:1618
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

source/cppfront.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -2116,14 +2116,18 @@ class cppfront
21162116
&& n.body
21172117
);
21182118

2119+
// Note: This used to emit cpp2_range as a range-for-loop scope variable,
2120+
// but some major compilers seem to have random troubles with that;
2121+
// the workaround to avoid their bugs for now is to emit a { } block
2122+
// around the Cpp1 range-for and make the scope variable a normal local
21192123
if (n.for_with_in) {
2120-
printer.print_cpp2("for ( auto const& cpp2_range = ", n.position());
2124+
printer.print_cpp2("{ auto const& cpp2_range = ", n.position());
21212125
}
21222126
else {
2123-
printer.print_cpp2("for ( auto&& cpp2_range = ", n.position());
2127+
printer.print_cpp2("{ auto&& cpp2_range = ", n.position());
21242128
}
21252129
emit(*n.range);
2126-
printer.print_cpp2("; ", n.position());
2130+
printer.print_cpp2("; for ( ", n.position());
21272131
emit(*n.parameter);
21282132
printer.print_cpp2(" : cpp2_range ) ", n.position());
21292133
if (!labelname.empty()) {
@@ -2151,6 +2155,8 @@ class cppfront
21512155
printer.print_extra(" CPP2_CONTINUE_BREAK("+labelname+") }");
21522156
}
21532157

2158+
printer.print_extra("}");
2159+
21542160
in_non_rvalue_context.pop_back();
21552161
}
21562162

@@ -5410,7 +5416,7 @@ class cppfront
54105416
{
54115417
printer.print_cpp2( prefix, n.position() );
54125418
printer.print_cpp2( "auto " + type_qualification_if_any_for(n), n.position() );
5413-
printer.print_cpp2( *n.name(), n.identifier->position() );
5419+
emit( *n.name() );
54145420
emit( *func, n.name(), is_main, false, suffix1 );
54155421
printer.print_cpp2( suffix2, n.position() );
54165422
}

0 commit comments

Comments
 (0)