Skip to content

Remove annoying integer casts from pointer equality checks #162

@sim642

Description

@sim642

I brought this up at 2023-04-19 GobCon, where the notes say:

Why does CIL insert annoying integer casts to all pointer equality checks?

  1. E.g. ((unsigned long)x) == ((unsigned long)y)
  2. This is in particular an issue as the int-type they are cast-to depends on the architecture. Therefore, combining on a different architecture changes the results!
  3. Possible issue with casts being inserted before CIL merging; and types changing after the CIL merge
  4. The standard demands no such thing?
    1. C11 6.5.9.2: “One of the following shall hold: [...] - both operands are pointers to qualified or unqualified versions of compatible types;”
    2. C11 6.5.9.4: “If both of the operands have arithmetic type, the usual arithmetic conversions are performed.”
  5. Proposition: Double check that these casts are not needed, then do not insert them in
  6. Check whether pointers of different type can be compared without a cast according to the C standard
  7. If not, then check whether attributes (which may be collected during merging) are relevant with regard to (f).
  8. If attributes are not relevant or if pointers of different type can be compared, then we can remove the casts (at least for pointers of the same type).

This seems to be done here:

cil/src/frontc/cabs2cil.ml

Lines 5003 to 5008 in d2760ba

let pointerComparison e1 t1 e2 t2 =
(* Cast both sides to an integer *)
let commontype = !upointType in
intType,
optConstFoldBinOp false bop (makeCastT ~e:e1 ~oldt:t1 ~newt:commontype)
(makeCastT ~e:e2 ~oldt:t2 ~newt:commontype) intType

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions