@@ -139,6 +139,20 @@ class AllocationInstruction extends CallInstruction {
139139 AllocationInstruction ( ) { this .getStaticCallTarget ( ) instanceof Cpp:: AllocationFunction }
140140}
141141
142+ private predicate isIndirectionType ( Type t ) { t instanceof Indirection }
143+
144+ private predicate hasUnspecifiedBaseType ( Indirection t , Type base ) {
145+ base = t .getBaseType ( ) .getUnspecifiedType ( )
146+ }
147+
148+ /**
149+ * Holds if `t2` is the same type as `t1`, but after stripping away `result` number
150+ * of indirections.
151+ * Furthermore, specifies in `t2` been deeply stripped and typedefs has been resolved.
152+ */
153+ private int getNumberOfIndirectionsImpl ( Type t1 , Type t2 ) =
154+ shortestDistances( isIndirectionType / 1 , hasUnspecifiedBaseType / 2 ) ( t1 , t2 , result )
155+
142156/**
143157 * An abstract class for handling indirections.
144158 *
@@ -157,7 +171,10 @@ abstract class Indirection extends Type {
157171 * For example, the number of indirections of a variable `p` of type
158172 * `int**` is `3` (i.e., `p`, `*p` and `**p`).
159173 */
160- abstract int getNumberOfIndirections ( ) ;
174+ final int getNumberOfIndirections ( ) {
175+ result =
176+ getNumberOfIndirectionsImpl ( this .getType ( ) , any ( Type end | not end instanceof Indirection ) )
177+ }
161178
162179 /**
163180 * Holds if `deref` is an instruction that behaves as a `LoadInstruction`
@@ -195,19 +212,11 @@ private class PointerOrArrayOrReferenceTypeIndirection extends Indirection insta
195212 PointerOrArrayOrReferenceTypeIndirection ( ) {
196213 baseType = PointerOrArrayOrReferenceType .super .getBaseType ( )
197214 }
198-
199- override int getNumberOfIndirections ( ) {
200- result = 1 + countIndirections ( this .getBaseType ( ) .getUnspecifiedType ( ) )
201- }
202215}
203216
204217private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper {
205218 PointerWrapperTypeIndirection ( ) { baseType = PointerWrapper .super .getBaseType ( ) }
206219
207- override int getNumberOfIndirections ( ) {
208- result = 1 + countIndirections ( this .getBaseType ( ) .getUnspecifiedType ( ) )
209- }
210-
211220 override predicate isAdditionalDereference ( Instruction deref , Operand address ) {
212221 exists ( CallInstruction call |
213222 operandForFullyConvertedCall ( getAUse ( deref ) , call ) and
@@ -228,10 +237,6 @@ private module IteratorIndirections {
228237 baseType = super .getValueType ( )
229238 }
230239
231- override int getNumberOfIndirections ( ) {
232- result = 1 + countIndirections ( this .getBaseType ( ) .getUnspecifiedType ( ) )
233- }
234-
235240 override predicate isAdditionalDereference ( Instruction deref , Operand address ) {
236241 exists ( CallInstruction call |
237242 operandForFullyConvertedCall ( getAUse ( deref ) , call ) and
0 commit comments