type-punning warnings for CXXTypeidExpr::child_begin()/child_end()

In ExprCXX.cpp I see:

Stmt::child_iterator CXXTypeidExpr::child_begin() {
   return isTypeOperand() ? child_iterator() : (Stmt**)&Operand;
}

The expression '(Stmt**)&Operand' leads to type-punning warnings during a Release build. This looks like a real issue to me. Is this safe, or do we need to fix it? The same warning appears in child_end().

This is a real bug. "Operand" should be declared as a Stmt*.

-Chris

The problem is that Operand is used as a variant to represent either a Type* or a Stmt*.

It looks like a real issue to me too. I guess the simplest solution
is to change "void *Operand;" to "union {void* Operand; Stmt*
OperandExpr;};", and change child_begin to use OperandExpr. It isn't
pretty, but I think it has the intended semantics.

I guess it's worth noting that SizeOfAlignOfExpr has the same issue.

-Eli

Err, right... my solution was overly complicated.

-Eli

Eli Friedman wrote:

I'm not certain that using a union will change anything. I think there will still be a type-punning issue, even if we manage to make the warning go away.

Ted Kremenek wrote:

My code, both of it. I suppose I can go with the union.

I'm not certain that using a union will change anything. I think there will still be a type-punning issue, even if we manage to make the warning go away.

No, there won't. The node uses this field either as a type or an expression, for the entire lifetime. I just need to be careful which I initially assign.

Sebastian

Makes sense.