Skip to content

Commit 2a805c0

Browse files
authored
Merge pull request #748 from github/lcartey/a7-1-3
`A7-1-3`: Remove false positives where the typedef type is referenced in the initializer
2 parents d0c84dc + 917bb45 commit 2a805c0

File tree

4 files changed

+44
-16
lines changed

4 files changed

+44
-16
lines changed

Diff for: change_notes/2024-10-15-a7-1-3-multi-refs.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `A7-1-3` - `CvQualifiersNotPlacedOnTheRightHandSide.ql`:
2+
- Removed false positives where a correctly CV-qualified typedef variable type was also referenced in the initializer.

Diff for: cpp/autosar/src/rules/A7-1-3/CvQualifiersNotPlacedOnTheRightHandSide.ql

+29-16
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,50 @@ import cpp
2020
import codingstandards.cpp.autosar
2121

2222
/**
23-
* Holds if declaration `e` using a `TypedefType` is CV-qualified
24-
*
25-
* For example, given `using intconstptr = int * const`:
26-
* the predicate holds for `const/volatile intconstptr ptr1`, but not for `intconstptr ptr2`
23+
* Unwrap layers of indirection that occur on the right side of the type.
2724
*/
28-
predicate containsExtraSpecifiers(VariableDeclarationEntry e) {
29-
e.getType().toString().matches("const %") or
30-
e.getType().toString().matches("volatile %")
25+
Type unwrapIndirection(Type type) {
26+
if type instanceof DerivedType and not type instanceof SpecifiedType
27+
then result = unwrapIndirection(type.(DerivedType).getBaseType())
28+
else result = type
3129
}
3230

3331
// DeclStmts that have a TypedefType name use (ie TypeMention) in them
3432
//AND TypeMention.getStartColumn() - DeclStmt.getStartColumn() > len(const)
3533
//AND the declared thing contains one of these "extra" specifiers in the DeclarationEntry Location
36-
from VariableDeclarationEntry e, TypedefType t, TypeMention tm
34+
from
35+
VariableDeclarationEntry e, TypedefType t, TypeMention tm, string message, Element explainer,
36+
string explainerMessage
3737
where
3838
not isExcluded(e, ConstPackage::cvQualifiersNotPlacedOnTheRightHandSideQuery()) and
39-
containsExtraSpecifiers(e) and
39+
// Variable type is specified, and has the typedef type as a base type
40+
unwrapIndirection(e.getType()).(SpecifiedType).getBaseType() = t and
4041
exists(string filepath, int startline |
4142
e.getLocation().hasLocationInfo(filepath, startline, _, _, _) and
4243
tm.getLocation().hasLocationInfo(filepath, startline, _, _, _) and
4344
e = t.getATypeNameUse() and
4445
tm.getMentionedType() = t and
46+
// TypeMention occurs before the variable declaration
47+
tm.getLocation().getStartColumn() < e.getLocation().getStartColumn() and
4548
exists(DeclStmt s |
4649
s.getDeclarationEntry(_) = e and
47-
//const could fit in there
50+
// TypeMention occurs after the start of the StmtDecl, with enough space for const/volatile
4851
tm.getLocation().getStartColumn() - s.getLocation().getStartColumn() > 5
49-
//volatile could fit in there
50-
//but the above condition subsumes this one
51-
//l.getStartColumn() - tm.getLocation().getStartColumn() > 8
5252
)
53+
) and
54+
if exists(t.getFile().getRelativePath())
55+
then
56+
message =
57+
"There is possibly a const or volatile specifier on the left hand side of typedef name $@." and
58+
explainer = t and
59+
explainerMessage = t.getName()
60+
else (
61+
// Type occurs outside source root, so don't link
62+
message =
63+
"There is possibly a const or volatile specifier on the left hand side of typedef name " +
64+
t.getName() + "." and
65+
// explainer not used in this case
66+
explainer = e and
67+
explainerMessage = ""
5368
)
54-
select e,
55-
"There is possibly a const or volatile specifier on the left hand side of typedef name $@.", t,
56-
t.getName()
69+
select e, message, explainer, explainerMessage
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
| test.cpp:9:16:9:19 | definition of ptr1 | There is possibly a const or volatile specifier on the left hand side of typedef name $@. | test.cpp:1:7:1:12 | intptr | intptr |
22
| test.cpp:10:19:10:22 | definition of ptr2 | There is possibly a const or volatile specifier on the left hand side of typedef name $@. | test.cpp:1:7:1:12 | intptr | intptr |
33
| test.cpp:19:21:19:24 | definition of ptr8 | There is possibly a const or volatile specifier on the left hand side of typedef name $@. | test.cpp:3:7:3:17 | constintptr | constintptr |
4+
| test.cpp:32:23:32:26 | definition of u32d | There is possibly a const or volatile specifier on the left hand side of typedef name uint32_t. | test.cpp:32:23:32:26 | definition of u32d | |

Diff for: cpp/autosar/test/rules/A7-1-3/test.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,16 @@ void f() {
1818
constintptr const ptr7 = &l; // COMPLIANT
1919
const constintptr ptr8 = &l; // NON_COMPLIANT
2020
inttypedef ptr9 = l; // COMPLIANT
21+
}
22+
23+
#include <cstdint>
24+
25+
void false_positive() {
26+
std::uint8_t u8{0};
27+
28+
auto const u32 = static_cast<std::uint32_t>(u8); // COMPLIANT - auto ignored
29+
std::uint32_t const u32b = static_cast<std::uint32_t>(u8); // COMPLIANT
30+
31+
const auto u32c = static_cast<std::uint32_t>(u8); // COMPLIANT - auto ignored
32+
const std::uint32_t u32d = static_cast<std::uint32_t>(u8); // NON_COMPLIANT
2133
}

0 commit comments

Comments
 (0)