Skip to content

Commit 0edeb8f

Browse files
Merge pull request #876 from github/lcartey/restore-deleted-deviations-suppression-query
Restore deleted deviations suppression query
2 parents eedca61 + 8c2da1c commit 0edeb8f

13 files changed

+341
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- The `DeviationsSuppression.ql` query has been restored after being incorrectly deleted in a previous release.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import cpp
2+
3+
/** Holds if `lineNumber` is an indexed line number in file `f`. */
4+
predicate isLineNumber(File f, int lineNumber) {
5+
exists(Location l | l.getFile() = f |
6+
l.getStartLine() = lineNumber
7+
or
8+
l.getEndLine() = lineNumber
9+
)
10+
}
11+
12+
/** Gets the last line number in `f`. */
13+
int getLastLineNumber(File f) { result = max(int lineNumber | isLineNumber(f, lineNumber)) }
14+
15+
/** Gets the last column number on the last line of `f`. */
16+
int getLastColumnNumber(File f) {
17+
result =
18+
max(Location l |
19+
l.getFile() = f and
20+
l.getEndLine() = getLastLineNumber(f)
21+
|
22+
l.getEndColumn()
23+
)
24+
}
25+
26+
/** Gets the last column number on the given line of `filepath`. */
27+
bindingset[filepath, lineNumber]
28+
int getLastColumnNumber(string filepath, int lineNumber) {
29+
result = max(Location l | l.hasLocationInfo(filepath, _, _, lineNumber, _) | l.getEndColumn())
30+
}

cpp/common/src/codingstandards/cpp/deviations/CodeIdentifierDeviation.qll

+85-18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import cpp
3434
import Deviations
35+
import codingstandards.cpp.Locations
3536

3637
string supportedStandard() { result = ["misra", "autosar", "cert"] }
3738

