Skip to content

Commit 6225fcf

Browse files
authored
Merge pull request #12 from pavgust/imp/c-locations
Simplify C locations handling
2 parents 6132b2c + 628edc9 commit 6225fcf

File tree

2 files changed

+45
-58
lines changed

2 files changed

+45
-58
lines changed

cpp/ql/src/definitions.qll

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,16 @@ private predicate constructorCallStartLoc(ConstructorCall cc, File f, int line,
102102

103103
/**
104104
* Holds if `f`, `line`, `column` indicate the start character
105-
* of `tm`.
105+
* of `tm`, which mentions `t`.
106106
*/
107-
private predicate typeMentionStartLoc(TypeMention tm, File f, int line, int column) {
107+
private predicate typeMentionStartLoc(TypeMention tm, Type t, File f, int line, int column) {
108108
exists(Location l |
109109
l = tm.getLocation() and
110110
l.getFile() = f and
111111
l.getStartLine() = line and
112112
l.getStartColumn() = column
113-
)
113+
) and
114+
t = tm.getMentionedType()
114115
}
115116

116117
/**
@@ -119,7 +120,7 @@ private predicate typeMentionStartLoc(TypeMention tm, File f, int line, int colu
119120
private cached predicate constructorCallTypeMention(ConstructorCall cc, TypeMention tm) {
120121
exists(File f, int line, int column |
121122
constructorCallStartLoc(cc, f, line, column) and
122-
typeMentionStartLoc(tm, f, line, column)
123+
typeMentionStartLoc(tm, _, f, line, column)
123124
)
124125
}
125126

@@ -155,15 +156,16 @@ Top definitionOf(Top e, string kind) {
155156
kind = "T" and
156157
e.(TypeMention).getMentionedType() = result and
157158
not constructorCallTypeMention(_, e) and // handled elsewhere
158-
159-
// multiple mentions can be generated when a typedef is used. Exclude
160-
// all but the originating typedef.
161-
not exists(TypeMention tm, File f, int startline, int startcol |
162-
typeMentionStartLoc(e, f, startline, startcol) and
163-
typeMentionStartLoc(tm, f, startline, startcol) and
164-
(
165-
e.(TypeMention).getMentionedType() = tm.getMentionedType().(TypedefType).getBaseType() or
166-
e.(TypeMention).getMentionedType() = tm.getMentionedType().(TypedefType).getBaseType().(SpecifiedType).getBaseType()
159+
// Multiple type mentions can be generated when a typedef is used, and
160+
// in such cases we want to exclude all but the originating typedef.
161+
not exists(Type secondary |
162+
exists(TypeMention tm, File f, int startline, int startcol |
163+
typeMentionStartLoc(e, result, f, startline, startcol) and
164+
typeMentionStartLoc(tm, secondary, f, startline, startcol) and
165+
(
166+
result = secondary.(TypedefType).getBaseType() or
167+
result = secondary.(TypedefType).getBaseType().(SpecifiedType).getBaseType()
168+
)
167169
)
168170
)
169171
) or (
@@ -186,7 +188,7 @@ Top definitionOf(Top e, string kind) {
186188
not exists(MacroInvocation mi, Location l1, Location l2 |
187189
l1 = e.(Include).getLocation() and
188190
l2 = mi.getLocation() and
189-
l1.getFile() = l2.getFile() and
191+
l1.getContainer() = l2.getContainer() and
190192
l1.getStartLine() = l2.getStartLine()
191193
// (an #include directive must be always on it's own line)
192194
)

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

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ class Location extends @location {
88

99
/** Gets the container corresponding to this location. */
1010
Container getContainer() {
11-
locations_default(this,result,_,_,_,_) or
12-
locations_stmt(this,result,_,_,_,_) or
13-
locations_expr(this,result,_,_,_,_)
11+
this.fullLocationInfo(result, _, _, _, _)
1412
}
1513

1614
/** Gets the file corresponding to this location, if any. */
@@ -20,30 +18,22 @@ class Location extends @location {
2018

2119
/** Gets the start line of this location. */
2220
int getStartLine() {
23-
locations_default(this,_,result,_,_,_) or
24-
locations_stmt(this,_,result,_,_,_) or
25-
locations_expr(this,_,result,_,_,_)
26-
}
27-
28-
/** Gets the end line of this location. */
29-
int getEndLine() {
30-
locations_default(this,_,_,_,result,_) or
31-
locations_stmt(this,_,_,_,result,_) or
32-
locations_expr(this,_,_,_,result,_)
21+
this.fullLocationInfo(_, result, _, _, _)
3322
}
3423

3524
/** Gets the start column of this location. */
3625
int getStartColumn() {
37-
locations_default(this,_,_,result,_,_) or
38-
locations_stmt(this,_,_,result,_,_) or
39-
locations_expr(this,_,_,result,_,_)
26+
this.fullLocationInfo(_, _, result, _, _)
27+
}
28+
29+
/** Gets the end line of this location. */
30+
int getEndLine() {
31+
this.fullLocationInfo(_, _, _, result, _)
4032
}
4133

4234
/** Gets the end column of this location. */
4335
int getEndColumn() {
44-
locations_default(this,_,_,_,_,result) or
45-
locations_stmt(this,_,_,_,_,result) or
46-
locations_expr(this,_,_,_,_,result)
36+
this.fullLocationInfo(_, _, _, _, result)
4737
}
4838

4939
/**
@@ -58,6 +48,20 @@ class Location extends @location {
5848
)
5949
}
6050

51+
/**
52+
* Holds if this element is in the specified container.
53+
* The location spans column `startcolumn` of line `startline` to
54+
* column `endcolumn` of line `endline`.
55+
*
56+
* This predicate is similar to `hasLocationInfo`, but exposes the `Container`
57+
* entity, rather than merely its path.
58+
*/
59+
predicate fullLocationInfo(
60+
Container container, int startline, int startcolumn, int endline, int endcolumn) {
61+
locations_default(this, container, startline, startcolumn, endline, endcolumn) or
62+
locations_expr(this, container, startline, startcolumn, endline, endcolumn) or
63+
locations_stmt(this, container, startline, startcolumn, endline, endcolumn)
64+
}
6165

6266
/**
6367
* Holds if this element is at the specified location.
@@ -68,7 +72,9 @@ class Location extends @location {
6872
*/
6973
predicate hasLocationInfo(
7074
string filepath, int startline, int startcolumn, int endline, int endcolumn) {
71-
none()
75+
exists(Container f
76+
| this.fullLocationInfo(f,startline,startcolumn,endline,endcolumn)
77+
| filepath = f.getAbsolutePath())
7278
}
7379

7480
/** Holds if `this` comes on a line strictly before `l`. */
@@ -108,34 +114,13 @@ class Location extends @location {
108114
* A location of an element. Not used for expressions or statements, which
109115
* instead use LocationExpr and LocationStmt respectively.
110116
*/
111-
library class LocationDefault extends Location, @location_default {
112-
override predicate hasLocationInfo(
113-
string filepath, int startline, int startcolumn, int endline, int endcolumn) {
114-
exists(Container f
115-
| locations_default(this,f,startline,startcolumn,endline,endcolumn)
116-
| filepath = f.getAbsolutePath())
117-
}
118-
}
117+
library class LocationDefault extends Location, @location_default {}
119118

120119
/** A location of a statement. */
121-
library class LocationStmt extends Location, @location_stmt {
122-
override predicate hasLocationInfo(
123-
string filepath, int startline, int startcolumn, int endline, int endcolumn) {
124-
exists(Container f
125-
| locations_stmt(this,f,startline,startcolumn,endline,endcolumn)
126-
| filepath = f.getAbsolutePath())
127-
}
128-
}
120+
library class LocationStmt extends Location, @location_stmt {}
129121

130122
/** A location of an expression. */
131-
library class LocationExpr extends Location, @location_expr {
132-
override predicate hasLocationInfo(
133-
string filepath, int startline, int startcolumn, int endline, int endcolumn) {
134-
exists(Container f
135-
| locations_expr(this,f,startline,startcolumn,endline,endcolumn)
136-
| filepath = f.getAbsolutePath())
137-
}
138-
}
123+
library class LocationExpr extends Location, @location_expr {}
139124

140125
/**
141126
* Gets the length of the longest line in file `f`.

0 commit comments

Comments
 (0)