@@ -112,7 +112,7 @@ class Node extends TIRDataFlowNode {
112
112
Declaration getFunction ( ) { none ( ) } // overridden in subclasses
113
113
114
114
/** Gets the type of this node. */
115
- IRType getType ( ) { none ( ) } // overridden in subclasses
115
+ DataFlowType getType ( ) { none ( ) } // overridden in subclasses
116
116
117
117
/** Gets the instruction corresponding to this node, if any. */
118
118
Instruction asInstruction ( ) { result = this .( InstructionNode ) .getInstruction ( ) }
@@ -272,7 +272,7 @@ class Node extends TIRDataFlowNode {
272
272
/**
273
273
* Gets an upper bound on the type of this node.
274
274
*/
275
- IRType getTypeBound ( ) { result = this .getType ( ) }
275
+ DataFlowType getTypeBound ( ) { result = this .getType ( ) }
276
276
277
277
/** Gets the location of this element. */
278
278
cached
@@ -321,7 +321,7 @@ class InstructionNode extends Node, TInstructionNode {
321
321
322
322
override Declaration getFunction ( ) { result = instr .getEnclosingFunction ( ) }
323
323
324
- override IRType getType ( ) { result = instr .getResultIRType ( ) }
324
+ override DataFlowType getType ( ) { result = instr .getResultType ( ) }
325
325
326
326
final override Location getLocationImpl ( ) { result = instr .getLocation ( ) }
327
327
@@ -347,13 +347,32 @@ class OperandNode extends Node, TOperandNode {
347
347
348
348
override Declaration getFunction ( ) { result = op .getUse ( ) .getEnclosingFunction ( ) }
349
349
350
- override IRType getType ( ) { result = op .getIRType ( ) }
350
+ override DataFlowType getType ( ) { result = op .getType ( ) }
351
351
352
352
final override Location getLocationImpl ( ) { result = op .getLocation ( ) }
353
353
354
354
override string toStringImpl ( ) { result = this .getOperand ( ) .toString ( ) }
355
355
}
356
356
357
+ /**
358
+ * Returns `t`, but stripped of the `n` outermost pointers, references, etc.
359
+ *
360
+ * For example, `stripPointers(int*&, 2)` is `int` and `stripPointers(int*, 0)` is `int*`.
361
+ */
362
+ private Type stripPointers ( Type t , int n ) {
363
+ result = t and n = 0
364
+ or
365
+ result = stripPointers ( t .( PointerType ) .getBaseType ( ) , n - 1 )
366
+ or
367
+ result = stripPointers ( t .( ArrayType ) .getBaseType ( ) , n - 1 )
368
+ or
369
+ result = stripPointers ( t .( ReferenceType ) .getBaseType ( ) , n - 1 )
370
+ or
371
+ result = stripPointers ( t .( PointerToMemberType ) .getBaseType ( ) , n - 1 )
372
+ or
373
+ result = stripPointers ( t .( FunctionPointerIshType ) .getBaseType ( ) , n - 1 )
374
+ }
375
+
357
376
/**
358
377
* INTERNAL: do not use.
359
378
*
@@ -406,7 +425,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
406
425
407
426
override Declaration getFunction ( ) { result = phi .getBasicBlock ( ) .getEnclosingFunction ( ) }
408
427
409
- override IRType getType ( ) { result instanceof IRVoidType }
428
+ override DataFlowType getType ( ) { result = this . getAnInput ( ) . getType ( ) }
410
429
411
430
final override Location getLocationImpl ( ) { result = phi .getBasicBlock ( ) .getLocation ( ) }
412
431
@@ -449,8 +468,6 @@ class SideEffectOperandNode extends Node, IndirectOperand {
449
468
450
469
override Function getFunction ( ) { result = call .getEnclosingFunction ( ) }
451
470
452
- override IRType getType ( ) { result instanceof IRVoidType }
453
-
454
471
Expr getArgument ( ) { result = call .getArgument ( argumentIndex ) .getUnconvertedResultExpression ( ) }
455
472
}
456
473
@@ -473,8 +490,6 @@ class IndirectParameterNode extends Node, IndirectInstruction {
473
490
474
491
override Function getFunction ( ) { result = this .getInstruction ( ) .getEnclosingFunction ( ) }
475
492
476
- override IRType getType ( ) { result instanceof IRVoidType }
477
-
478
493
override string toStringImpl ( ) {
479
494
result = this .getParameter ( ) .toString ( ) + " indirection"
480
495
or
@@ -499,8 +514,6 @@ class IndirectReturnNode extends IndirectOperand {
499
514
Operand getAddressOperand ( ) { result = operand }
500
515
501
516
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
502
-
503
- override IRType getType ( ) { result instanceof IRVoidType }
504
517
}
505
518
506
519
/**
@@ -587,6 +600,23 @@ class IndirectReturnOutNode extends Node {
587
600
int getIndirectionIndex ( ) { result = indirectionIndex }
588
601
}
589
602
603
+ private PointerType getGLValueType ( Type t , int indirectionIndex ) {
604
+ result .getBaseType ( ) = stripPointers ( t , indirectionIndex - 1 )
605
+ }
606
+
607
+ bindingset [ isGLValue]
608
+ private DataFlowType getType0 ( Type t , int indirectionIndex , boolean isGLValue ) {
609
+ if isGLValue = true
610
+ then
611
+ result = getGLValueType ( t , indirectionIndex )
612
+ or
613
+ // If the `PointerType` with the correct base type isn't in the database we cannot
614
+ // return a correct type. So instead we'll return a value that has "one indirection too little".
615
+ not exists ( getGLValueType ( t , indirectionIndex ) ) and
616
+ result = stripPointers ( t , indirectionIndex - 1 )
617
+ else result = stripPointers ( t , indirectionIndex )
618
+ }
619
+
590
620
/**
591
621
* INTERNAL: Do not use.
592
622
*
@@ -608,7 +638,11 @@ class IndirectOperand extends Node, TIndirectOperand {
608
638
609
639
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
610
640
611
- override IRType getType ( ) { result = this .getOperand ( ) .getIRType ( ) }
641
+ override DataFlowType getType ( ) {
642
+ exists ( boolean isGLValue | if operand .isGLValue ( ) then isGLValue = true else isGLValue = false |
643
+ result = getType0 ( operand .getType ( ) .getUnspecifiedType ( ) , indirectionIndex , isGLValue )
644
+ )
645
+ }
612
646
613
647
final override Location getLocationImpl ( ) { result = this .getOperand ( ) .getLocation ( ) }
614
648
@@ -638,7 +672,11 @@ class IndirectInstruction extends Node, TIndirectInstruction {
638
672
639
673
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
640
674
641
- override IRType getType ( ) { result = this .getInstruction ( ) .getResultIRType ( ) }
675
+ override DataFlowType getType ( ) {
676
+ exists ( boolean isGLValue | if instr .isGLValue ( ) then isGLValue = true else isGLValue = false |
677
+ result = getType0 ( instr .getResultType ( ) .getUnspecifiedType ( ) , indirectionIndex , isGLValue )
678
+ )
679
+ }
642
680
643
681
final override Location getLocationImpl ( ) { result = this .getInstruction ( ) .getLocation ( ) }
644
682
@@ -852,6 +890,8 @@ abstract class PostUpdateNode extends Node {
852
890
* Gets the node before the state update.
853
891
*/
854
892
abstract Node getPreUpdateNode ( ) ;
893
+
894
+ final override Type getType ( ) { result = this .getPreUpdateNode ( ) .getType ( ) }
855
895
}
856
896
857
897
/**
@@ -915,7 +955,7 @@ class VariableNode extends Node, TVariableNode {
915
955
result = v
916
956
}
917
957
918
- override IRType getType ( ) { result . getCanonicalLanguageType ( ) . hasUnspecifiedType ( v .getType ( ) , _ ) }
958
+ override DataFlowType getType ( ) { result = v .getType ( ) }
919
959
920
960
final override Location getLocationImpl ( ) { result = v .getLocation ( ) }
921
961
0 commit comments