CFGBuilder ad OpaqueValueExprs

(Apologies if this comes through twice. Domain problems.)

I have an expression with OpaqueValueExprs and subexpressions to which
they correspond. I'm trying to figure out how to make this work with
CFGBuilder, so I'm using CFGBuilder::VisitConditionalOperator as a
guide. For instance, this code:

int foo(int x) {
  x = x + 1;
  (x > 2) ? : (x += 2);
  return x;

generates the following CFG:

[ B4 (ENTRY) ]
    Predecessors (0):
    Successors (1): B3

[ B1 ]
      1: [B3.2] ?: [B2.1]
      2: return x;
    Predecessors (2): B2 B3
    Successors (1): B0

[ B2 ]
      1: (x += 2)
    Predecessors (1): B3
    Successors (1): B1

[ B3 ]
      1: x = x + 1
      2: (x > 2)
      T: [B3.3] ? ... : ...
    Predecessors (1): B4
    Successors (2): B1 B2

[ B0 (EXIT) ]
    Predecessors (1): B1
    Successors (0):

This seems wrong to me. First is the blank on B3.3. This is the implicit
cast of the OpaqueValueExpr (refers to "(x > 2)") to int; that is, the
true branch of the conditional. Second, no statement for the
OpaqueValueExpr gets emitted at all, either in the condition or in the
true branch. Third, we have B3.T, which indicates that the condition is
B3.3 -- the implicit conversion expression. That's not right. It should
be B3.2, the boolean expression. B1.1 seems to get this correct, and it
seems that B1.1 and B3.T should agree about what the condition is.

Any explanation of this CFG is greatly appreciated. And general guidance
about how to correctly handle OpaqueValueExprs in CFGBuilding would be
welcome as well.

Thanks in advance,


Hi Eric,

Not all expressions are included in the CFG. Only ones that add fixed control-flow, e.g. ternary operators, are included in the CFGBlock. Control-flow between expressions and their subexpressions is implicitly implied, and thus not all of the control-flow needs to be linearized into the CFGBlock.

As for the blank line, that looks like a missing case in the CFG printer, but I think the CFG itself looks well-formed.