Skip to content

Commit 11c7023

Browse files
author
Dave Bartolomeo
authored
Merge pull request github#3795 from rdmarsh2/rdmarsh/cpp/add-qldoc-3
C++: QLDoc for PrintAST and AST-based range analysis
2 parents 3f0975f + 9a1f909 commit 11c7023

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

cpp/ql/src/semmle/code/cpp/PrintAST.qll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* Provides queries to pretty-print a C++ AST as a graph.
3+
*
4+
* By default, this will print the AST for all functions in the database. To change this behavior,
5+
* extend `PrintASTConfiguration` and override `shouldPrintFunction` to hold for only the functions
6+
* you wish to view the AST for.
7+
*/
8+
19
import cpp
210
private import semmle.code.cpp.Print
311

@@ -7,6 +15,9 @@ private newtype TPrintASTConfiguration = MkPrintASTConfiguration()
715
* The query can extend this class to control which functions are printed.
816
*/
917
class PrintASTConfiguration extends TPrintASTConfiguration {
18+
/**
19+
* Gets a textual representation of this `PrintASTConfiguration`.
20+
*/
1021
string toString() { result = "PrintASTConfiguration" }
1122

1223
/**
@@ -96,6 +107,9 @@ private newtype TPrintASTNode =
96107
* A node in the output tree.
97108
*/
98109
class PrintASTNode extends TPrintASTNode {
110+
/**
111+
* Gets a textual representation of this node in the PrintAST output tree.
112+
*/
99113
abstract string toString();
100114

101115
/**
@@ -208,6 +222,9 @@ class ExprNode extends ASTNode {
208222
result = expr.getValueCategoryString()
209223
}
210224

225+
/**
226+
* Gets the value of this expression, if it is a constant.
227+
*/
211228
string getValue() { result = expr.getValue() }
212229
}
213230

@@ -373,6 +390,9 @@ class ParametersNode extends PrintASTNode, TParametersNode {
373390

374391
override ASTNode getChild(int childIndex) { result.getAST() = func.getParameter(childIndex) }
375392

393+
/**
394+
* Gets the `Function` for which this node represents the parameters.
395+
*/
376396
final Function getFunction() { result = func }
377397
}
378398

@@ -392,6 +412,9 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers
392412
result.getAST() = ctor.getInitializer(childIndex)
393413
}
394414

415+
/**
416+
* Gets the `Constructor` for which this node represents the initializer list.
417+
*/
395418
final Constructor getConstructor() { result = ctor }
396419
}
397420

@@ -411,6 +434,9 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo
411434
result.getAST() = dtor.getDestruction(childIndex)
412435
}
413436

437+
/**
438+
* Gets the `Destructor` for which this node represents the destruction list.
439+
*/
414440
final Destructor getDestructor() { result = dtor }
415441
}
416442

@@ -464,6 +490,9 @@ class FunctionNode extends ASTNode {
464490
key = "semmle.order" and result = getOrder().toString()
465491
}
466492

493+
/**
494+
* Gets the `Function` this node represents.
495+
*/
467496
final Function getFunction() { result = func }
468497
}
469498

@@ -499,11 +528,16 @@ class ArrayAggregateLiteralNode extends ExprNode {
499528
}
500529
}
501530

531+
/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
502532
query predicate nodes(PrintASTNode node, string key, string value) {
503533
node.shouldPrint() and
504534
value = node.getProperty(key)
505535
}
506536

