<div dir="ltr"><div class="gmail_extra"><br><br><div class="gmail_quote">2013/12/13 Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
  Have you checked that IR generation does the right thing in these cases? A CodeGen test for this would be useful.<br>
<div class="im"><br></div></blockquote><div>Attached is a test that can be compiled and run to check particular binding in clang and gcc.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div class="im">
<br>
================<br>
Comment at: test/Parser/bad-control.c:22-30<br>
@@ +21,11 @@<br>
+<br>
+// GCC rejects this code<br>
+void pr8880_3(int first) {<br>
+  for ( ; ; (void)({ if (first) { first = 0; continue; } 0; })) {}<br>
+}<br>
+<br>
+// GCC rejects this code (see also tests/Analysis/dead-stores.c rdar8014335()<br>
+void pr8880_4(int first) {<br>
+  for ( ; ; (void)({ if (first) { first = 0; break; } 0; })) {}<br>
+}<br>
+<br>
----------------<br>
</div><div class="im">Serge Pavlov wrote:<br>
> Richard Smith wrote:<br>
> > Does this mean we're misinterpreting pr8880_10 and pr8880_11 below?<br>
> No, this is a feature of GCC. It uses different interpretation depending on whether code is compiled as C or as C++. In C++ mode break and continue in the second or third expression of for statement refer to the inner loop, in C mode - to the outer. However in both modes GCC reject using break/continue if for statement is not inside another loop. Clang is more consistent, it considers that the third expression refers to the inner loop and the second - to outer, the interpretation is the same in C and C++ mode.<br>

</div>Interesting. I agree that it makes little sense for C and C++ to differ here, other than GCC compatibility.<br>
<br>
Why does break/continue in the second expression bind to the inner scope and the third expression bind to the outer? It seems strange that we would (deliberately) differ from both GCC's C mode and its C++ mode here.<br>

<br></blockquote><div>Doug Gregor filed a bug against GCC (<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44715">http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44715</a>), but after 3 years GCC still keeps inconsistent behavior. Maybe he has more information on this subject.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Since GCC rejects this if the loop is non-nested, it seems more reasonable to me for them to always bind to the surrounding scope. Is there a reason to not do that?<br></blockquote><div><br></div><div>In C++ mode break/continue bind to inner scope. Surprisingly this construct is used in QT macro 'foreach'. The following code:</div>
<div><br></div><div><div>  foreach(QString name, names)</div><div>    qDebug() << name;</div></div><div><br></div><div>after preprocessing produces:</div><div><br></div><div><div>for (QForeachContainer<__typeof__(names)> _container_(names); </div>
<div>     !_container_.brk && _container_.i != _container_.e;</div><div>     __extension__ ({ ++_container_.brk; ++_container_.i; }))</div><div>for (QString name = *_container_.i;; __extension__ ({--_container_.brk; break;}))</div>
<div>    qDebug() << name;</div></div><div><br></div><div>So clang must bind break in the third expression to inner loop.</div><div><br></div><div>There is also a test in Analysis/dead-stores.c :</div><div><br></div>
<div><div>// The FOREACH macro in QT uses 'break' statements within statement expressions</div><div>// placed within the increment code of for loops.</div><div>void rdar8014335() {</div><div>  for (int i = 0 ; i != 10 ; ({ break; })) {</div>
<div>    for ( ; ; ({ ++i; break; })) ;</div><div>    // Note that the next value stored to 'i' is never executed</div><div>    // because the next statement to be executed is the 'break'</div><div>    // in the increment code of the first loop.</div>
<div>    i = i * 3; // expected-warning{{Value stored to 'i' is never read}} expected-warning{{The left operand to '*' is always 1}}</div><div>  }</div><div>}</div></div><div><br></div><div>This code cannot be compiled by GCC (I tried 4.6.3 and ToT). The test was added by Ted Kremenek in r104375. Maybe he can recall if it was obtained from real application. If so, this is the second usage case clang should support.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D2018" target="_blank">http://llvm-reviews.chandlerc.com/D2018</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>Thanks,<br>--Serge<br>
</div></div>