codeql icon indicating copy to clipboard operation
codeql copied to clipboard

Swift: first prototype of a generated IPA layer

Open redsun82 opened this issue 3 years ago • 0 comments
trafficstars

This introduces a first version of a generated IPA layer.

Schema

In schema.yml, types can be marked with either

MyType:
  _ipa:
    from: OtherType

or

MyType:
  _ipa:
    on:
      arg1: OtherType
      arg2: int

The former are "derived" IPA types, built on top of DB entities, the latter are "fresh" ones, built from scratch.

New generated files

Db.qll defines a thin non customizable QL class layer over DB types, inside a Db module. So for example Db::Expr is a simple wrapper of @expr.

Ipa.qll defines the base algebraic type Ipa::TElement with all pure DB types and IPA types as defined in schema.yml. IPA types get characteristic predicates (except for parameterless derived IPA types) to be customized in stubs (MyTypeConstructor.qll) alongside the other stubs already created. DB types that have one or more derived IPA types built on top of them also have a characteristic predicate subtracting those derived types from their instances. The rest of the type hierarchy is recreated via class = ... or ... declarations. The Ipa module is fully cached, and also provides conversions to and from DB instances when it makes sense (for types that are not derived IPA ones).

Class customization

This works more or less like before, with one notable exception: the overrideable property getters are now named getImmediateX in case the result is a class (not a built-in type), and are used to return the result without element resolution kicking in. For pure DB types, properties are implemented as before based on DB relations (using the property getters defined in Db.qll). For fresh or derived IPA types, properties are left unimplemented. Inherited properties will however be implemented if the type is a derived IPA with the source compatible with the inherited type.

Example

This PR contains a simple example of usage, introducing singleton IPA-synthesized unknown file and location instances.

Class fields

It was initially planned to have underlying DB entities or derived IPA constructor argumetns as fields in the classes. This turned out to not work because that would have required extensive use of characteristic predicates, which were exhausting the internal limit of 2^25 for BDD tree nodes...

Further work

This is a prototype with some corners being cut:

  • IPA types are still used for dbscheme, trap and cpp generation, they should be removed from there
  • qlgen.py has become too big and with too many things being generated, it should probably be split
  • while codegen unit tests have been kept passing, the additional functionality is not covered yet
  • there is room for quality of life improvements, like generating getters for derived IPA type constructor arguments
  • getImmediateX might be too noisy to have in the public interface of the classes. Maybe we can rethink the resolution mechanism that we have used mostly for hiding conversion AST nodes, or maybe we can just hide away this detail better. (a protected access modifier would help here...)

redsun82 avatar Jul 25 '22 12:07 redsun82