[cfe-commits] r117220 - in /cfe/trunk: lib/Analysis/CFG.cpp test/Sema/warn-unreachable.c

Frits van Bommel fvbommel at gmail.com
Wed Oct 27 02:13:13 PDT 2010


On Wed, Oct 27, 2010 at 4:32 AM, Zhongxing Xu <xuzhongxing at gmail.com> wrote:
>
>
> On Tue, Oct 26, 2010 at 4:16 PM, Frits van Bommel <fvbommel at gmail.com>
> wrote:
>>
>> On Tue, Oct 26, 2010 at 4:53 AM, Zhongxing Xu <xuzhongxing at gmail.com>
>> wrote:
>> > Only statements containing control flow could cause 'Block' to be NULL,
>> > e.g.
>> > DoStmt, WhileStmt, CastStmt. They do occur in the RHS of assignments,
>> > but
>> > they do not occur in the LHS of assignments. So I think it's safe here.
>> > Or I
>> > could miss something?
>>
>> The following code is accepted by both gcc and clang in c++ mode, even
>> if -pedantic and/or -std=c++98 is passed:
>> =====
>> int* iftrue();
>> int* iffalse();
>>
>> void conditional_assign (int cond, int val) {
>>    (cond ? *iftrue() : *iffalse()) = val;
>> }
>> =====
>>
>> Neither will compile it in C mode as-is, but both are fine with it if
>> I put move the dereference to before the opening bracket. (Again, even
>> with -pedantic and/or (-std=c89 or -std=c99)
>> Apparently C doesn't preserve the lvalue-ness of the conditional
>> operator's operands, but C++ does. Not really surprising given that
>> C++ has an int& type but C doesn't; in C++ their types are int& while
>> in C they're probably plain old ints.
>>
>> Anyway, this is an example of code clang (like gcc) compiles without
>> complaining that has control flow in the LHS of an assignment
>> operator.
>
> conditional operator does not terminate the current 'Block'. So this does no
> harm.

Okay, I guess you're using "Block" as a source-level {}-delimited
piece of code here, unrelated to the LLVM notion of a "basic block"?

>> I didn't check whether statement expressions are allowed in the LHS,
>> but that could be another case.
>
> StmtExpr cannot produce an lvalue, so they cannot appear in the LHS of an
> assignment.

They don't need to produce an lvalue directly, just be involved in
computing one. For instance, they can just produce a pointer that can
be dereferenced to be an lvalue:
=====
int* iftrue();
int* iffalse();

void conditional_assign (int cond, int val) {
   *({
       int* result = 0;
       if(cond) {
           result = iftrue();
       } else {
           result = iffalse();
       }
       result;
   }) = val;
}
=====
Could something like this break that code? (possibly with different
code in the statement expression?)

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




More information about the cfe-commits mailing list