@@ -38,13 +38,12 @@ private module Cached {
38
38
TVariableNode ( Variable var ) or
39
39
TPostFieldUpdateNode ( FieldAddress operand , int indirectionIndex ) {
40
40
indirectionIndex =
41
- [ 0 .. Ssa:: countIndirectionsForCppType ( operand .getObjectAddress ( ) .getResultLanguageType ( ) ) -
42
- 1 ]
41
+ [ 1 .. Ssa:: countIndirectionsForCppType ( operand .getObjectAddress ( ) .getResultLanguageType ( ) ) ]
43
42
} or
44
43
TSsaPhiNode ( Ssa:: PhiNode phi ) or
45
44
TIndirectArgumentOutNode ( ArgumentOperand operand , int indirectionIndex ) {
46
45
Ssa:: isModifiableByCall ( operand ) and
47
- indirectionIndex = [ 0 .. Ssa:: countIndirectionsForCppType ( operand .getLanguageType ( ) ) - 1 ]
46
+ indirectionIndex = [ 1 .. Ssa:: countIndirectionsForCppType ( operand .getLanguageType ( ) ) ]
48
47
} or
49
48
TIndirectOperand ( Operand op , int indirectionIndex ) {
50
49
Ssa:: hasIndirectOperand ( op , indirectionIndex )
@@ -113,7 +112,7 @@ class Node extends TIRDataFlowNode {
113
112
Declaration getFunction ( ) { none ( ) } // overridden in subclasses
114
113
115
114
/** Gets the type of this node. */
116
- IRType getType ( ) { none ( ) } // overridden in subclasses
115
+ DataFlowType getType ( ) { none ( ) } // overridden in subclasses
117
116
118
117
/** Gets the instruction corresponding to this node, if any. */
119
118
Instruction asInstruction ( ) { result = this .( InstructionNode ) .getInstruction ( ) }
@@ -273,7 +272,7 @@ class Node extends TIRDataFlowNode {
273
272
/**
274
273
* Gets an upper bound on the type of this node.
275
274
*/
276
- IRType getTypeBound ( ) { result = this .getType ( ) }
275
+ DataFlowType getTypeBound ( ) { result = this .getType ( ) }
277
276
278
277
/** Gets the location of this element. */
279
278
cached
@@ -322,7 +321,7 @@ class InstructionNode extends Node, TInstructionNode {
322
321
323
322
override Declaration getFunction ( ) { result = instr .getEnclosingFunction ( ) }
324
323
325
- override IRType getType ( ) { result = instr .getResultIRType ( ) }
324
+ override DataFlowType getType ( ) { result = instr .getResultType ( ) }
326
325
327
326
final override Location getLocationImpl ( ) { result = instr .getLocation ( ) }
328
327
@@ -348,13 +347,32 @@ class OperandNode extends Node, TOperandNode {
348
347
349
348
override Declaration getFunction ( ) { result = op .getUse ( ) .getEnclosingFunction ( ) }
350
349
351
- override IRType getType ( ) { result = op .getIRType ( ) }
350
+ override DataFlowType getType ( ) { result = op .getType ( ) }
352
351
353
352
final override Location getLocationImpl ( ) { result = op .getLocation ( ) }
354
353
355
354
override string toStringImpl ( ) { result = this .getOperand ( ) .toString ( ) }
356
355
}
357
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
+
358
376
/**
359
377
* INTERNAL: do not use.
360
378
*
@@ -370,19 +388,15 @@ class PostFieldUpdateNode extends TPostFieldUpdateNode, PartialDefinitionNode {
370
388
371
389
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
372
390
373
- override IRType getType ( ) { result = fieldAddress .getIRType ( ) }
374
-
375
391
FieldAddress getFieldAddress ( ) { result = fieldAddress }
376
392
377
393
Field getUpdatedField ( ) { result = fieldAddress .getField ( ) }
378
394
379
395
int getIndirectionIndex ( ) { result = indirectionIndex }
380
396
381
397
override Node getPreUpdateNode ( ) {
382
- // + 1 because we're storing into an lvalue, and the original node should be the rvalue of
383
- // the same address.
384
398
hasOperandAndIndex ( result , pragma [ only_bind_into ] ( fieldAddress ) .getObjectAddressOperand ( ) ,
385
- indirectionIndex + 1 )
399
+ indirectionIndex )
386
400
}
387
401
388
402
override Expr getDefinedExpr ( ) {
@@ -411,7 +425,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
411
425
412
426
override Declaration getFunction ( ) { result = phi .getBasicBlock ( ) .getEnclosingFunction ( ) }
413
427
414
- override IRType getType ( ) { result instanceof IRVoidType }
428
+ override DataFlowType getType ( ) { result = this . getAnInput ( ) . getType ( ) }
415
429
416
430
final override Location getLocationImpl ( ) { result = phi .getBasicBlock ( ) .getLocation ( ) }
417
431
@@ -454,8 +468,6 @@ class SideEffectOperandNode extends Node, IndirectOperand {
454
468
455
469
override Function getFunction ( ) { result = call .getEnclosingFunction ( ) }
456
470
457
- override IRType getType ( ) { result instanceof IRVoidType }
458
-
459
471
Expr getArgument ( ) { result = call .getArgument ( argumentIndex ) .getUnconvertedResultExpression ( ) }
460
472
}
461
473
@@ -478,8 +490,6 @@ class IndirectParameterNode extends Node, IndirectInstruction {
478
490
479
491
override Function getFunction ( ) { result = this .getInstruction ( ) .getEnclosingFunction ( ) }
480
492
481
- override IRType getType ( ) { result instanceof IRVoidType }
482
-
483
493
override string toStringImpl ( ) {
484
494
result = this .getParameter ( ) .toString ( ) + " indirection"
485
495
or
@@ -504,8 +514,6 @@ class IndirectReturnNode extends IndirectOperand {
504
514
Operand getAddressOperand ( ) { result = operand }
505
515
506
516
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
507
-
508
- override IRType getType ( ) { result instanceof IRVoidType }
509
517
}
510
518
511
519
/**
@@ -536,9 +544,7 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PostUpdate
536
544
537
545
override Function getFunction ( ) { result = this .getCallInstruction ( ) .getEnclosingFunction ( ) }
538
546
539
- override IRType getType ( ) { result instanceof IRVoidType }
540
-
541
- override Node getPreUpdateNode ( ) { hasOperandAndIndex ( result , operand , indirectionIndex + 1 ) }
547
+ override Node getPreUpdateNode ( ) { hasOperandAndIndex ( result , operand , indirectionIndex ) }
542
548
543
549
override string toStringImpl ( ) {
544
550
// This string should be unique enough to be helpful but common enough to
@@ -594,6 +600,38 @@ class IndirectReturnOutNode extends Node {
594
600
int getIndirectionIndex ( ) { result = indirectionIndex }
595
601
}
596
602
603
+ private PointerType getGLValueType ( Type t , int indirectionIndex ) {
604
+ result .getBaseType ( ) = stripPointers ( t , indirectionIndex - 1 )
605
+ }
606
+
607
+ bindingset [ isGLValue]
608
+ private DataFlowType getTypeImpl ( Type t , int indirectionIndex , boolean isGLValue ) {
609
+ if isGLValue = true
610
+ then
611
+ result = getGLValueType ( t , indirectionIndex )
612
+ or
613
+ // Ideally, the above case would cover all glvalue cases. However, consider the case where
614
+ // the database consists only of:
615
+ // ```
616
+ // void test() {
617
+ // int* x;
618
+ // x = nullptr;
619
+ // }
620
+ // ```
621
+ // and we want to compute the type of `*x` in the assignment `x = nullptr`. Here, `x` is an lvalue
622
+ // of type int* (which morally is an int**). So when we call `getTypeImpl` it will be with the
623
+ // parameters:
624
+ // - t = int*
625
+ // - indirectionIndex = 1 (when we want to model the dataflow node corresponding to *x)
626
+ // - isGLValue = true
627
+ // In this case, `getTypeImpl(t, indirectionIndex, isGLValue)` should give back `int**`. In this
628
+ // case, however, `int**` does not exist in the database. So instead we return int* (which is
629
+ // wrong, but at least we have a type).
630
+ not exists ( getGLValueType ( t , indirectionIndex ) ) and
631
+ result = stripPointers ( t , indirectionIndex - 1 )
632
+ else result = stripPointers ( t , indirectionIndex )
633
+ }
634
+
597
635
/**
598
636
* INTERNAL: Do not use.
599
637
*
@@ -615,7 +653,11 @@ class IndirectOperand extends Node, TIndirectOperand {
615
653
616
654
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
617
655
618
- override IRType getType ( ) { result = this .getOperand ( ) .getIRType ( ) }
656
+ override DataFlowType getType ( ) {
657
+ exists ( boolean isGLValue | if operand .isGLValue ( ) then isGLValue = true else isGLValue = false |
658
+ result = getTypeImpl ( operand .getType ( ) .getUnspecifiedType ( ) , indirectionIndex , isGLValue )
659
+ )
660
+ }
619
661
620
662
final override Location getLocationImpl ( ) { result = this .getOperand ( ) .getLocation ( ) }
621
663
@@ -645,7 +687,11 @@ class IndirectInstruction extends Node, TIndirectInstruction {
645
687
646
688
override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
647
689
648
- override IRType getType ( ) { result = this .getInstruction ( ) .getResultIRType ( ) }
690
+ override DataFlowType getType ( ) {
691
+ exists ( boolean isGLValue | if instr .isGLValue ( ) then isGLValue = true else isGLValue = false |
692
+ result = getTypeImpl ( instr .getResultType ( ) .getUnspecifiedType ( ) , indirectionIndex , isGLValue )
693
+ )
694
+ }
649
695
650
696
final override Location getLocationImpl ( ) { result = this .getInstruction ( ) .getLocation ( ) }
651
697
@@ -859,6 +905,8 @@ abstract class PostUpdateNode extends Node {
859
905
* Gets the node before the state update.
860
906
*/
861
907
abstract Node getPreUpdateNode ( ) ;
908
+
909
+ final override DataFlowType getType ( ) { result = this .getPreUpdateNode ( ) .getType ( ) }
862
910
}
863
911
864
912
/**
@@ -922,7 +970,7 @@ class VariableNode extends Node, TVariableNode {
922
970
result = v
923
971
}
924
972
925
- override IRType getType ( ) { result . getCanonicalLanguageType ( ) . hasUnspecifiedType ( v .getType ( ) , _ ) }
973
+ override DataFlowType getType ( ) { result = v .getType ( ) }
926
974
927
975
final override Location getLocationImpl ( ) { result = v .getLocation ( ) }
928
976
@@ -1075,7 +1123,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
1075
1123
store .getDestinationAddressOperand ( ) = address
1076
1124
)
1077
1125
or
1078
- Ssa:: outNodeHasAddressAndIndex ( nodeFrom , address , indirectionIndex - 1 )
1126
+ Ssa:: outNodeHasAddressAndIndex ( nodeFrom , address , indirectionIndex )
1079
1127
)
1080
1128
}
1081
1129
0 commit comments