Skip to content

Commit cb07855

Browse files
committed
Rule 8.13: Handle multiple copies
If the same code is compiled multiple times, variables may be const in one case but non-const in another. Handle this by requiring all such copies to be const-able before flagging.
1 parent 2a805c0 commit cb07855

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,47 @@ import cpp
1818
import codingstandards.c.misra
1919
import codingstandards.cpp.Pointers
2020
import codingstandards.cpp.SideEffect
21+
import codingstandards.cpp.alertreporting.HoldsForAllCopies
2122

22-
from Variable ptr, PointerOrArrayType type
23+
class NonConstPointerVariableCandidate extends Variable {
24+
NonConstPointerVariableCandidate() {
25+
// Avoid elements in macro expansions, as they cannot be equated across copies
26+
not this.isInMacroExpansion() and
27+
exists(PointerOrArrayType type |
28+
// include only pointers which point to a const-qualified type
29+
this.getType() = type and
30+
not type.isDeeplyConstBelow()
31+
) and
32+
// exclude pointers passed as arguments to functions which take a
33+
// parameter that points to a non-const-qualified type
34+
not exists(FunctionCall fc, int i |
35+
fc.getArgument(i) = this.getAnAccess() and
36+
not fc.getTarget().getParameter(i).getType().isDeeplyConstBelow()
37+
) and
38+
// exclude any pointers which have their underlying data modified
39+
not exists(VariableEffect effect |
40+
effect.getTarget() = this and
41+
// but not pointers that are only themselves modified
42+
not effect.(AssignExpr).getLValue() = effect.getAnAccess() and
43+
not effect.(CrementOperation).getOperand() = effect.getAnAccess()
44+
) and
45+
// exclude pointers assigned to another pointer to a non-const-qualified type
46+
not exists(Variable a |
47+
a.getAnAssignedValue() = this.getAnAccess() and
48+
not a.getType().(PointerOrArrayType).isDeeplyConstBelow()
49+
)
50+
}
51+
}
52+
53+
/**
54+
* Ensure that all copies of a variable are considered to be missing const qualification to avoid
55+
* false positives where a variable is only used/modified in a single copy.
56+
*/
57+
class NonConstPointerVariable =
58+
HoldsForAllCopies<NonConstPointerVariableCandidate, Variable>::LogicalResultElement;
59+
60+
from NonConstPointerVariable ptr
2361
where
24-
not isExcluded(ptr, Pointers1Package::pointerShouldPointToConstTypeWhenPossibleQuery()) and
25-
// include only pointers which point to a const-qualified type
26-
ptr.getType() = type and
27-
not type.isDeeplyConstBelow() and
28-
// exclude pointers passed as arguments to functions which take a
29-
// parameter that points to a non-const-qualified type
30-
not exists(FunctionCall fc, int i |
31-
fc.getArgument(i) = ptr.getAnAccess() and
32-
not fc.getTarget().getParameter(i).getType().isDeeplyConstBelow()
33-
) and
34-
// exclude any pointers which have their underlying data modified
35-
not exists(VariableEffect effect |
36-
effect.getTarget() = ptr and
37-
// but not pointers that are only themselves modified
38-
not effect.(AssignExpr).getLValue() = effect.getAnAccess() and
39-
not effect.(CrementOperation).getOperand() = effect.getAnAccess()
40-
) and
41-
// exclude pointers assigned to another pointer to a non-const-qualified type
42-
not exists(Variable a |
43-
a.getAnAssignedValue() = ptr.getAnAccess() and
44-
not a.getType().(PointerOrArrayType).isDeeplyConstBelow()
45-
)
46-
select ptr, "$@ points to a non-const-qualified type.", ptr, ptr.getName()
62+
not isExcluded(ptr.getAnElementInstance(),
63+
Pointers1Package::pointerShouldPointToConstTypeWhenPossibleQuery())
64+
select ptr, "$@ points to a non-const-qualified type.", ptr, ptr.getAnElementInstance().getName()

0 commit comments

Comments
 (0)