@@ -144,6 +144,20 @@ class AllocationInstruction extends CallInstruction {
144144 AllocationInstruction ( ) { this .getStaticCallTarget ( ) instanceof Cpp:: AllocationFunction }
145145}
146146
147+ private predicate isIndirectionType ( Type t ) { t instanceof Indirection }
148+
149+ private predicate hasUnspecifiedBaseType ( Indirection t , Type base ) {
150+ base = t .getBaseType ( ) .getUnspecifiedType ( )
151+ }
152+
153+ /**
154+ * Holds if `t2` is the same type as `t1`, but after stripping away `result` number
155+ * of indirections.
156+ * Furthermore, specifies in `t2` been deeply stripped and typedefs has been resolved.
157+ */
158+ private int getNumberOfIndirectionsImpl ( Type t1 , Type t2 ) =
159+ shortestDistances( isIndirectionType / 1 , hasUnspecifiedBaseType / 2 ) ( t1 , t2 , result )
160+
147161/**
148162 * An abstract class for handling indirections.
149163 *
@@ -162,7 +176,10 @@ abstract class Indirection extends Type {
162176 * For example, the number of indirections of a variable `p` of type
163177 * `int**` is `3` (i.e., `p`, `*p` and `**p`).
164178 */
165- abstract int getNumberOfIndirections ( ) ;
179+ final int getNumberOfIndirections ( ) {
180+ result =
181+ getNumberOfIndirectionsImpl ( this .getType ( ) , any ( Type end | not end instanceof Indirection ) )
182+ }
166183
167184 /**
168185 * Holds if `deref` is an instruction that behaves as a `LoadInstruction`
@@ -200,19 +217,11 @@ private class PointerOrArrayOrReferenceTypeIndirection extends Indirection insta
200217 PointerOrArrayOrReferenceTypeIndirection ( ) {
201218 baseType = PointerOrArrayOrReferenceType .super .getBaseType ( )
202219 }
203-
204- override int getNumberOfIndirections ( ) {
205- result = 1 + countIndirections ( this .getBaseType ( ) .getUnspecifiedType ( ) )
206- }
207220}
208221
209222private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper {
210223 PointerWrapperTypeIndirection ( ) { baseType = PointerWrapper .super .getBaseType ( ) }
211224
212- override int getNumberOfIndirections ( ) {
213- result = 1 + countIndirections ( this .getBaseType ( ) .getUnspecifiedType ( ) )
214- }
215-
216225 override predicate isAdditionalDereference ( Instruction deref , Operand address ) {
217226 exists ( CallInstruction call |
218227 operandForFullyConvertedCall ( getAUse ( deref ) , call ) and
@@ -233,10 +242,6 @@ private module IteratorIndirections {
233242 baseType = super .getValueType ( )
234243 }
235244
236- override int getNumberOfIndirections ( ) {
237- result = 1 + countIndirections ( this .getBaseType ( ) .getUnspecifiedType ( ) )
238- }
239-
240245 override predicate isAdditionalDereference ( Instruction deref , Operand address ) {
241246 exists ( CallInstruction call |
242247 operandForFullyConvertedCall ( getAUse ( deref ) , call ) and
0 commit comments