@@ -236,63 +236,13 @@ private Type getArgumentOrReturnType(Method m, int i) {
236236}
237237
238238/**
239- * INTERNAL: Do not use.
240- *
241239 * Provides an implementation of Global Value Numbering for types
242240 * (see https://en.wikipedia.org/wiki/Global_value_numbering), where
243241 * types are considered equal modulo identity conversions and method
244242 * type parameters (at the same index).
245243 */
246- module Gvn {
247- private newtype TCompoundTypeKind =
248- TPointerTypeKind ( ) or
249- TNullableTypeKind ( ) or
250- TArrayTypeKind ( int dim , int rnk ) {
251- exists ( ArrayType at | dim = at .getDimension ( ) and rnk = at .getRank ( ) )
252- } or
253- TConstructedType ( UnboundGenericType ugt )
254-
255- /** A type kind for a compound type. */
256- class CompoundTypeKind extends TCompoundTypeKind {
257- int getNumberOfTypeParameters ( ) {
258- this = TPointerTypeKind ( ) and result = 1
259- or
260- this = TNullableTypeKind ( ) and result = 1
261- or
262- this = TArrayTypeKind ( _, _) and result = 1
263- or
264- exists ( UnboundGenericType ugt | this = TConstructedType ( ugt ) |
265- result = ugt .getNumberOfTypeParameters ( )
266- )
267- }
268-
269- string toString ( ) {
270- this = TPointerTypeKind ( ) and result = "*"
271- or
272- this = TNullableTypeKind ( ) and result = "?"
273- or
274- exists ( int dim , int rnk | this = TArrayTypeKind ( dim , rnk ) |
275- result = "[" + dim + ", " + rnk + "]"
276- )
277- or
278- exists ( UnboundGenericType ugt | this = TConstructedType ( ugt ) |
279- result = ugt .getNameWithoutBrackets ( )
280- )
281- }
282-
283- Location getLocation ( ) { result instanceof EmptyLocation }
284- }
285-
286- /** Gets the type kind for type `t`, if any. */
287- CompoundTypeKind getTypeKind ( Type t ) {
288- result = TPointerTypeKind ( ) and t instanceof PointerType
289- or
290- result = TNullableTypeKind ( ) and t instanceof NullableType
291- or
292- t = any ( ArrayType at | result = TArrayTypeKind ( at .getDimension ( ) , at .getRank ( ) ) )
293- or
294- result = TConstructedType ( t .( ConstructedType ) .getUnboundGeneric ( ) )
295- }
244+ private module Gvn {
245+ private import semmle.code.csharp.Unification
296246
297247 private class MethodTypeParameter extends TypeParameter {
298248 MethodTypeParameter ( ) { this = any ( UnboundGenericMethod ugm ) .getATypeParameter ( ) }
@@ -310,38 +260,47 @@ module Gvn {
310260 private newtype TGvnType =
311261 TLeafGvnType ( int i ) { id ( _, i ) } or
312262 TMethodTypeParameterGvnType ( int i ) { i = any ( MethodTypeParameter p ) .getIndex ( ) } or
313- TConstructedGvnType ( TConstructedGvnType0 t )
263+ TConstructedGvnType ( ConstructedGvnTypeList l )
314264
315- private newtype TConstructedGvnType0 =
265+ private newtype TConstructedGvnTypeList =
316266 TConstructedGvnTypeNil ( CompoundTypeKind k ) or
317- TConstructedGvnTypeCons ( TGvnType head , TConstructedGvnType0 tail ) {
318- gvnConstructedCons ( _, _, head , tail )
267+ TConstructedGvnTypeCons ( GvnType head , ConstructedGvnTypeList tail ) {
268+ gvnConstructedCons ( _, _, _ , head , tail )
319269 }
320270
321- private TConstructedGvnType0 gvnConstructed ( Type t , int i ) {
322- result = TConstructedGvnTypeNil ( getTypeKind ( t ) ) and i = - 1
271+ private ConstructedGvnTypeList gvnConstructed ( Type t , CompoundTypeKind k , int i ) {
272+ result = TConstructedGvnTypeNil ( k ) and
273+ i = - 1 and
274+ k = getTypeKind ( t )
323275 or
324- exists ( TGvnType head , TConstructedGvnType0 tail | gvnConstructedCons ( t , i , head , tail ) |
276+ exists ( GvnType head , ConstructedGvnTypeList tail | gvnConstructedCons ( t , k , i , head , tail ) |
325277 result = TConstructedGvnTypeCons ( head , tail )
326278 )
327279 }
328280
329281 pragma [ noinline]
330- private TGvnType gvnTypeChild ( Type t , int i ) { result = getGlobalValueNumber ( t .getChild ( i ) ) }
282+ private GvnType gvnTypeChild ( Type t , int i ) { result = getGlobalValueNumber ( t .getChild ( i ) ) }
331283
332284 pragma [ noinline]
333- private predicate gvnConstructedCons ( Type t , int i , TGvnType head , TConstructedGvnType0 tail ) {
334- tail = gvnConstructed ( t , i - 1 ) and
285+ private predicate gvnConstructedCons (
286+ Type t , CompoundTypeKind k , int i , GvnType head , ConstructedGvnTypeList tail
287+ ) {
288+ tail = gvnConstructed ( t , k , i - 1 ) and
335289 head = gvnTypeChild ( t , i )
336290 }
337291
338292 /** Gets the global value number for a given type. */
293+ pragma [ nomagic]
339294 GvnType getGlobalValueNumber ( Type t ) {
340295 result = TLeafGvnType ( any ( int i | id ( t , i ) ) )
341296 or
342297 result = TMethodTypeParameterGvnType ( t .( MethodTypeParameter ) .getIndex ( ) )
343298 or
344- result = TConstructedGvnType ( gvnConstructed ( t , getTypeKind ( t ) .getNumberOfTypeParameters ( ) - 1 ) )
299+ exists ( ConstructedGvnTypeList l , CompoundTypeKind k , int i |
300+ l = gvnConstructed ( t , k , i ) and
301+ i = k .getNumberOfTypeParameters ( ) - 1 and
302+ result = TConstructedGvnType ( l )
303+ )
345304 }
346305
347306 /** A global value number for a type. */
@@ -351,40 +310,42 @@ module Gvn {
351310 or
352311 exists ( int i | this = TMethodTypeParameterGvnType ( i ) | result = "M!" + i )
353312 or
354- exists ( GvnConstructedType t | this = TConstructedGvnType ( t ) | result = t .toString ( ) )
313+ exists ( ConstructedGvnTypeList l | this = TConstructedGvnType ( l ) | result = l .toString ( ) )
355314 }
356315
357316 Location getLocation ( ) { result instanceof EmptyLocation }
358317 }
359318
360- /** A global value number for a constructed type. */
361- class GvnConstructedType extends TConstructedGvnType0 {
362- private CompoundTypeKind getKind ( ) {
363- this = TConstructedGvnTypeNil ( result )
319+ private class ConstructedGvnTypeList extends TConstructedGvnTypeList {
320+ private int length ( ) {
321+ this = TConstructedGvnTypeNil ( _) and result = - 1
364322 or
365- exists ( GvnConstructedType tail | this = TConstructedGvnTypeCons ( _, tail ) |
366- result = tail .getKind ( )
323+ exists ( ConstructedGvnTypeList tail | this = TConstructedGvnTypeCons ( _, tail ) |
324+ result = tail .length ( ) + 1
367325 )
368326 }
369327
370328 private GvnType getArg ( int i ) {
371- this = TConstructedGvnTypeCons ( result , TConstructedGvnTypeNil ( _) ) and
372- i = 0
373- or
374- exists ( GvnConstructedType tail | this = TConstructedGvnTypeCons ( result , tail ) |
375- exists ( tail .getArg ( i - 1 ) )
329+ exists ( GvnType head , ConstructedGvnTypeList tail |
330+ this = TConstructedGvnTypeCons ( head , tail )
331+ |
332+ result = head and
333+ i = this .length ( )
334+ or
335+ result = tail .getArg ( i )
376336 )
377337 }
378338
379339 language [ monotonicAggregates]
380340 string toString ( ) {
381- exists ( CompoundTypeKind k | k = this .getKind ( ) |
382- result = k + "<" +
383- concat ( int i |
384- i in [ 0 .. k .getNumberOfTypeParameters ( ) - 1 ]
385- |
386- this .getArg ( i ) .toString ( ) , ", "
387- ) + ">"
341+ exists ( CompoundTypeKind k , string args |
342+ this = gvnConstructed ( _, k , _) and
343+ args = concat ( int i |
344+ i in [ 0 .. k .getNumberOfTypeParameters ( ) - 1 ]
345+ |
346+ this .getArg ( i ) .toString ( ) , ", " order by i
347+ ) and
348+ result = k .toString ( args )
388349 )
389350 }
390351
0 commit comments