@@ -226,15 +227,20 @@ class DeviationAttribute extends StdAttribute {
226227

227228
DeviationRecord getADeviationRecord() { result = record }
228229

229-
pragma[nomagic]
230-
Element getASuppressedElement() {
230+
/** Gets the element to which this attribute was applied. */
231+
Element getPrimarySuppressedElement() {
231232
result.(Type).getAnAttribute() = this
232233
or
233234
result.(Stmt).getAnAttribute() = this
234235
or
235236
result.(Variable).getAnAttribute() = this
236237
or
237238
result.(Function).getAnAttribute() = this
239+
}
240+
241+
pragma[nomagic]
242+
Element getASuppressedElement() {
243+
result = this.getPrimarySuppressedElement()
238244
or
239245
result.(Expr).getEnclosingStmt() = this.getASuppressedElement()
240246
or
@@ -289,11 +295,14 @@ newtype TCodeIndentifierDeviation =
289295
} or
290296
TMultiLineDeviation(
291297
DeviationRecord record, DeviationBegin beginComment, DeviationEnd endComment, string filepath,
292-
int suppressedStartLine, int suppressedEndLine
298+
int suppressedStartLine, int suppressedStartColumn, int suppressedEndLine,
299+
int suppressedEndColumn
293300
) {
294301
isDeviationRangePaired(record, beginComment, endComment) and
295-
beginComment.getLocation().hasLocationInfo(filepath, suppressedStartLine, _, _, _) and
296-
endComment.getLocation().hasLocationInfo(filepath, suppressedEndLine, _, _, _)
302+
beginComment
303+
.getLocation()
304+
.hasLocationInfo(filepath, suppressedStartLine, suppressedStartColumn, _, _) and
305+
endComment.getLocation().hasLocationInfo(filepath, _, _, suppressedEndLine, suppressedEndColumn)
297306
} or
298307
TCodeIdentifierDeviation(DeviationRecord record, DeviationAttribute attribute) {
299308
attribute.getADeviationRecord() = record
@@ -304,7 +313,7 @@ class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
304313
DeviationRecord getADeviationRecord() {
305314
this = TSingleLineDeviation(result, _, _, _)
306315
or
307-
this = TMultiLineDeviation(result, _, _, _, _, _)
316+
this = TMultiLineDeviation(result, _, _, _, _, _, _, _)
308317
or
309318
this = TCodeIdentifierDeviation(result, _)
310319
}
@@ -315,18 +324,38 @@ class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
315324
bindingset[e]
316325
pragma[inline_late]
317326
predicate isElementMatching(Element e) {
318-
exists(string filepath, int elementLocationStart |
319-
e.getLocation().hasLocationInfo(filepath, elementLocationStart, _, _, _)
327+
exists(string filepath, int elementLocationStart, int elementLocationColumnStart |
328+
e.getLocation()
329+
.hasLocationInfo(filepath, elementLocationStart, elementLocationColumnStart, _, _)
320330
|
321331
exists(int suppressedLine |
322332
this = TSingleLineDeviation(_, _, filepath, suppressedLine) and
323333
suppressedLine = elementLocationStart
324334
)
325335
or
326-
exists(int suppressedStartLine, int suppressedEndLine |
327-
this = TMultiLineDeviation(_, _, _, filepath, suppressedStartLine, suppressedEndLine) and
328-
suppressedStartLine < elementLocationStart and
329-
suppressedEndLine > elementLocationStart
336+
exists(
337+
int suppressedStartLine, int suppressedStartColumn, int suppressedEndLine,
338+
int suppressedEndColumn
339+
|
340+
this =
341+
TMultiLineDeviation(_, _, _, filepath, suppressedStartLine, suppressedStartColumn,
342+
suppressedEndLine, suppressedEndColumn) and
343+
(
344+
// Element starts on a line after the begin marker of the suppression
345+
suppressedStartLine < elementLocationStart
346+
or
347+
// Element exists on the same line as the begin marker, and occurs after it
348+
suppressedStartLine = elementLocationStart and
349+
suppressedStartColumn < elementLocationColumnStart
350+
) and
351+
(
352+
// Element starts on a line before the end marker of the suppression
353+
suppressedEndLine > elementLocationStart
354+
or
355+
// Element exists on the same line as the end marker of the suppression, and occurs before it
356+
suppressedEndLine = elementLocationStart and
357+
elementLocationColumnStart < suppressedEndColumn
358+
)
330359
)
331360
)
332361
or
@@ -336,26 +365,64 @@ class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
336365
)
337366
}
338367

368+
/**
369+
* Holds for the region matched by this code identifier deviation.
370+
*
371+
* Note: this is not the location of the marker itself.
372+
*/
373+
predicate hasLocationInfo(
374+
string filepath, int suppressedLine, int suppressedColumn, int endline, int endcolumn
375+
) {
376+
exists(Comment commentMarker |
377+
this = TSingleLineDeviation(_, commentMarker, filepath, suppressedLine) and
378+
suppressedColumn = 1 and
379+
endline = suppressedLine
380+
|
381+
if commentMarker instanceof DeviationEndOfLineMarker
382+
then endcolumn = commentMarker.(DeviationEndOfLineMarker).getLocation().getEndColumn()
383+
else
384+
// Find the last column for a location on the next line
385+
endcolumn = getLastColumnNumber(filepath, suppressedLine)
386+
)
387+
or
388+
this =
389+
TMultiLineDeviation(_, _, _, filepath, suppressedLine, suppressedColumn, endline, endcolumn)
390+
or
391+
exists(DeviationAttribute attribute |
392+
this = TCodeIdentifierDeviation(_, attribute) and
393+
attribute
394+
.getPrimarySuppressedElement()
395+
.getLocation()
396+
.hasLocationInfo(filepath, suppressedLine, suppressedColumn, endline, endcolumn)
397+
)
398+
}
399+
339400
string toString() {
340401
exists(string filepath |
341402
exists(int suppressedLine |
342403
this = TSingleLineDeviation(_, _, filepath, suppressedLine) and
343404
result =
344-
"Deviation record " + getADeviationRecord() + " applied to " + filepath + " Line " +
405+
"Deviation of " + getADeviationRecord().getQuery() + " applied to " + filepath + " Line " +
345406
suppressedLine
346407
)
347408
or
348-
exists(int suppressedStartLine, int suppressedEndLine |
349-
this = TMultiLineDeviation(_, _, _, filepath, suppressedStartLine, suppressedEndLine) and
409+
exists(
410+
int suppressedStartLine, int suppressedStartColumn, int suppressedEndLine,
411+
int suppressedEndColumn
412+
|
413+
this =
414+
TMultiLineDeviation(_, _, _, filepath, suppressedStartLine, suppressedStartColumn,
415+
suppressedEndLine, suppressedEndColumn) and
350416
result =
351-
"Deviation record " + getADeviationRecord() + " applied to " + filepath + " Line" +
352-
suppressedStartLine + ":" + suppressedEndLine
417+
"Deviation of " + getADeviationRecord().getQuery() + " applied to " + filepath + " Line " +
418+
suppressedStartLine + ":" + suppressedStartColumn + ":" + suppressedEndLine + ":" +
419+
suppressedEndColumn
353420
)
354421
)
355422
or
356423
exists(DeviationAttribute attribute |
357424
this = TCodeIdentifierDeviation(_, attribute) and
358-
result = "Deviation record " + getADeviationRecord() + " applied to " + attribute
425+
result = "Deviation of " + getADeviationRecord().getQuery() + " applied to " + attribute
359426
)
360427
}
361428
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
<overview>
4+
<p>This query generates suppression information for rules that have an associated deviation record.</p>
5+
</overview>
6+
<references>
7+
<li>
8+
MISRA Compliance 2020 document:
9+
<a href="https://www.misra.org.uk/app/uploads/2021/06/MISRA-Compliance-2020.pdf">Chapter 4.2 (page 12) - Deviations.</a>
10+
</li>
11+
</references>
12+
</qhelp>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* @name Deviation suppression
3+
* @description Generates information about files and locations where certain alerts should be considered suppressed by deviations.
4+
* @kind alert-suppression
5+
* @id cpp/coding-standards/deviation-suppression
6+
*/
7+
8+
import cpp
9+
import Deviations
10+
import codingstandards.cpp.Locations
11+
12+
newtype TDeviationScope =
13+
TDeviationRecordFileScope(DeviationRecord dr, File file) {
14+
exists(string deviationPath |
15+
dr.isDeviated(_, deviationPath) and
16+
file.getRelativePath().prefix(deviationPath.length()) = deviationPath
17+
)
18+
} or
19+
TDeviationRecordCodeIdentiferDeviationScope(DeviationRecord dr, CodeIdentifierDeviation c) {
20+
c = dr.getACodeIdentifierDeviation()
21+
}
22+
23+
/** A deviation scope. */
24+
class DeviationScope extends TDeviationScope {
25+
/** Gets the location at which this deviation was defined. */
26+
abstract Locatable getDeviationDefinitionLocation();
27+
28+
/** Gets the Query being deviated. */
29+
abstract Query getQuery();
30+
31+
abstract string toString();
32+
33+
abstract predicate hasLocationInfo(
34+
string filepath, int startline, int startcolumn, int endline, int endcolumn
35+
);
36+
}
37+
38+
/** A deviation scope derived from a "path" entry in a `DeviationRecord`. */
39+
class DeviationRecordFileScope extends DeviationScope, TDeviationRecordFileScope {
40+
private DeviationRecord getDeviationRecord() { this = TDeviationRecordFileScope(result, _) }
41+
42+
override Locatable getDeviationDefinitionLocation() { result = getDeviationRecord() }
43+
44+
private File getFile() { this = TDeviationRecordFileScope(_, result) }
45+
46+
override Query getQuery() { result = getDeviationRecord().getQuery() }
47+
48+
override predicate hasLocationInfo(
49+
string filepath, int startline, int startcolumn, int endline, int endcolumn
50+
) {
51+
// In an ideal world, we would produce a URL here that informed the AlertSuppression code that
52+
// the whole file was suppressed. However, the alert suppression code only works with locations
53+
// with lines and columns, so we generate a location that covers the whole "indexed" file, by
54+
// finding the location indexed in the database with the latest line and column number.
55+
exists(File f | f = getFile() |
56+
f.getLocation().hasLocationInfo(filepath, _, _, _, _) and
57+
startline = 1 and
58+
startcolumn = 1 and
59+
endline = getLastLineNumber(f) and
60+
endcolumn = getLastColumnNumber(f)
61+
)
62+
}
63+
64+
override string toString() {
65+
result = "Deviation of " + getDeviationRecord().getQuery() + " for " + getFile() + "."
66+
}
67+
}
68+
69+
/**
70+
* A deviation scope derived from a comment corresponding to a "code-identifier" entry for a
71+
* `DeviationRecord`.
72+
*/
73+
class DeviationRecordCommentScope extends DeviationScope,
74+
TDeviationRecordCodeIdentiferDeviationScope
75+
{
76+
private DeviationRecord getDeviationRecord() {
77+
this = TDeviationRecordCodeIdentiferDeviationScope(result, _)
78+
}
79+
80+
private CodeIdentifierDeviation getCodeIdentifierDeviation() {
81+
this = TDeviationRecordCodeIdentiferDeviationScope(_, result)
82+
}
83+
84+
override Locatable getDeviationDefinitionLocation() { result = getDeviationRecord() }
85+
86+
override Query getQuery() { result = getDeviationRecord().getQuery() }
87+
88+
override predicate hasLocationInfo(
89+
string filepath, int startline, int startcolumn, int endline, int endcolumn
90+
) {
91+
getCodeIdentifierDeviation()
92+
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
93+
}
94+
95+
override string toString() { result = getCodeIdentifierDeviation().toString() }
96+
}
97+
98+
from DeviationScope deviationScope
99+
select deviationScope.getDeviationDefinitionLocation(), // suppression comment
100+
"// lgtm[" + deviationScope.getQuery().getQueryId() + "]", // text of suppression comment (excluding delimiters)
101+
"lgtm[" + deviationScope.getQuery().getQueryId() + "]", // text of suppression annotation
102+
deviationScope // scope of suppression

cpp/common/test/deviations/deviations_basic_test/TypeLongDoubleUsed.expected

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@
1010
| main.cpp:21:15:21:16 | d6 | Use of long double type. |
1111
| main.cpp:30:15:30:17 | d10 | Use of long double type. |
1212
| main.cpp:38:15:38:17 | d14 | Use of long double type. |
13+
| main.cpp:42:15:42:17 | d15 | Use of long double type. |
14+
| main.cpp:43:113:43:115 | d18 | Use of long double type. |

cpp/common/test/deviations/deviations_basic_test/main.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,10 @@ int main(int argc, char **argv) {
3737
// codeql::autosar_deviation_end(a-0-4-2-deviation)
3838
long double d14; // NON_COMPLIANT (A0-4-2)
3939
getX(); // NON_COMPLIANT (A0-1-2)
40+
41+
// clang-format off
42+
long double d15; /* NON_COMPLIANT*/ /* codeql::autosar_deviation_begin(a-0-4-2-deviation) */ long double d16; // COMPLIANT[DEVIATED]
43+
long double d17; /* COMPLIANT[DEVIATED] */ /* codeql::autosar_deviation_end(a-0-4-2-deviation) */ long double d18; // NON_COMPLIANT
44+
// clang-format on
4045
return 0;
4146
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/type-long-double-used] | lgtm[cpp/autosar/type-long-double-used] | main.cpp:12:1:12:58 | Deviation of cpp/autosar/type-long-double-used applied to main.cpp Line 12 |
2+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/type-long-double-used] | lgtm[cpp/autosar/type-long-double-used] | main.cpp:14:1:14:65 | Deviation of cpp/autosar/type-long-double-used applied to main.cpp Line 14 |
3+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/type-long-double-used] | lgtm[cpp/autosar/type-long-double-used] | main.cpp:18:1:18:40 | Deviation of cpp/autosar/type-long-double-used applied to main.cpp Line 18 |
4+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/type-long-double-used] | lgtm[cpp/autosar/type-long-double-used] | main.cpp:21:3:27:53 | Deviation of cpp/autosar/type-long-double-used applied to main.cpp Line 21:3:27:53 |
5+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/type-long-double-used] | lgtm[cpp/autosar/type-long-double-used] | main.cpp:29:3:35:53 | Deviation of cpp/autosar/type-long-double-used applied to main.cpp Line 29:3:35:53 |
6+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/type-long-double-used] | lgtm[cpp/autosar/type-long-double-used] | main.cpp:40:39:41:99 | Deviation of cpp/autosar/type-long-double-used applied to main.cpp Line 40:39:41:99 |
7+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/unused-return-value] | lgtm[cpp/autosar/unused-return-value] | nested/nested2/test2.h:1:1:6:1 | Deviation of cpp/autosar/unused-return-value for nested/nested2/test2.h. |
8+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/useless-assignment] | lgtm[cpp/autosar/useless-assignment] | coding-standards.xml:1:1:17:19 | Deviation of cpp/autosar/useless-assignment for coding-standards.xml. |
9+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/useless-assignment] | lgtm[cpp/autosar/useless-assignment] | main.cpp:1:1:44:1 | Deviation of cpp/autosar/useless-assignment for main.cpp. |
10+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/useless-assignment] | lgtm[cpp/autosar/useless-assignment] | nested/coding-standards.xml:1:1:13:19 | Deviation of cpp/autosar/useless-assignment for nested/coding-standards.xml. |
11+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/useless-assignment] | lgtm[cpp/autosar/useless-assignment] | nested/nested2/test2.h:1:1:6:1 | Deviation of cpp/autosar/useless-assignment for nested/nested2/test2.h. |
12+
| file://:0:0:0:0 | (no string representation) | // lgtm[cpp/autosar/useless-assignment] | lgtm[cpp/autosar/useless-assignment] | nested/test.h:1:1:6:1 | Deviation of cpp/autosar/useless-assignment for nested/test.h. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
codingstandards/cpp/deviations/DeviationsSuppression.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
| main.cpp:11:15:11:16 | d1 | Use of long double type. |
2+
| main.cpp:12:15:12:16 | d2 | Use of long double type. |
3+
| main.cpp:14:15:14:16 | d3 | Use of long double type. |
4+
| main.cpp:16:15:16:16 | d4 | Use of long double type. |
5+
| main.cpp:18:15:18:16 | d5 | Use of long double type. |
6+
| main.cpp:19:15:19:16 | d6 | Use of long double type. |
7+
| main.cpp:22:15:22:16 | d7 | Use of long double type. |
8+
| main.cpp:24:15:24:16 | d8 | Use of long double type. |
9+
| main.cpp:26:15:26:16 | d9 | Use of long double type. |
10+
| main.cpp:28:15:28:17 | d10 | Use of long double type. |
11+
| main.cpp:30:15:30:17 | d11 | Use of long double type. |
12+
| main.cpp:32:15:32:17 | d12 | Use of long double type. |
13+
| main.cpp:34:15:34:17 | d13 | Use of long double type. |
14+
| main.cpp:36:15:36:17 | d14 | Use of long double type. |
15+
| main.cpp:40:15:40:17 | d15 | Use of long double type. |
16+
| main.cpp:40:108:40:110 | d16 | Use of long double type. |
17+
| main.cpp:41:15:41:17 | d17 | Use of long double type. |
18+
| main.cpp:41:113:41:115 | d18 | Use of long double type. |

0 commit comments

Comments
 (0)