Skip to content

Use switch cases as current_block values and block/break labels #1526

@randomPoison

Description

@randomPoison

It would be beneficial in a couple of ways if we could capture switch cases in the CFG that we construct and feed into relooper:

In both cases c2rust needs to name some item in a way that corresponds to a node in the CFG. Currently we mostly fall back to numeric labels in these cases. Capturing switch cases would allow us to generate more meaningful names in some cases.

Details

In relooper 2, a common case of blocks with synthetic labels is switch with fallthrough between cases:

C code demonstrating fallthrough and the relooper 2 translation
switch (x)
{
case A:
    x += 1;
case B:
    x += 1;
case C:
    x += 1;
}
return x;
's_19: {
    'c_114: {
        match x {
            0 => {
                x += 1 as ::core::ffi::c_int;
            }
            1 => {}
            2 => {
                break 'c_114;
            }
            _ => {
                break 's_19;
            }
        }
        x += 1 as ::core::ffi::c_int;
    }
    x += 1 as ::core::ffi::c_int;
}
return x;

In the translation above we have blocks labeled 's_19 and 'c_114, which are derived from the labels of the corresponding nodes in the underlying CFG. In some cases these numeric labels are inevitable, but when the control flow comes from the cases of a switch, we could potentially use the case values to generate more meaningful block labels:

Alternate translation using case values for block labels
'case_default: {
    'case_C: {
        match x {
            0 => {
                x += 1 as ::core::ffi::c_int;
            }
            1 => {}
            2 => {
                break 'case_C;
            }
            _ => {
                break 'case_default;
            }
        }
        x += 1 as ::core::ffi::c_int;
    }
    x += 1 as ::core::ffi::c_int;
}
return x;

Misc. thoughts:

  • Currently we only capture named labels from goto labels in the original C, and all other CFG nodes get a synthetic (numeric) label.
  • switch case values aren't guaranteed to be unique in the same way goto labels are, so we couldn't use them as CFG labels directly, but we could capture the case value in the CFG node and then make use of it when building the relooped AST.
  • This is primarily motivated by relooper 2 so that we can generate better block/break labels, but is also applicable to Generate an enum for current_block labels #1523, since in that case we will be generating enum variants that correspond to CFG labels.

Metadata

Metadata

Assignees

No one assigned

    Labels

    control flowenhancementNew feature or requestreadabilityGenerated code is hard to read and can be simplified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions