<br><br><div class="gmail_quote">2010/10/27 Marcin Świderski <span dir="ltr"><<a href="mailto:marcin.sfider@gmail.com">marcin.sfider@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="gmail_quote">2010/10/26 Frits van Bommel <span dir="ltr"><<a href="mailto:fvbommel@gmail.com" target="_blank">fvbommel@gmail.com</a>></span><div><div></div><div class="h5"><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<div>On Tue, Oct 26, 2010 at 4:53 AM, Zhongxing Xu <<a href="mailto:xuzhongxing@gmail.com" target="_blank">xuzhongxing@gmail.com</a>> wrote:<br>
> Only statements containing control flow could cause 'Block' to be NULL, e.g.<br>
> DoStmt, WhileStmt, CastStmt. They do occur in the RHS of assignments, but<br>
> they do not occur in the LHS of assignments. So I think it's safe here. Or I<br>
> could miss something?<br>
<br>
</div>The following code is accepted by both gcc and clang in c++ mode, even<br>
if -pedantic and/or -std=c++98 is passed:<br>
=====<br>
int* iftrue();<br>
int* iffalse();<br>
<br>
void conditional_assign (int cond, int val) {<br>
    (cond ? *iftrue() : *iffalse()) = val;<br>
}<br>
=====<br>
<br>
Neither will compile it in C mode as-is, but both are fine with it if<br>
I put move the dereference to before the opening bracket. (Again, even<br>
with -pedantic and/or (-std=c89 or -std=c99)<br>
Apparently C doesn't preserve the lvalue-ness of the conditional<br>
operator's operands, but C++ does. Not really surprising given that<br>
C++ has an int& type but C doesn't; in C++ their types are int& while<br>
in C they're probably plain old ints.<br>
<br>
Anyway, this is an example of code clang (like gcc) compiles without<br>
complaining that has control flow in the LHS of an assignment<br>
operator.<br>
<br>
I didn't check whether statement expressions are allowed in the LHS,<br>
but that could be another case.<br>
<div><div></div><div></div></div></blockquote></div></div></div><div><br></div><div>I've found code that did crash the CFGBuilder (with RHS then LHS visiting order for assignment operator) in test/Analysis/misc-ps-region-store.m:</div>

<br><div><div>struct list_pr8141</div><div>{</div><div>  struct list_pr8141 *tail;</div><div>};</div><div><br></div><div><div>struct list_pr8141 *</div><div>pr8141 (void) {</div><div>  struct list_pr8141 *items;</div><div>

  for (;; items = ({ do { } while (0); items->tail; })) // expected-warning{{Dereference of undefined pointer value}}</div><div>    {</div><div>    }</div><div>}</div></div><div><br></div><div>After switching to LHS then RHS visiting order (as in repository) this will work fine, but it's just a one case. I did play with the code a little and came up with this piece:</div>

<div><br></div><div>struct list_pr8141 *</div><div>pr8141 (void) {</div><div>  struct list_pr8141 *items;</div><div>  while (items - ({ do { } while (0); items->tail; })) {}</div><div>}</div></div><div><br></div><div>
This will crash the CFGBuilder as it is in repository. After fixing VisitBinaryOperator() to always return a block this will still crash, but in VisitWhileStmt on assert on line 1739. This have been run with command used for misc-ps-region-store.m test file.</div>

</blockquote></div><br>Hi Marcin,<br><br>I fixed this case in r117436.<br>