-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathTraditionalCStyleCastsUsed.ql
More file actions
86 lines (82 loc) · 3.05 KB
/
TraditionalCStyleCastsUsed.ql
File metadata and controls
86 lines (82 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
* @id cpp/autosar/traditional-c-style-casts-used
* @name A5-2-2: Traditional C-style casts shall not be used
* @description Traditional C-style casts shall not be used.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/autosar/id/a5-2-2
* correctness
* scope/single-translation-unit
* external/autosar/allocated-target/implementation
* external/autosar/enforcement/automated
* external/autosar/obligation/required
*/
import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.Macro
import codingstandards.cpp.CStyleCasts
/**
* Gets the macro (if any) that generated the given `CStyleCast`.
*
* If there are nested macro invocations, we identify the most specific macro that generated the
* cast.
*/
Macro getGeneratedFrom(CStyleCast c) {
exists(MacroInvocation mi |
mi = result.getAnInvocation() and
mi.getAGeneratedElement() = c and
mi.getLocation().getStartColumn() = c.getLocation().getStartColumn() and
not exists(MacroInvocation child |
child.getParentInvocation() = mi and
child.getAGeneratedElement() = c
)
)
}
/*
* In theory this query should exclude casts using the "functional notation" syntax, e.g.
* ```
* int(x);
* ```
* This is because this is not a C-style cast, as it is not legitimate C code. However, our database
* schema does not distinguish between C-style casts and functional casts, so we cannot exclude just
* those.
*
* In addition, we do not get `CStyleCasts` in cases where the cast is converted to a `ConstructorCall`.
* This holds for both the "functional notation" syntax and the "c-style" syntax, e.g. both of these
* are represented in our model as `ConstructorCall`s only:
* ```
* class A { public: A(int); };
* void create() {
* (A)1;
* A(1);
* }
* ```
*
* As a consequence this query:
* - Produces false positives when primitive types are cast using the "functional notation" syntax.
* - Produces false negatives when a C-style cast is converted to a `ConstructorCall` e.g. when the
* argument type is compatible with a single-argument constructor.
*/
from ExplicitUserDefinedCStyleCast c, string extraMessage, Locatable l, string supplementary
where
not isExcluded(c, BannedSyntaxPackage::traditionalCStyleCastsUsedQuery()) and
// Not generated from a library macro
not getGeneratedFrom(c) instanceof LibraryMacro and
// If the cast was generated from a user-provided macro, then report the macro that generated the
// cast, as the macro itself may have generated the cast
if getGeneratedFrom(c) instanceof UserProvidedMacro
then
extraMessage = " generated from macro $@" and
// Add macro as explanatory link
l = getGeneratedFrom(c) and
supplementary = getGeneratedFrom(c).getName()
else (
// No extra message required
extraMessage = "" and
// No explanatory link required, but we still need to set these to valid values
l = c and
supplementary = ""
)
select c, "Use of explicit c-style cast to " + c.getType().getName() + extraMessage + ".", l,
supplementary