@@ -112,7 +112,7 @@ class Node extends TIRDataFlowNode {
112112 Declaration getFunction ( ) { none ( ) } // overridden in subclasses
113113
114114 /** Gets the type of this node. */
115- IRType getType ( ) { none ( ) } // overridden in subclasses
115+ DataFlowType getType ( ) { none ( ) } // overridden in subclasses
116116
117117 /** Gets the instruction corresponding to this node, if any. */
118118 Instruction asInstruction ( ) { result = this .( InstructionNode ) .getInstruction ( ) }
@@ -272,7 +272,7 @@ class Node extends TIRDataFlowNode {
272272 /**
273273 * Gets an upper bound on the type of this node.
274274 */
275- IRType getTypeBound ( ) { result = this .getType ( ) }
275+ DataFlowType getTypeBound ( ) { result = this .getType ( ) }
276276
277277 /** Gets the location of this element. */
278278 cached
@@ -321,7 +321,7 @@ class InstructionNode extends Node, TInstructionNode {
321321
322322 override Declaration getFunction ( ) { result = instr .getEnclosingFunction ( ) }
323323
324- override IRType getType ( ) { result = instr .getResultIRType ( ) }
324+ override DataFlowType getType ( ) { result = instr .getResultType ( ) }
325325
326326 final override Location getLocationImpl ( ) { result = instr .getLocation ( ) }
327327
@@ -347,13 +347,32 @@ class OperandNode extends Node, TOperandNode {
347347
348348 override Declaration getFunction ( ) { result = op .getUse ( ) .getEnclosingFunction ( ) }
349349
350- override IRType getType ( ) { result = op .getIRType ( ) }
350+ override DataFlowType getType ( ) { result = op .getType ( ) }
351351
352352 final override Location getLocationImpl ( ) { result = op .getLocation ( ) }
353353
354354 override string toStringImpl ( ) { result = this .getOperand ( ) .toString ( ) }
355355}
356356
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+
357376/**
358377 * INTERNAL: do not use.
359378 *
@@ -406,7 +425,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
406425
407426 override Declaration getFunction ( ) { result = phi .getBasicBlock ( ) .getEnclosingFunction ( ) }
408427
409- override IRType getType ( ) { result instanceof IRVoidType }
428+ override DataFlowType getType ( ) { result = this . getAnInput ( ) . getType ( ) }
410429
411430 final override Location getLocationImpl ( ) { result = phi .getBasicBlock ( ) .getLocation ( ) }
412431
@@ -449,8 +468,6 @@ class SideEffectOperandNode extends Node, IndirectOperand {
449468
450469 override Function getFunction ( ) { result = call .getEnclosingFunction ( ) }
451470
452- override IRType getType ( ) { result instanceof IRVoidType }
453-
454471 Expr getArgument ( ) { result = call .getArgument ( argumentIndex ) .getUnconvertedResultExpression ( ) }
455472}
456473
@@ -473,8 +490,6 @@ class IndirectParameterNode extends Node, IndirectInstruction {
473490
474491 override Function getFunction ( ) { result = this .getInstruction ( ) .getEnclosingFunction ( ) }
475492
476- override IRType getType ( ) { result instanceof IRVoidType }
477-
478493 override string toStringImpl ( ) {
479494 result = this .getParameter ( ) .toString ( ) + " indirection"
480495 or
@@ -499,8 +514,6 @@ class IndirectReturnNode extends IndirectOperand {
499514 Operand getAddressOperand ( ) { result = operand }
500515
501516 override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
502-
503- override IRType getType ( ) { result instanceof IRVoidType }
504517}
505518
506519/**
@@ -587,6 +600,23 @@ class IndirectReturnOutNode extends Node {
587600 int getIndirectionIndex ( ) { result = indirectionIndex }
588601}
589602
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+
590620/**
591621 * INTERNAL: Do not use.
592622 *
@@ -608,7 +638,11 @@ class IndirectOperand extends Node, TIndirectOperand {
608638
609639 override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
610640
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+ }
612646
613647 final override Location getLocationImpl ( ) { result = this .getOperand ( ) .getLocation ( ) }
614648
@@ -638,7 +672,11 @@ class IndirectInstruction extends Node, TIndirectInstruction {
638672
639673 override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
640674
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+ }
642680
643681 final override Location getLocationImpl ( ) { result = this .getInstruction ( ) .getLocation ( ) }
644682
@@ -852,6 +890,8 @@ abstract class PostUpdateNode extends Node {
852890 * Gets the node before the state update.
853891 */
854892 abstract Node getPreUpdateNode ( ) ;
893+
894+ final override Type getType ( ) { result = this .getPreUpdateNode ( ) .getType ( ) }
855895}
856896
857897/**
@@ -915,7 +955,7 @@ class VariableNode extends Node, TVariableNode {
915955 result = v
916956 }
917957
918- override IRType getType ( ) { result . getCanonicalLanguageType ( ) . hasUnspecifiedType ( v .getType ( ) , _ ) }
958+ override DataFlowType getType ( ) { result = v .getType ( ) }
919959
920960 final override Location getLocationImpl ( ) { result = v .getLocation ( ) }
921961
0 commit comments