<br><br><div class="gmail_quote">On Wed, Oct 27, 2010 at 5:13 PM, Frits van Bommel <span dir="ltr"><<a href="mailto:fvbommel@gmail.com">fvbommel@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div><div></div><div class="h5">On Wed, Oct 27, 2010 at 4:32 AM, Zhongxing Xu <<a href="mailto:xuzhongxing@gmail.com">xuzhongxing@gmail.com</a>> wrote:<br>
><br>
><br>
> On Tue, Oct 26, 2010 at 4:16 PM, Frits van Bommel <<a href="mailto:fvbommel@gmail.com">fvbommel@gmail.com</a>><br>
> wrote:<br>
>><br>
>> On Tue, Oct 26, 2010 at 4:53 AM, Zhongxing Xu <<a href="mailto:xuzhongxing@gmail.com">xuzhongxing@gmail.com</a>><br>
>> wrote:<br>
>> > Only statements containing control flow could cause 'Block' to be NULL,<br>
>> > e.g.<br>
>> > DoStmt, WhileStmt, CastStmt. They do occur in the RHS of assignments,<br>
>> > but<br>
>> > they do not occur in the LHS of assignments. So I think it's safe here.<br>
>> > Or I<br>
>> > could miss something?<br>
>><br>
>> 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>
> conditional operator does not terminate the current 'Block'. So this does no<br>
> harm.<br>
<br>
</div></div>Okay, I guess you're using "Block" as a source-level {}-delimited<br>
piece of code here, unrelated to the LLVM notion of a "basic block"?<br></blockquote><div><br>I meant the 'Block' variable in CFGBuilder that points to the 'current' block.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<div class="im"><br>
>> I didn't check whether statement expressions are allowed in the LHS,<br>
>> but that could be another case.<br>
><br>
> StmtExpr cannot produce an lvalue, so they cannot appear in the LHS of an<br>
> assignment.<br>
<br>
</div>They don't need to produce an lvalue directly, just be involved in<br>
computing one. For instance, they can just produce a pointer that can<br>
be dereferenced to be an lvalue:<br>
<div class="im">=====<br>
int* iftrue();<br>
int* iffalse();<br>
<br>
void conditional_assign (int cond, int val) {<br>
</div>   *({<br>
       int* result = 0;<br>
       if(cond) {<br>
           result = iftrue();<br>
       } else {<br>
           result = iffalse();<br>
       }<br>
       result;<br>
   }) = val;<br>
}<br>
=====<br>
Could something like this break that code? (possibly with different<br>
code in the statement expression?)<br></blockquote><div><br>No. Note that the LHS is actually a unary operator. What would cause trouble is that StmtExpr occurs in the top level in the LHS of assignment.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

<br>
(Statement expressions could probably also be used in array indices,<br>
parameters to functions returning references, and so on. So they can<br>
most definitely occur in the LHS of an assignment statement)<br>
</blockquote></div><br>