Skip to content

Commit e147a60

Browse files
committed
C++: Replace 'IRType' with 'Type' in dataflow. This means we're more compatible with the old AST library.
1 parent 65a538e commit e147a60

File tree

3 files changed

+61
-21
lines changed

3 files changed

+61
-21
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -465,20 +465,20 @@ predicate clearsContent(Node n, Content c) {
465465
predicate expectsContent(Node n, ContentSet c) { none() }
466466

467467
/** Gets the type of `n` used for type pruning. */
468-
IRType getNodeType(Node n) {
468+
DataFlowType getNodeType(Node n) {
469469
suppressUnusedNode(n) and
470-
result instanceof IRVoidType // stub implementation
470+
result instanceof VoidType // stub implementation
471471
}
472472

473473
/** Gets a string representation of a type returned by `getNodeType`. */
474-
string ppReprType(IRType t) { none() } // stub implementation
474+
string ppReprType(DataFlowType t) { none() } // stub implementation
475475

476476
/**
477477
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
478478
* a node of type `t1` to a node of type `t2`.
479479
*/
480480
pragma[inline]
481-
predicate compatibleTypes(IRType t1, IRType t2) {
481+
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
482482
any() // stub implementation
483483
}
484484

@@ -502,7 +502,7 @@ class DataFlowCallable = Cpp::Declaration;
502502

503503
class DataFlowExpr = Expr;
504504

505-
class DataFlowType = IRType;
505+
class DataFlowType = Type;
506506

507507
/** A function call relevant for data flow. */
508508
class DataFlowCall extends CallInstruction {

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

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/ssa0/SsaInternals.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private module SourceVariables {
3636

3737
override string toString() { result = var.toString() }
3838

39-
override DataFlowType getType() { result = var.getIRType() }
39+
override DataFlowType getType() { result = var.getType() }
4040
}
4141

4242
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
@@ -48,7 +48,7 @@ private module SourceVariables {
4848

4949
override string toString() { result = call.toString() }
5050

51-
override DataFlowType getType() { result = call.getResultIRType() }
51+
override DataFlowType getType() { result = call.getResultType() }
5252
}
5353

5454
private newtype TSourceVariable =

0 commit comments

Comments
 (0)