@@ -2029,157 +2029,6 @@ predicate localExprFlow(Expr e1, Expr e2) {
20292029 localExprFlowPlus ( e1 , e2 )
20302030}
20312031
2032- /**
2033- * A canonical representation of a field.
2034- *
2035- * For performance reasons we want a unique `Content` that represents
2036- * a given field across any template instantiation of a class.
2037- *
2038- * This is possible in _almost_ all cases, but there are cases where it is
2039- * not possible to map between a field in the uninstantiated template to a
2040- * field in the instantiated template. This happens in the case of local class
2041- * definitions (because the local class is not the template that constructs
2042- * the instantiation - it is the enclosing function). So this abstract class
2043- * has two implementations: a non-local case (where we can represent a
2044- * canonical field as the field declaration from an uninstantiated class
2045- * template or a non-templated class), and a local case (where we simply use
2046- * the field from the instantiated class).
2047- */
2048- abstract private class CanonicalField extends Field {
2049- /** Gets a field represented by this canonical field. */
2050- abstract Field getAField ( ) ;
2051-
2052- /**
2053- * Gets a class that declares a field represented by this canonical field.
2054- */
2055- abstract Class getADeclaringType ( ) ;
2056-
2057- /**
2058- * Gets a type that this canonical field may have. Note that this may
2059- * not be a unique type. For example, consider this case:
2060- * ```
2061- * template<typename T>
2062- * struct S { T x; };
2063- *
2064- * S<int> s1;
2065- * S<char> s2;
2066- * ```
2067- * In this case the canonical field corresponding to `S::x` has two types:
2068- * `int` and `char`.
2069- */
2070- Type getAType ( ) { result = this .getAField ( ) .getType ( ) }
2071-
2072- Type getAnUnspecifiedType ( ) { result = this .getAType ( ) .getUnspecifiedType ( ) }
2073- }
2074-
2075- private class NonLocalCanonicalField extends CanonicalField {
2076- Class declaringType ;
2077-
2078- NonLocalCanonicalField ( ) {
2079- declaringType = this .getDeclaringType ( ) and
2080- not declaringType .isFromTemplateInstantiation ( _) and
2081- not declaringType .isLocal ( ) // handled in LocalCanonicalField
2082- }
2083-
2084- override Field getAField ( ) {
2085- exists ( Class c | result .getDeclaringType ( ) = c |
2086- // Either the declaring class of the field is a template instantiation
2087- // that has been constructed from this canonical declaration
2088- c .isConstructedFrom ( declaringType ) and
2089- pragma [ only_bind_out ] ( result .getName ( ) ) = pragma [ only_bind_out ] ( this .getName ( ) )
2090- or
2091- // or this canonical declaration is not a template.
2092- not c .isConstructedFrom ( _) and
2093- result = this
2094- )
2095- }
2096-
2097- override Class getADeclaringType ( ) {
2098- result = this .getDeclaringType ( )
2099- or
2100- result .isConstructedFrom ( this .getDeclaringType ( ) )
2101- }
2102- }
2103-
2104- private class LocalCanonicalField extends CanonicalField {
2105- Class declaringType ;
2106-
2107- LocalCanonicalField ( ) {
2108- declaringType = this .getDeclaringType ( ) and
2109- declaringType .isLocal ( )
2110- }
2111-
2112- override Field getAField ( ) { result = this }
2113-
2114- override Class getADeclaringType ( ) { result = declaringType }
2115- }
2116-
2117- /**
2118- * A canonical representation of a `Union`. See `CanonicalField` for the explanation for
2119- * why we need a canonical representation.
2120- */
2121- abstract private class CanonicalUnion extends Union {
2122- /** Gets a union represented by this canonical union. */
2123- abstract Union getAUnion ( ) ;
2124-
2125- /** Gets a canonical field of this canonical union. */
2126- CanonicalField getACanonicalField ( ) { result .getDeclaringType ( ) = this }
2127- }
2128-
2129- private class NonLocalCanonicalUnion extends CanonicalUnion {
2130- NonLocalCanonicalUnion ( ) { not this .isFromTemplateInstantiation ( _) and not this .isLocal ( ) }
2131-
2132- override Union getAUnion ( ) {
2133- result = this
2134- or
2135- result .isConstructedFrom ( this )
2136- }
2137- }
2138-
2139- private class LocalCanonicalUnion extends CanonicalUnion {
2140- LocalCanonicalUnion ( ) { this .isLocal ( ) }
2141-
2142- override Union getAUnion ( ) { result = this }
2143- }
2144-
2145- bindingset [ f]
2146- pragma [ inline_late]
2147- private int getFieldSize ( CanonicalField f ) { result = max ( f .getAType ( ) .getSize ( ) ) }
2148-
2149- /**
2150- * Gets a field in the union `u` whose size
2151- * is `bytes` number of bytes.
2152- */
2153- private CanonicalField getAFieldWithSize ( CanonicalUnion u , int bytes ) {
2154- result = u .getACanonicalField ( ) and
2155- bytes = getFieldSize ( result )
2156- }
2157-
2158- cached
2159- private newtype TContent =
2160- TNonUnionContent ( CanonicalField f , int indirectionIndex ) {
2161- // the indirection index for field content starts at 1 (because `TNonUnionContent` is thought of as
2162- // the address of the field, `FieldAddress` in the IR).
2163- indirectionIndex = [ 1 .. max ( SsaImpl:: getMaxIndirectionsForType ( f .getAnUnspecifiedType ( ) ) ) ] and
2164- // Reads and writes of union fields are tracked using `UnionContent`.
2165- not f .getDeclaringType ( ) instanceof Union
2166- } or
2167- TUnionContent ( CanonicalUnion u , int bytes , int indirectionIndex ) {
2168- exists ( CanonicalField f |
2169- f = u .getACanonicalField ( ) and
2170- bytes = getFieldSize ( f ) and
2171- // We key `UnionContent` by the union instead of its fields since a write to one
2172- // field can be read by any read of the union's fields. Again, the indirection index
2173- // is 1-based (because 0 is considered the address).
2174- indirectionIndex =
2175- [ 1 .. max ( SsaImpl:: getMaxIndirectionsForType ( getAFieldWithSize ( u , bytes )
2176- .getAnUnspecifiedType ( ) )
2177- ) ]
2178- )
2179- } or
2180- TElementContent ( int indirectionIndex ) {
2181- indirectionIndex = [ 1 .. getMaxElementContentIndirectionIndex ( ) ]
2182- }
21832032
21842033/**
21852034 * A description of the way data may be stored inside an object. Examples
0 commit comments