Skip to content

Commit 2591460

Browse files
authored
Merge pull request github#12181 from MathiasVP/fix-node-type
C++: Fix node types
2 parents 4ba5059 + b01a45f commit 2591460

File tree

4 files changed

+88
-11
lines changed

4 files changed

+88
-11
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,31 @@ class Node0Impl extends TIRDataFlowNode0 {
6969

7070
/** Gets a textual representation of this node. */
7171
final string toString() { result = this.toStringImpl() }
72+
73+
/** Holds if the value of this node is a glvalue */
74+
predicate isGLValue() { none() } // overridden in subclasses
75+
}
76+
77+
/**
78+
* Gets the type of the operand `op`.
79+
*
80+
* The boolean `isGLValue` is true if the operand represents a glvalue. In that case,
81+
* the returned type should be thought of as a pointer type whose base type is given
82+
* by this predicate.
83+
*/
84+
DataFlowType getOperandType(Operand op, boolean isGLValue) {
85+
Ssa::getLanguageType(op).hasType(result, isGLValue)
86+
}
87+
88+
/**
89+
* Gets the type of the instruction `instr`.
90+
*
91+
* The boolean `isGLValue` is true if the operand represents a glvalue. In that case,
92+
* the returned type should be thought of as a pointer type whose base type is given
93+
* by this predicate.
94+
*/
95+
DataFlowType getInstructionType(Instruction instr, boolean isGLValue) {
96+
Ssa::getResultLanguageType(instr).hasType(result, isGLValue)
7297
}
7398

7499
/**
@@ -84,7 +109,7 @@ abstract class InstructionNode0 extends Node0Impl {
84109

85110
override Declaration getFunction() { result = instr.getEnclosingFunction() }
86111

87-
override DataFlowType getType() { result = instr.getResultType() }
112+
override DataFlowType getType() { result = getInstructionType(instr, _) }
88113

89114
final override Location getLocationImpl() { result = instr.getLocation() }
90115

@@ -93,6 +118,8 @@ abstract class InstructionNode0 extends Node0Impl {
93118
// does not use `Instruction.toString` because that's expensive to compute.
94119
result = instr.getOpcode().toString()
95120
}
121+
122+
final override predicate isGLValue() { exists(getInstructionType(instr, true)) }
96123
}
97124

98125
/**
@@ -127,11 +154,13 @@ abstract class OperandNode0 extends Node0Impl {
127154

128155
override Declaration getFunction() { result = op.getUse().getEnclosingFunction() }
129156

130-
override DataFlowType getType() { result = op.getType() }
157+
override DataFlowType getType() { result = getOperandType(op, _) }
131158

132159
final override Location getLocationImpl() { result = op.getLocation() }
133160

134161
override string toStringImpl() { result = op.toString() }
162+
163+
final override predicate isGLValue() { exists(getOperandType(op, true)) }
135164
}
136165

137166
/**

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,13 @@ class Node extends TIRDataFlowNode {
143143
/** Gets the function to which this node belongs, if any. */
144144
Declaration getFunction() { none() } // overridden in subclasses
145145

146+
/** Holds if this node represents a glvalue. */
147+
predicate isGLValue() { none() }
148+
146149
/**
147150
* Gets the type of this node.
148151
*
149-
* If `asInstruction().isGLValue()` holds, then the type of this node
152+
* If `isGLValue()` holds, then the type of this node
150153
* should be thought of as "pointer to `getType()`".
151154
*/
152155
DataFlowType getType() { none() } // overridden in subclasses
@@ -394,6 +397,8 @@ private class Node0 extends Node, TNode0 {
394397
// does not use `Instruction.toString` because that's expensive to compute.
395398
result = node.toStringImpl()
396399
}
400+
401+
override predicate isGLValue() { node.isGLValue() }
397402
}
398403

399404
/**
@@ -497,7 +502,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
497502

498503
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
499504

500-
override DataFlowType getType() { result = this.getAnInput().getType() }
505+
override DataFlowType getType() { result = this.getAnInput().getType().getUnspecifiedType() }
501506

502507
final override Location getLocationImpl() { result = phi.getBasicBlock().getLocation() }
503508

@@ -591,10 +596,14 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
591596

592597
override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() }
593598

599+
final override predicate isGLValue() { globalDef.getIndirectionIndex() = 0 }
600+
594601
override DataFlowType getType() {
595-
exists(int indirectionIndex |
596-
indirectionIndex = globalDef.getIndirectionIndex() and
597-
result = getTypeImpl(globalDef.getUnspecifiedType(), indirectionIndex)
602+
exists(DataFlowType type |
603+
type = globalDef.getUnspecifiedType() and
604+
if this.isGLValue()
605+
then result = type
606+
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
598607
)
599608
}
600609

@@ -843,8 +852,11 @@ class RawIndirectOperand extends Node, TRawIndirectOperand {
843852
override Declaration getEnclosingCallable() { result = this.getFunction() }
844853

845854
override DataFlowType getType() {
846-
exists(int sub | if operand.isGLValue() then sub = 1 else sub = 0 |
847-
result = getTypeImpl(operand.getType().getUnspecifiedType(), indirectionIndex - sub)
855+
exists(int sub, DataFlowType type, boolean isGLValue |
856+
type = getOperandType(operand, isGLValue) and
857+
if isGLValue = true then sub = 1 else sub = 0
858+
|
859+
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
848860
)
849861
}
850862

@@ -938,8 +950,11 @@ class RawIndirectInstruction extends Node, TRawIndirectInstruction {
938950
override Declaration getEnclosingCallable() { result = this.getFunction() }
939951

940952
override DataFlowType getType() {
941-
exists(int sub | if instr.isGLValue() then sub = 1 else sub = 0 |
942-
result = getTypeImpl(instr.getResultType().getUnspecifiedType(), indirectionIndex - sub)
953+
exists(int sub, DataFlowType type, boolean isGLValue |
954+
type = getInstructionType(instr, isGLValue) and
955+
if isGLValue = true then sub = 1 else sub = 0
956+
|
957+
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
943958
)
944959
}
945960

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
failures
2+
astTypeBugs
3+
irTypeBugs
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import TestUtilities.InlineExpectationsTest
2+
import cpp
3+
4+
module AstTest {
5+
private import semmle.code.cpp.dataflow.internal.DataFlowUtil
6+
7+
query predicate astTypeBugs(Location location, Node node) {
8+
exists(int n |
9+
n = count(node.getType()) and
10+
location = node.getLocation() and
11+
n != 1
12+
)
13+
}
14+
}
15+
16+
import AstTest
17+
18+
module IrTest {
19+
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
20+
21+
query predicate irTypeBugs(Location location, Node node) {
22+
exists(int n |
23+
n = count(node.getType()) and
24+
location = node.getLocation() and
25+
n != 1
26+
)
27+
}
28+
}
29+
30+
import IrTest

0 commit comments

Comments
 (0)