Deviations: Support C/C++ attributes
This commit adds support for C/C++ attributes to specify deviations with code identifiers in the code. Attributes are inherited from parents, and support multiple code identifiers in a single definition.
This commit is contained in:
Родитель
6e68fb8645
Коммит
1a2454165d
|
@ -177,6 +177,40 @@ private predicate isDeviationRangePaired(
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A standard attribute that either deviates a result.
|
||||
*/
|
||||
class DeviationAttribute extends StdAttribute {
|
||||
DeviationRecord record;
|
||||
|
||||
DeviationAttribute() {
|
||||
this.hasQualifiedName("codingstandards", "deviation") and
|
||||
// Support multiple argument deviations
|
||||
"\"" + record.getCodeIdentifier() + "\"" = this.getAnArgument().getValueText()
|
||||
}
|
||||
|
||||
DeviationRecord getDeviationRecord() { result = record }
|
||||
|
||||
pragma[nomagic]
|
||||
Element getASuppressedElement() {
|
||||
result.(Type).getAnAttribute() = this
|
||||
or
|
||||
result.(Stmt).getAnAttribute() = this
|
||||
or
|
||||
result.(Variable).getAnAttribute() = this
|
||||
or
|
||||
result.(Function).getAnAttribute() = this
|
||||
or
|
||||
result.(Expr).getEnclosingStmt() = this.getASuppressedElement()
|
||||
or
|
||||
result.(Stmt).getParentStmt() = this.getASuppressedElement()
|
||||
or
|
||||
result.(Stmt).getEnclosingFunction() = this.getASuppressedElement()
|
||||
or
|
||||
result.(LocalVariable) = this.getASuppressedElement().(DeclStmt).getADeclaration()
|
||||
}
|
||||
}
|
||||
|
||||
newtype TCodeIndentifierDeviation =
|
||||
TSingleLineDeviation(DeviationRecord record, Comment comment, string filepath, int suppressedLine) {
|
||||
(
|
||||
|
@ -195,6 +229,9 @@ newtype TCodeIndentifierDeviation =
|
|||
isDeviationRangePaired(record, beginComment, endComment) and
|
||||
beginComment.getLocation().hasLocationInfo(filepath, suppressedStartLine, _, _, _) and
|
||||
endComment.getLocation().hasLocationInfo(filepath, suppressedEndLine, _, _, _)
|
||||
} or
|
||||
TCodeIdentifierDeviation(DeviationRecord record, DeviationAttribute attribute) {
|
||||
attribute.getDeviationRecord() = record
|
||||
}
|
||||
|
||||
class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
|
||||
|
@ -203,6 +240,8 @@ class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
|
|||
this = TSingleLineDeviation(result, _, _, _)
|
||||
or
|
||||
this = TMultiLineDeviation(result, _, _, _, _, _)
|
||||
or
|
||||
this = TCodeIdentifierDeviation(result, _)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,6 +264,11 @@ class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
|
|||
suppressedEndLine > elementLocationStart
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(DeviationAttribute attribute |
|
||||
this = TCodeIdentifierDeviation(_, attribute) and
|
||||
attribute.getASuppressedElement() = e
|
||||
)
|
||||
}
|
||||
|
||||
string toString() {
|
||||
|
@ -243,5 +287,10 @@ class CodeIdentifierDeviation extends TCodeIndentifierDeviation {
|
|||
suppressedStartLine + ":" + suppressedEndLine
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(DeviationAttribute attribute |
|
||||
this = TCodeIdentifierDeviation(_, attribute) and
|
||||
result = "Deviation record " + getDeviationRecord() + " applied to " + attribute
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
| attribute_syntax.cpp:6:15:6:17 | dd1 | Use of long double type. |
|
||||
| attribute_syntax.cpp:22:15:22:17 | d10 | Use of long double type. |
|
||||
| attribute_syntax.cpp:30:15:30:17 | d14 | Use of long double type. |
|
||||
| attribute_syntax.cpp:34:20:34:22 | d16 | Use of long double type. |
|
||||
| main.cpp:13:15:13:16 | d1 | Use of long double type. |
|
||||
| main.cpp:18:15:18:16 | d4 | Use of long double type. |
|
||||
| main.cpp:21:15:21:16 | d6 | Use of long double type. |
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
| attribute_syntax.cpp:5:3:5:6 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| attribute_syntax.cpp:17:5:17:8 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| attribute_syntax.cpp:19:5:19:8 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| attribute_syntax.cpp:25:5:25:8 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| attribute_syntax.cpp:27:5:27:8 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| attribute_syntax.cpp:31:3:31:6 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| attribute_syntax.cpp:42:3:42:6 | call to getZ | Return value from call to $@ is unused. | attribute_syntax.cpp:1:5:1:8 | getZ | getZ |
|
||||
| main.cpp:12:3:12:6 | call to getX | Return value from call to $@ is unused. | main.cpp:8:5:8:8 | getX | getX |
|
||||
| main.cpp:25:3:25:6 | call to getX | Return value from call to $@ is unused. | main.cpp:8:5:8:8 | getX | getX |
|
||||
| main.cpp:27:3:27:6 | call to getX | Return value from call to $@ is unused. | main.cpp:8:5:8:8 | getX | getX |
|
||||
| main.cpp:33:3:33:6 | call to getX | Return value from call to $@ is unused. | main.cpp:8:5:8:8 | getX | getX |
|
||||
| main.cpp:35:3:35:6 | call to getX | Return value from call to $@ is unused. | main.cpp:8:5:8:8 | getX | getX |
|
||||
| main.cpp:39:3:39:6 | call to getX | Return value from call to $@ is unused. | main.cpp:8:5:8:8 | getX | getX |
|
||||
| nested/nested3/test3.h:5:3:5:7 | call to getZ3 | Return value from call to $@ is unused. | nested/nested3/test3.h:1:5:1:9 | getZ3 | getZ3 |
|
||||
| nested/test.h:5:3:5:6 | call to getY | Return value from call to $@ is unused. | nested/test.h:1:5:1:8 | getY | getY |
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
int getZ() { return 5; }
|
||||
|
||||
int alt() {
|
||||
int x = 0; // COMPLIANT[DEVIATED]
|
||||
getZ(); // NON_COMPLIANT
|
||||
long double dd1; // NON_COMPLIANT (A0-4-2)
|
||||
|
||||
long double [[codingstandards::deviation(
|
||||
"a-0-4-2-deviation")]] dd3; // COMPLIANT[DEVIATED]
|
||||
long double [[codingstandards::deviation("a")]] dd3a; // NON_COMPLIAT
|
||||
|
||||
[[codingstandards::deviation(
|
||||
"a-0-4-2-deviation")]] long double dd4; // COMPLIANT[DEVIATED]
|
||||
|
||||
[[codingstandards::deviation("a-0-4-2-deviation")]] {
|
||||
long double d7; // COMPLIANT[DEVIATED]
|
||||
getZ(); // NON_COMPLIANT (A0-1-2)
|
||||
long double d8; // COMPLIANT[DEVIATED]
|
||||
getZ(); // NON_COMPLIANT (A0-1-2)
|
||||
long double d9; // COMPLIANT[DEVIATED]
|
||||
}
|
||||
long double d10; // NON_COMPLIANT (A0-4-2)
|
||||
[[codingstandards::deviation("a-0-4-2-deviation")]] {
|
||||
long double d11; // COMPLIANT[DEVIATED]
|
||||
getZ(); // NON_COMPLIANT (A0-1-2)
|
||||
long double d12; // COMPLIANT[DEVIATED]
|
||||
getZ(); // NON_COMPLIANT (A0-1-2)
|
||||
long double d13; // COMPLIANT[DEVIATED]
|
||||
}
|
||||
long double d14; // NON_COMPLIANT (A0-4-2)
|
||||
getZ(); // NON_COMPLIANT (A0-1-2)
|
||||
[[codingstandards::deviation("a-0-4-2-deviation")]]
|
||||
for (long double d15 = 0.0; true;) {} // COMPLIANT[DEVIATED]
|
||||
for (long double d16 = 0.0; true;) { // NON_COMPLIANT (A0-4-2)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
[[codingstandards::deviation("a-0-4-2-deviation")]]
|
||||
int alt2() {
|
||||
int x = 0; // COMPLIANT[DEVIATED]
|
||||
getZ(); // NON_COMPLIANT
|
||||
long double dd1; // COMPLIANT[DEVIATED]
|
||||
}
|
|
@ -421,15 +421,50 @@ The `process_coding_standards_config.py` has a dependency on the package `pyyaml
|
|||
|
||||
`pip3 install -r path/to/codeql-coding-standards/scripts/configuration/requirements.txt`
|
||||
|
||||
##### Deviation code identifiers
|
||||
##### Deviation code identifier attributes
|
||||
|
||||
A code identifier specified in a deviation record can be applied to certain results in the code by adding a comment marker consisting of a `code-identifier` with some optional annotations. The supported marker annotation formats are:
|
||||
A code identifier specified in a deviation record can be applied to certain results in the code by adding a C or C++ attribute of the following format:
|
||||
|
||||
```
|
||||
[[codingstandards::deviation("code-identifier")]]
|
||||
```
|
||||
|
||||
This attribute may be added to the following program elements:
|
||||
* Functions
|
||||
* Statements
|
||||
* Variables
|
||||
* Type declarations
|
||||
|
||||
Deviation attributes are inherited from parents in the code structure. For example, a deviation attribute applied to a function will apply the deviation to all code within the function. Note: deviations are not inherited by lambda expressions.
|
||||
|
||||
Multiple code identifiers may be passed in a single attribute to apply multiple deviations, for example:
|
||||
|
||||
```
|
||||
[[codingstandards::deviation("code-identifier-1", "code-identifier-2")]]
|
||||
```
|
||||
|
||||
Note - considation should be taken to ensure the use of custom attributes for deviations is compatible with your chosen language version, compiler, compiler configuration and coding standard.
|
||||
|
||||
**Use of attributes in C Coding Standards**: The C Standard introduces attributes in C23, however some compilers support attributes as a language extension in prior versions. You should:
|
||||
* Confirm that your compiler supports attributes for your chosen compiler configuration, if necessary as a language extension.
|
||||
* Confirm that unknown attributes are ignored by the compiler.
|
||||
* For MISRA C, add a project deviation against "Rule 1.2: Language extensions should not be used", if attribute support is a language extension in your language version.
|
||||
|
||||
**Use of attributes in C++ Coding Standards**: The C++ Standard supports attributes in C++14, however the handling of unknown attributes is implementation defined. From C++17 onwards, unknown attributes are mandated to be ignored. Unknown attributes will usually raise an "unknown attribute" warning. You should:
|
||||
* If using C++14, confirm that your compiler ignores unknown attributes.
|
||||
* If using AUTOSAR and a compiler which produces warnings on unknown attributes, the compiler warning should be disabled (as per `A1-1-2: A warning level of the compilation process shall be set in compliance with project policies`), to ensure compliance with `A1-4-3: All code should compiler free of compiler warnings`.
|
||||
|
||||
If you cannot satisfy these condition, please use the deviation code identifier comment format instead.
|
||||
|
||||
##### Deviation code identifier comments
|
||||
|
||||
As an alternative to attributes, a code identifier specified in a deviation record can be applied to certain results in the code by adding a comment marker consisting of a `code-identifier` with some optional annotations. The supported marker annotation formats are:
|
||||
|
||||
- `<code-identifier>` - the deviation applies to results on the current line.
|
||||
- `codingstandards::deviation(<code-identifier>)` - the deviation applies to results on the current line.
|
||||
- `codingstandards::deviation_next_line(<code-identifier>)` - this deviation applies to results on the next line.
|
||||
- `DEVIATION_BEGIN(<code-identifier>)` - marks the beginning of a range of lines where the deviation applies.
|
||||
- `DEVIATION_END(<code-identifier>)` - marks the end of a range of lines where the deviation applies.
|
||||
- `codingstandards::deviation_begin(<code-identifier>)` - marks the beginning of a range of lines where the deviation applies.
|
||||
- `codingstandards::deviation_end(<code-identifier>)` - marks the end of a range of lines where the deviation applies.
|
||||
|
||||
Here are some examples, using the deviation record with the `a-0-4-2-deviation` code-identifier specified above:
|
||||
```cpp
|
||||
|
@ -465,7 +500,9 @@ A `codingstandards::deviation_end` without a matching `codingstandards::deviatio
|
|||
|
||||
`codingstandards::deviation_begin` and `codingstandards::deviation_end` markers only apply within a single file. Markers cannot be paired across files, and deviations do not apply to included files.
|
||||
|
||||
##### Deviation permit
|
||||
Note: deviation markers cannot be applied to the body of a macro. Please apply the deviation to macro expansion, or use the attribute deviation format.
|
||||
|
||||
##### Deviation permits
|
||||
|
||||
The current implementation supports _deviation permits_ as described in the [MISRA Compliance:2020](https://www.misra.org.uk/app/uploads/2021/06/MISRA-Compliance-2020.pdf) section _4.3 Deviation permits_.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче