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

Marcin Świderski marcin.sfider at gmail.com
Tue Oct 26 12:08:01 PDT 2010


2010/10/26 Frits van Bommel <fvbommel at gmail.com>

> 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.
>
> I didn't check whether statement expressions are allowed in the LHS,
> but that could be another case.
>

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:

struct list_pr8141
{
  struct list_pr8141 *tail;
};

struct list_pr8141 *
pr8141 (void) {
  struct list_pr8141 *items;
  for (;; items = ({ do { } while (0); items->tail; })) //
expected-warning{{Dereference of undefined pointer value}}
    {
    }
}

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:

struct list_pr8141 *
pr8141 (void) {
  struct list_pr8141 *items;
  while (items - ({ do { } while (0); items->tail; })) {}
}

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20101026/7c2af29b/attachment.html>


More information about the cfe-commits mailing list