Skip to content

Commit e039876

Browse files
committed
A5-2-2: Exclude c-style casts generated by library macros
casts generated by library macros are not modifiable by the user, so can be excluded from the results of this rule. In addition, this commit improves the query message to specify whether the cast was generated due to the expansion of a macro, and to provide a link to the macro in question. This helps users identify the location in the code where the cast is actually written.
1 parent f9a2c5e commit e039876

File tree

5 files changed

+81
-7
lines changed

5 files changed

+81
-7
lines changed

cpp/autosar/src/rules/A5-2-2/TraditionalCStyleCastsUsed.ql

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,54 @@
1616
import cpp
1717
import codingstandards.cpp.autosar
1818

19-
from CStyleCast c
19+
/**
20+
* Gets the macro (if any) that generated the given `CStyleCast`.
21+
*
22+
* If there are nested macro invocations, we identify the most specific macro that generated the
23+
* cast.
24+
*/
25+
Macro getGeneratedFrom(CStyleCast c) {
26+
exists(MacroInvocation mi |
27+
mi = result.getAnInvocation() and
28+
mi.getAGeneratedElement() = c and
29+
mi.getLocation().getStartColumn() = c.getLocation().getStartColumn() and
30+
not exists(MacroInvocation child |
31+
child.getParentInvocation() = mi and
32+
child.getAGeneratedElement() = c
33+
)
34+
)
35+
}
36+
37+
/** A macro within the source location of this project. */
38+
class UserProvidedMacro extends Macro {
39+
UserProvidedMacro() { exists(this.getFile().getRelativePath()) }
40+
}
41+
42+
/** A macro defined within a library used by this project. */
43+
class LibraryMacro extends Macro {
44+
LibraryMacro() { not this instanceof UserProvidedMacro }
45+
}
46+
47+
from CStyleCast c, string extraMessage, Locatable l, string supplementary
2048
where
2149
not isExcluded(c, BannedSyntaxPackage::traditionalCStyleCastsUsedQuery()) and
2250
not c.isImplicit() and
23-
not c.getType() instanceof UnknownType
24-
select c, "Use of explicit C-style Cast"
51+
not c.getType() instanceof UnknownType and
52+
// Exclude casts created from macro invocations of macros defined by third parties
53+
not getGeneratedFrom(c) instanceof LibraryMacro and
54+
// If the cast was generated from a user-provided macro, then report the macro that generated the
55+
// cast, as the macro itself may have generated the cast
56+
if getGeneratedFrom(c) instanceof UserProvidedMacro
57+
then
58+
extraMessage = " generated from macro $@" and
59+
// Add macro as explanatory link
60+
l = getGeneratedFrom(c) and
61+
supplementary = getGeneratedFrom(c).getName()
62+
else (
63+
// No extra message required
64+
extraMessage = "" and
65+
// No explanatory link required, but we still need to set these to valid values
66+
l = c and
67+
supplementary = ""
68+
)
69+
select c, "Use of explicit c-style cast" + extraMessage, l, supplementary
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
| test.cpp:8:22:8:37 | (uint32_t)... | Use of explicit C-style Cast |
2-
| test.cpp:9:22:9:32 | (unsigned int)... | Use of explicit C-style Cast |
3-
| test.cpp:15:3:15:13 | (void)... | Use of explicit C-style Cast |
1+
| test.cpp:8:22:8:37 | (uint32_t)... | Use of explicit c-style cast | test.cpp:8:22:8:37 | (uint32_t)... | |
2+
| test.cpp:9:22:9:32 | (unsigned int)... | Use of explicit c-style cast | test.cpp:9:22:9:32 | (unsigned int)... | |
3+
| test.cpp:15:3:15:13 | (void)... | Use of explicit c-style cast | test.cpp:15:3:15:13 | (void)... | |
4+
| test.cpp:77:3:77:11 | (int)... | Use of explicit c-style cast generated from macro $@ | test.cpp:70:1:70:31 | #define ADD_ONE(x) ((int)x) + 1 | ADD_ONE |
5+
| test.cpp:79:3:79:18 | (int)... | Use of explicit c-style cast generated from macro $@ | test.cpp:71:1:71:36 | #define NESTED_ADD_ONE(x) ADD_ONE(x) | NESTED_ADD_ONE |
6+
| test.cpp:85:19:85:26 | (int)... | Use of explicit c-style cast | test.cpp:85:19:85:26 | (int)... | |
7+
| test.cpp:86:27:86:34 | (int)... | Use of explicit c-style cast | test.cpp:86:27:86:34 | (int)... | |

cpp/autosar/test/rules/A5-2-2/test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,25 @@ class A5_2_2 final {
6565
void a5_2_2_test() {
6666
A5_2_2 a;
6767
a.f("");
68+
}
69+
70+
#define ADD_ONE(x) ((int)x) + 1
71+
#define NESTED_ADD_ONE(x) ADD_ONE(x)
72+
#define NO_CAST_ADD_ONE(x) x + 1
73+
74+
#include "macro_c_style_casts.h"
75+
76+
void test_macro_cast() {
77+
ADD_ONE(1); // NON_COMPLIANT - expansion of user-defined macro creates
78+
// c-style cast
79+
NESTED_ADD_ONE(1); // NON_COMPLIANT - expansion of user-defined macro creates
80+
// c-style cast
81+
LIBRARY_ADD_TWO(1); // COMPLIANT - macro generating the cast is defined in a
82+
// library, and is not modifiable by the user
83+
LIBRARY_NESTED_ADD_TWO(1); // COMPLIANT - macro generating the cast is defined
84+
// in a library, and is not modifiable by the user
85+
NO_CAST_ADD_ONE((int)1.0); // NON_COMPLIANT - cast in argument to macro
86+
LIBRARY_NO_CAST_ADD_TWO((int)1.0); // NON_COMPLIANT - library macro with
87+
// c-style cast in argument, written by
88+
// user so should be reported
6889
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Macros used in test for A5-2-2
2+
#define LIBRARY_ADD_TWO(x) ((int)x) + 2
3+
#define LIBRARY_NESTED_ADD_TWO(x) LIBRARY_ADD_TWO(x)
4+
#define LIBRARY_NO_CAST_ADD_TWO(x) x + 1

cpp/options

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
semmle-extractor-options:--clang -std=c++14 -nostdinc++ -I../../../../common/test/includes/standard-library
1+
semmle-extractor-options:--clang -std=c++14 -nostdinc++ -I../../../../common/test/includes/standard-library -I../../../../common/test/includes/custom-library

0 commit comments

Comments
 (0)