Skip to content

Commit 9b4593b

Browse files
committed
Address incorrect is compiled evaluated logic
Need to consider all possible values passed as arguments and default values.
1 parent 4bed9b6 commit 9b4593b

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,24 @@ predicate isTypeZeroInitializable(Type t) {
3333
t.getUnderlyingType() instanceof ArrayType
3434
}
3535

36+
/*
37+
* Returns true if the given call may be evaluated at compile time and is compile time evaluated because
38+
* all its arguments are compile time evaluated and its default values are compile time evaluated.
39+
*/
3640
predicate isCompileTimeEvaluated(Call call) {
41+
// 1. The call may be evaluated at compile time, because it is constexpr, and
3742
call.getTarget().isConstexpr() and
38-
forall(Expr arg | arg = call.getAnArgument() |
39-
DataFlow::localExprFlow(any(Literal l), arg)
43+
// 2. all its arguments are compile time evaluated, and
44+
forall(DataFlow::Node ultimateArgSource | DataFlow::localFlow(ultimateArgSource, DataFlow::exprNode(call.getAnArgument())) and not DataFlow::localFlowStep(_, ultimateArgSource) |
45+
ultimateArgSource.asExpr() instanceof Literal
4046
or
41-
DataFlow::localExprFlow(any(Call c | isCompileTimeEvaluated(call)), arg)
47+
any(Call c | isCompileTimeEvaluated(c)) = ultimateArgSource.asExpr()
48+
) and
49+
// 3. all the default values used are compile time evaluated.
50+
forall(Expr defaultValue, Parameter parameterUsingDefaultValue, int idx | parameterUsingDefaultValue = call.getTarget().getParameter(idx) and not exists(call.getArgument(idx)) and parameterUsingDefaultValue.getAnAssignedValue() = defaultValue |
51+
defaultValue instanceof Literal
52+
or
53+
any(Call c | isCompileTimeEvaluated(c)) = defaultValue
4254
)
4355
}
4456

cpp/autosar/test/rules/A7-1-2/VariableMissingConstexpr.expected

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,15 @@
1010
| test.cpp:55:7:55:8 | m2 | Variable m2 could be marked 'constexpr'. |
1111
| test.cpp:130:7:130:8 | m1 | Variable m1 could be marked 'constexpr'. |
1212
| test.cpp:141:7:141:8 | m1 | Variable m1 could be marked 'constexpr'. |
13-
| test.cpp:212:7:212:7 | x | Variable x could be marked 'constexpr'. |
13+
| test.cpp:217:7:217:7 | x | Variable x could be marked 'constexpr'. |
14+
| test.cpp:228:7:228:7 | v | Variable v could be marked 'constexpr'. |
15+
| test.cpp:229:7:229:7 | w | Variable w could be marked 'constexpr'. |
16+
| test.cpp:230:7:230:7 | a | Variable a could be marked 'constexpr'. |
17+
| test.cpp:231:7:231:7 | b | Variable b could be marked 'constexpr'. |
18+
| test.cpp:235:7:235:7 | f | Variable f could be marked 'constexpr'. |
19+
| test.cpp:236:7:236:7 | g | Variable g could be marked 'constexpr'. |
20+
| test.cpp:237:7:237:7 | h | Variable h could be marked 'constexpr'. |
21+
| test.cpp:238:7:238:7 | i | Variable i could be marked 'constexpr'. |
22+
| test.cpp:241:7:241:7 | l | Variable l could be marked 'constexpr'. |
23+
| test.cpp:244:7:244:7 | o | Variable o could be marked 'constexpr'. |
24+
| test.cpp:245:7:245:7 | q | Variable q could be marked 'constexpr'. |

cpp/autosar/test/rules/A7-1-2/test.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,42 @@ class ExcludedCases {
206206
void operator=(ExcludedCases &&) {} // COMPLIANT
207207
};
208208

209+
extern int random();
209210
constexpr int add(int x, int y) { return x + y; }
211+
constexpr int add1(int x, int y = 1) { return x + y; }
212+
constexpr int add2(int x, int y = add(add1(1), 2)) { return x + y; }
213+
constexpr int add3(int x, int y = random()) { return x + y; }
214+
constexpr int add4(int x = 1, int y = 2) { return x + y; }
210215

211216
constexpr void fp_reported_in_466(int p) {
212217
int x = add(1, 2); // NON_COMPLIANT
213218
int y = add(1, p); // COMPLIANT
219+
220+
int z = 0;
221+
if (p > 0) {
222+
z = 1;
223+
} else {
224+
z = p;
225+
}
226+
227+
int u = add(z, 2); // COMPLIANT
228+
int v = add(x, 2); // NON_COMPLIANT
229+
int w = add1(x, 2); // NON_COMPLIANT
230+
int a = add1(x); // NON_COMPLIANT
231+
int b = add1(1); // NON_COMPLIANT
232+
int c = add1(1, z); // COMPLIANT
233+
int d = add1(1, z); // COMPLIANT
234+
int e = add1(z); // COMPLIANT
235+
int f = add2(1); // NON_COMPLIANT
236+
int g = add2(1, 2); // NON_COMPLIANT
237+
int h = add2(x, 2); // NON_COMPLIANT
238+
int i = add2(x, 2); // NON_COMPLIANT
239+
int j = add2(z); // COMPLIANT
240+
int k = add2(z, 1); // COMPLIANT
241+
int l = add3(1, 1); // NON_COMPLIANT
242+
int m = add3(1); // COMPLIANT
243+
int n = add3(1, z); // COMPLIANT
244+
int o = add4(); // NON_COMPLIANT
245+
int q = add4(1); // NON_COMPLIANT
246+
int r = add4(1, z); // COMPLIANT
214247
}

0 commit comments

Comments
 (0)