[cfe-dev] Strange AST behavior with C++ casts

Nicola Gigante nicola.gigante at gmail.com
Tue Oct 4 04:51:36 PDT 2011


Il giorno 04/ott/2011, alle ore 11:48, Sebastian Redl ha scritto:

> On 03.10.2011 19:37, John McCall wrote:
>> Well, it's not accidental.  C's semantics are easy enough to check with a function that, logically, just computes a cast kind for the conversion, adding extra implicit casts in the rare cases where they're required.  C++'s semantics aren't that simple;  we can generate a lot of expressions for one of those casts, and the outermost node is not always a cast at all.
> To give you one example: a cast to a class type using a user-defined 
> conversion constructor will be a noop cast expression containing a 
> CXXConstructExpr (or something similar). There is not really a good way 
> you can embed that functionality in the cast expression itself.
> 

Hm, if I got it you mean something like:
struct C {
C(int);
};

C func() {
  return static_cast<C>(0);
}

which produces this AST:
C func() (CompoundStmt
  (ReturnStmt
    (CXXConstructExpr 'struct C''void (const struct C &) throw()' elidable
      (MaterializeTemporaryExpr 'const struct C' lvalue
        (ImplicitCastExpr 'const struct C' <NoOp>
          (CXXStaticCastExpr 'struct C' static_cast<struct C> <ConstructorConversion>
            (CXXConstructExpr 'struct C''void (int)'
              (IntegerLiteral 'int' 0))))))))

I don't find anything wrong in this AST, mainly because the kind of the static cast node 
is ConstructorConversion instead of NoOp.
There's a NoOp cast outside but that's another thing. Actually, this is the only case where 
TryStaticImplicitCast() doesn't do the ImplicitCastExpr trick,
maybe because it creates the CXXConstructExpr instead. 
In this case, the CXXConstructExpr is useful because it stores info
that could not be stored directly in the cast node.
However, in the other cases the ImplicitCastExpr node doesn't carry any additional information.
Imho is redundant, tell me if you don't agree.

Let me be clear: we don't want to get rid of every NoOp cast nor every implicit cast in the AST. That's just
a specific corner case in which we think this node is useless.

Would it be ok if I modify the function to not create the ImplicitCastExpr node in those cases,
relying on the external explicit cast node instead, as suggested (I think) by Eli?

> Sebastian

Thanks,
Nicola



More information about the cfe-dev mailing list