537+
/**
538+
* Holds if `target` is a child of `source` in the AST, and property `key` of the edge has the
539+
* given `value`.
540+
*/
507541
query predicate edges(PrintASTNode source, PrintASTNode target, string key, string value) {
508542
exists(int childIndex |
509543
source.shouldPrint() and
@@ -517,6 +551,7 @@ query predicate edges(PrintASTNode source, PrintASTNode target, string key, stri
517551
)
518552
}
519553

554+
/** Holds if property `key` of the graph has the given `value`. */
520555
query predicate graphProperties(string key, string value) {
521556
key = "semmle.graphKind" and value = "tree"
522557
}

cpp/ql/src/semmle/code/cpp/rangeanalysis/NanAnalysis.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
/**
2+
* Provides classes and predicates for recognizing floating point expressions which cannot be NaN.
3+
*/
4+
15
import cpp
26
private import semmle.code.cpp.rangeanalysis.RangeSSA
37

cpp/ql/src/semmle/code/cpp/rangeanalysis/PointlessComparison.qll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,17 @@ private float lowerBoundFC(Expr expr) { result = lowerBound(expr.getFullyConvert
1111
/** Gets the upper bound of the fully converted expression. */
1212
private float upperBoundFC(Expr expr) { result = upperBound(expr.getFullyConverted()) }
1313

14+
/**
15+
* Describes which side of a pointless comparison is known to be smaller.
16+
*/
1417
newtype SmallSide =
18+
/**
19+
* Represents that the left side of a pointless comparison is known to be smaller.
20+
*/
1521
LeftIsSmaller() or
22+
/**
23+
* Represents that the right side of a pointless comparison is known to be smaller.
24+
*/
1625
RightIsSmaller()
1726

1827
/**

cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysisUtils.qll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,27 @@ import cpp
55
* relation) or 'non-strict' (a `<=` or `>=` relation).
66
*/
77
newtype RelationStrictness =
8+
/**
9+
* Represents that a relation is 'strict' (that is, a `<` or `>` relation).
10+
*/
811
Strict() or
12+
/**
13+
* Represents that a relation is 'non-strict' (that is, a `<=` or `>=` relation)
14+
*/
915
Nonstrict()
1016

1117
/**
1218
* Describes whether a relation is 'greater' (that is, a `>` or `>=`
1319
* relation) or 'lesser' (a `<` or `<=` relation).
1420
*/
1521
newtype RelationDirection =
22+
/**
23+
* Represents that a relation is 'greater' (that is, a `>` or `>=` relation).
24+
*/
1625
Greater() or
26+
/**
27+
* Represents that a relation is 'lesser' (that is, a `<` or `<=` relation).
28+
*/
1729
Lesser()
1830

1931
private RelationStrictness negateStrictness(RelationStrictness strict) {
@@ -28,12 +40,18 @@ private RelationDirection negateDirection(RelationDirection dir) {
2840
dir = Lesser() and result = Greater()
2941
}
3042

43+
/**
44+
* Holds if `dir` is `Greater` (that is, a `>` or `>=` relation)
45+
*/
3146
boolean directionIsGreater(RelationDirection dir) {
3247
dir = Greater() and result = true
3348
or
3449
dir = Lesser() and result = false
3550
}
3651

52+
/**
53+
* Holds if `dir` is `Lesser` (that is, a `<` or `<=` relation)
54+
*/
3755
boolean directionIsLesser(RelationDirection dir) {
3856
dir = Greater() and result = false
3957
or

cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeSSA.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import semmle.code.cpp.controlflow.Dominance
2525
import semmle.code.cpp.controlflow.SSAUtils
2626
private import RangeAnalysisUtils
2727

28+
/**
29+
* The SSA logic comes in two versions: the standard SSA and range-analysis RangeSSA.
30+
* This class provides the range-analysis SSA logic.
31+
*/
2832
library class RangeSSA extends SSAHelper {
2933
RangeSSA() { this = 1 }
3034

@@ -84,6 +88,7 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
8488
/** Gets the control flow node for this definition. */
8589
ControlFlowNode getDefinition() { result = this }
8690

91+
/** Gets the basic block containing this definition. */
8792
BasicBlock getBasicBlock() { result.contains(getDefinition()) }
8893

8994
/** Whether this definition is a phi node for variable `v`. */
@@ -97,11 +102,13 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
97102
guard_defn(v, guard, this, branch)
98103
}
99104

105+
/** Gets the primary location of this definition. */
100106
Location getLocation() { result = this.(ControlFlowNode).getLocation() }
101107

102108
/** Whether this definition is from a parameter */
103109
predicate definedByParameter(Parameter p) { this = p.getFunction().getEntryPoint() }
104110

111+
/** Gets a definition of `v` that is a phi input for this basic block. */
105112
RangeSsaDefinition getAPhiInput(StackVariable v) {
106113
this.isPhiNode(v) and
107114
exists(BasicBlock pred |
@@ -153,6 +160,9 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
153160
)
154161
}
155162

163+
/**
164+
* Holds if this definition of the variable `v` reached the end of the basic block `b`.
165+
*/
156166
predicate reachesEndOfBB(StackVariable v, BasicBlock b) {
157167
exists(RangeSSA x | x.ssaDefinitionReachesEndOfBB(v, this, b))
158168
}

0 commit comments

Comments
 (0)