Skip to content

Commit 3d578f0

Browse files
Address feedback
1 parent 5d22374 commit 3d578f0

File tree

9 files changed

+85
-35
lines changed

9 files changed

+85
-35
lines changed

cpp/common/src/codingstandards/cpp/exclusions/cpp/Preprocessor.qll

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ newtype PreprocessorQuery =
77
TUndefOfMacroNotDefinedInFileQuery() or
88
TInvalidTokenInDefinedOperatorQuery() or
99
TDefinedOperatorExpandedInIfDirectiveQuery() or
10-
TNoValidIfdefGuardInHeaderQuery()
10+
TNoValidIfdefGuardInHeaderQuery() or
11+
TIncludeOutsideGuardQuery()
1112

1213
predicate isPreprocessorQueryMetadata(Query query, string queryId, string ruleId, string category) {
1314
query =
@@ -45,6 +46,15 @@ predicate isPreprocessorQueryMetadata(Query query, string queryId, string ruleId
4546
"cpp/misra/no-valid-ifdef-guard-in-header" and
4647
ruleId = "RULE-19-2-1" and
4748
category = "required"
49+
or
50+
query =
51+
// `Query` instance for the `includeOutsideGuard` query
52+
PreprocessorPackage::includeOutsideGuardQuery() and
53+
queryId =
54+
// `@id` for the `includeOutsideGuard` query
55+
"cpp/misra/include-outside-guard" and
56+
ruleId = "RULE-19-2-1" and
57+
category = "required"
4858
}
4959

5060
module PreprocessorPackage {
@@ -75,4 +85,11 @@ module PreprocessorPackage {
7585
// `Query` type for `noValidIfdefGuardInHeader` query
7686
TQueryCPP(TPreprocessorPackageQuery(TNoValidIfdefGuardInHeaderQuery()))
7787
}
88+
89+
Query includeOutsideGuardQuery() {
90+
//autogenerate `Query` type
91+
result =
92+
// `Query` type for `includeOutsideGuard` query
93+
TQueryCPP(TPreprocessorPackageQuery(TIncludeOutsideGuardQuery()))
94+
}
7895
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @id cpp/misra/include-outside-guard
3+
* @name RULE-19-2-1: Comments are the only content permitted outside of the scope of an include guard in a header file
4+
* @description Include directives shall be within the scope of an include guard.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-19-2-1
9+
* scope/single-translation-unit
10+
* maintainability
11+
* correctness
12+
* external/misra/enforcement/decidable
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.cpp.misra
18+
import semmle.code.cpp.headers.MultipleInclusion
19+
20+
predicate isOutside(CorrectIncludeGuard includeGuard, Location location) {
21+
location.getFile() = includeGuard.getFile() and
22+
(
23+
location.isBefore(includeGuard.getIfndef().getLocation())
24+
or
25+
includeGuard.getEndif().getLocation().isBefore(location)
26+
)
27+
}
28+
29+
from Include include, CorrectIncludeGuard includeGuard, HeaderFile header
30+
where
31+
not isExcluded(include, PreprocessorPackage::includeOutsideGuardQuery()) and
32+
includeGuard.getFile() = header and
33+
header = include.getFile() and
34+
isOutside(includeGuard, include.getLocation())
35+
select include, "Include is outside of its header file's $@.", includeGuard.getIfndef(),
36+
"include guard"

cpp/misra/src/rules/RULE-19-2-1/NoValidIfdefGuardInHeader.ql

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,8 @@
1616

1717
import cpp
1818
import codingstandards.cpp.misra
19-
import semmle.code.cpp.headers.MultipleInclusion
19+
import codingstandards.cpp.rules.includeguardsnotused.IncludeGuardsNotUsed
2020

21-
predicate isOutside(CorrectIncludeGuard includeGuard, Location location) {
22-
location.getFile() = includeGuard.getFile() and
23-
(
24-
location.isBefore(includeGuard.getIfndef().getLocation())
25-
or
26-
includeGuard.getEndif().getLocation().isBefore(location)
27-
)
21+
class NoValidIfdefGuardInHeaderQuery extends IncludeGuardsNotUsedSharedQuery {
22+
NoValidIfdefGuardInHeaderQuery() { this = PreprocessorPackage::noValidIfdefGuardInHeaderQuery() }
2823
}
29-
30-
from File included
31-
where
32-
not isExcluded(included, PreprocessorPackage::noValidIfdefGuardInHeaderQuery()) and
33-
included = any(Compilation c).getAFileCompiled().getAnIncludedFile+() and
34-
not exists(CorrectIncludeGuard includeGuard |
35-
includeGuard.getFile() = included and
36-
// Stricter: define is before all other contents
37-
not included
38-
.getATopLevelDeclaration()
39-
.getLocation()
40-
.isBefore(includeGuard.getDefine().getLocation()) and
41-
// Stricter: do not allow includes outside of the inclusion guard
42-
not exists(Include include | isOutside(includeGuard, include.getLocation()))
43-
)
44-
select included, "File does not have a well formatted include guard."
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| invalid8.h:1:1:1:19 | #include "valid1.h" | Include is outside of its header file's $@. | invalid8.h:3:1:3:18 | #ifndef INVALID8_H | include guard |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-19-2-1/IncludeOutsideGuard.ql
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
| invalid1.h:0:0:0:0 | invalid1.h | File does not have a well formatted include guard. |
2-
| invalid2.h:0:0:0:0 | invalid2.h | File does not have a well formatted include guard. |
3-
| invalid3.h:0:0:0:0 | invalid3.h | File does not have a well formatted include guard. |
4-
| invalid4.h:0:0:0:0 | invalid4.h | File does not have a well formatted include guard. |
5-
| invalid5_file2.h:0:0:0:0 | invalid5_file2.h | File does not have a well formatted include guard. |
6-
| invalid6_b.h:0:0:0:0 | invalid6_b.h | File does not have a well formatted include guard. |
7-
| invalid7.h:0:0:0:0 | invalid7.h | File does not have a well formatted include guard. |
8-
| invalid8.h:0:0:0:0 | invalid8.h | File does not have a well formatted include guard. |
9-
| invalid9.h:0:0:0:0 | invalid9.h | File does not have a well formatted include guard. |
1+
| invalid1.h:0:0:0:0 | invalid1.h | Header file invalid1.h is missing expected include guard. | invalid1.h:0:0:0:0 | invalid1.h | |
2+
| invalid2.h:0:0:0:0 | invalid2.h | Header file invalid2.h is missing expected include guard. | invalid2.h:0:0:0:0 | invalid2.h | |
3+
| invalid3.h:0:0:0:0 | invalid3.h | Header file invalid3.h is missing expected include guard. | invalid3.h:0:0:0:0 | invalid3.h | |
4+
| invalid4.h:0:0:0:0 | invalid4.h | Header file invalid4.h is missing expected include guard. | invalid4.h:0:0:0:0 | invalid4.h | |
5+
| invalid5_file2.h:0:0:0:0 | invalid5_file2.h | Header file invalid5_file2.h is missing expected include guard. | invalid5_file2.h:0:0:0:0 | invalid5_file2.h | |
6+
| invalid6_b.h:0:0:0:0 | invalid6_b.h | Header file invalid6_b.h is never included by reusing the include guard used by $@. | invalid6_a.h:0:0:0:0 | invalid6_a.h | include guard |
7+
| invalid7.h:0:0:0:0 | invalid7.h | Header file invalid7.h is missing expected include guard. | invalid7.h:0:0:0:0 | invalid7.h | |
8+
| invalid9.h:0:0:0:0 | invalid9.h | Header file invalid9.h is missing expected include guard. | invalid9.h:0:0:0:0 | invalid9.h | |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/includeguardsnotused/IncludeGuardsNotUsed.ql

cpp/misra/test/rules/RULE-19-2-1/valid2.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#if !defined(VALID2_H)
44
#define VALID2_H
55

6+
// COMPLIANT
67
void valid2_f1();
78

8-
#endif
9+
#endif
10+
// COMPLIANT

rule_packages/cpp/Preprocessor.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,20 @@
7070
"precision": "very-high",
7171
"severity": "error",
7272
"short_name": "NoValidIfdefGuardInHeader",
73+
"shared_implementation_short_name": "IncludeGuardsNotUsed",
74+
"tags": [
75+
"scope/single-translation-unit",
76+
"maintainability",
77+
"correctness"
78+
]
79+
},
80+
{
81+
"description": "Include directives shall be within the scope of an include guard.",
82+
"kind": "problem",
83+
"name": "Comments are the only content permitted outside of the scope of an include guard in a header file",
84+
"precision": "very-high",
85+
"severity": "error",
86+
"short_name": "IncludeOutsideGuard",
7387
"tags": [
7488
"scope/single-translation-unit",
7589
"maintainability",

0 commit comments

Comments
 (0)