Skip to content

Commit 8b9e4e3

Browse files
committed
C++: Introduce ElementBase class
By extending this class, a class can define its own `getLocation` predicate without participating in the dispatch hierarchy of `getLocation` as defined on `Element`. Classes wanting to override their location previously had to define `getURL` or `hasLocationInfo` instead and rely on these predicates not being defined on future versions of `Element`.
1 parent ea26ac8 commit 8b9e4e3

File tree

7 files changed

+38
-12
lines changed

7 files changed

+38
-12
lines changed

cpp/ql/src/AlertSuppression.ql

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ class SuppressionComment extends CppStyleComment {
5454
/**
5555
* The scope of an alert suppression comment.
5656
*/
57-
class SuppressionScope extends SuppressionComment {
57+
class SuppressionScope extends ElementBase {
58+
SuppressionScope() {
59+
this instanceof SuppressionComment
60+
}
61+
5862
/**
5963
* Holds if this element is at the specified location.
6064
* The location spans column `startcolumn` of line `startline` to
@@ -63,7 +67,7 @@ class SuppressionScope extends SuppressionComment {
6367
* [LGTM locations](https://lgtm.com/help/ql/locations).
6468
*/
6569
predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
66-
this.covers(filepath, startline, startcolumn, endline, endcolumn)
70+
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
6771
}
6872
}
6973

cpp/ql/src/Architecture/Refactoring Opportunities/ClassesWithManyFields.ql

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ predicate masterVde(VariableDeclarationEntry master, VariableDeclarationEntry vd
4646
exists(VariableDeclarationEntry previous | previousVde(previous, vde) and masterVde(master, previous))
4747
}
4848

49-
class VariableDeclarationGroup extends VariableDeclarationEntry {
49+
class VariableDeclarationGroup extends ElementBase {
5050
VariableDeclarationGroup() {
51+
this instanceof VariableDeclarationEntry and
5152
not previousVde(_, this)
5253
}
5354
Class getClass() {
@@ -62,7 +63,7 @@ class VariableDeclarationGroup extends VariableDeclarationEntry {
6263
masterVde(this, last) and
6364
this instanceof VariableDeclarationGroup and
6465
not previousVde(last, _) and
65-
this.getLocation() = lstart and
66+
exists(VariableDeclarationEntry vde | vde=this and vde instanceof VariableDeclarationEntry and vde.getLocation() = lstart) and
6667
last.getLocation() = lend and
6768
lstart.hasLocationInfo(path, startline, startcol, _, _) and
6869
lend.hasLocationInfo(path, _, _, endline, endcol)
@@ -78,7 +79,7 @@ class VariableDeclarationGroup extends VariableDeclarationEntry {
7879
name = vde.getName()))
7980
+ " fields here"
8081
else
81-
result = "declaration of " + this.getVariable().getName()
82+
result = "declaration of " + this.(VariableDeclarationEntry).getVariable().getName()
8283
}
8384
}
8485

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,29 @@ Element mkElement(@element e) {
4646
}
4747

4848
/**
49-
* A C/C++ element. This class is the base class for all C/C++
50-
* elements, such as functions, classes, expressions, and so on.
49+
* A C/C++ element with no member predicates other than `toString`. Not for
50+
* general use. This class does not define a location, so classes wanting to
51+
* change their location without affecting other classes can extend
52+
* `ElementBase` instead of `Element` to create a new rootdef for `getURL`,
53+
* `getLocation`, or `hasLocationInfo`.
5154
*/
52-
class Element extends @element {
53-
Element() {
55+
class ElementBase extends @element {
56+
ElementBase() {
5457
this = resolveElement(_)
5558
}
5659

5760
/** Gets a textual representation of this element. */
5861
string toString() { none() }
62+
}
63+
64+
/**
65+
* A C/C++ element. This class is the base class for all C/C++
66+
* elements, such as functions, classes, expressions, and so on.
67+
*/
68+
class Element extends ElementBase {
69+
Element() {
70+
this = resolveElement(_)
71+
}
5972

6073
/** Gets the primary file where this element occurs. */
6174
File getFile() { result = this.getLocation().getFile() }

cpp/ql/src/semmle/code/cpp/controlflow/ControlFlowGraph.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,12 @@ private predicate loopConditionAlwaysUponEntry(ControlFlowNode loop, Expr condit
146146
/**
147147
* An element that is convertible to `ControlFlowNode`. This class is similar
148148
* to `ControlFlowNode` except that is has no member predicates apart from
149-
* those inherited from `Locatable`.
149+
* `toString`.
150150
*
151151
* This class can be used as base class for classes that want to inherit the
152152
* extent of `ControlFlowNode` without inheriting its public member predicates.
153153
*/
154-
class ControlFlowNodeBase extends Locatable, @cfgnode {
154+
class ControlFlowNodeBase extends ElementBase, @cfgnode {
155155
}
156156

157157
predicate truecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {

cpp/ql/src/semmle/code/cpp/controlflow/DefinitionsAndUses.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class DefOrUse extends ControlFlowNodeBase {
8888
// Uninstantiated templates are purely syntax, and only on instantiation
8989
// will they be complete with information about types, conversions, call
9090
// targets, etc.
91-
not this.isFromUninstantiatedTemplate(_)
91+
not this.(ControlFlowNode).isFromUninstantiatedTemplate(_)
9292
}
9393

9494
/**

cpp/ql/src/semmle/code/cpp/controlflow/SSA.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ class SsaDefinition extends ControlFlowNodeBase {
7070
exists(StandardSSA x | x.phi_node(v, (BasicBlock)this))
7171
}
7272

73+
Location getLocation() {
74+
result = this.(ControlFlowNode).getLocation()
75+
}
76+
7377
/** Holds if the SSA variable `(this, p)` is defined by parameter `p`. */
7478
predicate definedByParameter(Parameter p) {
7579
this = p.getFunction().getEntryPoint()

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
113113
guard_defn(v, guard, this, branch)
114114
}
115115

116+
Location getLocation() {
117+
result = this.(ControlFlowNode).getLocation()
118+
}
119+
116120
/** Whether this definition is from a parameter */
117121
predicate definedByParameter(Parameter p) {
118122
this = p.getFunction().getEntryPoint()

0 commit comments

Comments
 (0)