Skip to content

Commit d3baeb9

Browse files
committed
Address FP by counting aggregate initialization
1 parent 1a7348b commit d3baeb9

File tree

2 files changed

+44
-15
lines changed

2 files changed

+44
-15
lines changed

cpp/autosar/src/rules/M0-1-4/SingleUsePODVariable.qll

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,29 @@ private string getConstExprValue(Variable v) {
1212

1313
/** Gets a "use" count according to rule M0-1-4. */
1414
int getUseCount(Variable v) {
15-
exists(int initializers |
16-
// We enforce that it's a POD type variable, so if it has an initializer it is explicit
17-
(if v.hasInitializer() then initializers = 1 else initializers = 0) and
18-
result =
19-
initializers +
20-
count(VariableAccess access | access = v.getAnAccess() and not access.isCompilerGenerated())
21-
+ count(UserProvidedConstructorFieldInit cfi | cfi.getTarget() = v) +
22-
// For constexpr variables used as template arguments, we don't see accesses (just the
23-
// appropriate literals). We therefore take a conservative approach and count the number of
24-
// template instantiations that use the given constant, and consider each one to be a use
25-
// of the variable
26-
count(ClassTemplateInstantiation cti |
27-
cti.getTemplateArgument(_).(Expr).getValue() = getConstExprValue(v)
28-
)
29-
)
15+
// We enforce that it's a POD type variable, so if it has an initializer it is explicit
16+
//v.getFile().getBaseName() = "test_member.cpp" and
17+
result =
18+
count(getAUserInitializedValue(v)) +
19+
count(VariableAccess access | access = v.getAnAccess() and not access.isCompilerGenerated()) +
20+
// For constexpr variables used as template arguments, we don't see accesses (just the
21+
// appropriate literals). We therefore take a conservative approach and count the number of
22+
// template instantiations that use the given constant, and consider each one to be a use
23+
// of the variable
24+
count(ClassTemplateInstantiation cti |
25+
cti.getTemplateArgument(_).(Expr).getValue() = getConstExprValue(v)
26+
)
27+
}
28+
29+
Expr getAUserInitializedValue(Variable v) {
30+
(
31+
result = v.getInitializer().getExpr()
32+
or
33+
exists(UserProvidedConstructorFieldInit cfi | cfi.getTarget() = v and result = cfi.getExpr())
34+
or
35+
exists(ClassAggregateLiteral l | not l.isCompilerGenerated() | result = l.getAFieldExpr(v))
36+
) and
37+
not result.isCompilerGenerated()
3038
}
3139

3240
/** Gets a single use of `v`, if `isSingleUseNonVolatilePODVariable` holds. */

cpp/autosar/test/rules/M0-1-4/test_member.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,25 @@ void test_e() { // Ensure that the template E is fully instantiated
7272
e2.getT();
7373
}
7474

75+
void test_fp_reported_in_388() {
76+
struct s1 {
77+
int m1; // COMPLIANT
78+
};
79+
80+
s1 l1 = {1}; // m1 is used here
81+
l1.m1;
82+
}
83+
84+
void test_array_initialized_members() {
85+
struct s1 {
86+
int m1; // COMPLIANT
87+
};
88+
89+
struct s1 l1[] = {
90+
{.m1 = 1},
91+
{.m1 = 2},
92+
};
93+
94+
l1[0].m1;
95+
}
7596
} // namespace test

0 commit comments

Comments
 (0)