Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 24247d2

Browse filesBrowse files
committed
Refactor A7-1-2 to extract constant expression logic
1 parent 30aa044 commit 24247d2
Copy full SHA for 24247d2

File tree

Expand file treeCollapse file tree

2 files changed

+82
-73
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+82
-73
lines changed

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

Copy file name to clipboardExpand all lines: cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql
+2-73Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import codingstandards.cpp.autosar
1818
import codingstandards.cpp.TrivialType
1919
import codingstandards.cpp.SideEffect
2020
import semmle.code.cpp.controlflow.SSA
21+
import codingstandards.cpp.Expr
2122

2223
predicate isZeroInitializable(Variable v) {
2324
not exists(v.getInitializer().getExpr()) and
@@ -34,78 +35,6 @@ predicate isTypeZeroInitializable(Type t) {
3435
t.getUnderlyingType() instanceof ArrayType
3536
}
3637

37-
/**
38-
* An optimized set of expressions used to determine the flow through constexpr variables.
39-
*/
40-
class VariableAccessOrCallOrLiteral extends Expr {
41-
VariableAccessOrCallOrLiteral() {
42-
this instanceof VariableAccess or
43-
this instanceof Call or
44-
this instanceof Literal
45-
}
46-
}
47-
48-
/**
49-
* Holds if the value of source flows through compile time evaluated variables to target.
50-
*/
51-
predicate flowsThroughConstExprVariables(
52-
VariableAccessOrCallOrLiteral source, VariableAccessOrCallOrLiteral target
53-
) {
54-
(
55-
source = target
56-
or
57-
source != target and
58-
exists(SsaDefinition intermediateDef, StackVariable intermediate |
59-
intermediateDef.getAVariable().getFunction() = source.getEnclosingFunction() and
60-
intermediateDef.getAVariable().getFunction() = target.getEnclosingFunction() and
61-
intermediateDef.getAVariable() = intermediate and
62-
intermediate.isConstexpr()
63-
|
64-
DataFlow::localExprFlow(source, intermediateDef.getDefiningValue(intermediate)) and
65-
flowsThroughConstExprVariables(intermediateDef.getAUse(intermediate), target)
66-
)
67-
)
68-
}
69-
70-
/*
71-
* Returns true if the given call may be evaluated at compile time and is compile time evaluated because
72-
* all its arguments are compile time evaluated and its default values are compile time evaluated.
73-
*/
74-
75-
predicate isCompileTimeEvaluated(Call call) {
76-
// 1. The call may be evaluated at compile time, because it is constexpr, and
77-
call.getTarget().isConstexpr() and
78-
// 2. all its arguments are compile time evaluated, and
79-
forall(DataFlow::Node ultimateArgSource, DataFlow::Node argSource |
80-
argSource = DataFlow::exprNode(call.getAnArgument()) and
81-
DataFlow::localFlow(ultimateArgSource, argSource) and
82-
not DataFlow::localFlowStep(_, ultimateArgSource)
83-
|
84-
(
85-
ultimateArgSource.asExpr() instanceof Literal
86-
or
87-
any(Call c | isCompileTimeEvaluated(c)) = ultimateArgSource.asExpr()
88-
) and
89-
// If the ultimate argument source is not the same as the argument source, then it must flow through
90-
// constexpr variables.
91-
(
92-
ultimateArgSource != argSource
93-
implies
94-
flowsThroughConstExprVariables(ultimateArgSource.asExpr(), argSource.asExpr())
95-
)
96-
) and
97-
// 3. all the default values used are compile time evaluated.
98-
forall(Expr defaultValue, Parameter parameterUsingDefaultValue, int idx |
99-
parameterUsingDefaultValue = call.getTarget().getParameter(idx) and
100-
not exists(call.getArgument(idx)) and
101-
parameterUsingDefaultValue.getAnAssignedValue() = defaultValue
102-
|
103-
defaultValue instanceof Literal
104-
or
105-
any(Call c | isCompileTimeEvaluated(c)) = defaultValue
106-
)
107-
}
108-
10938
from Variable v
11039
where
11140
not isExcluded(v, ConstPackage::variableMissingConstexprQuery()) and
@@ -119,7 +48,7 @@ where
11948
(
12049
v.getInitializer().getExpr().isConstant()
12150
or
122-
any(Call call | isCompileTimeEvaluated(call)) = v.getInitializer().getExpr()
51+
any(Call call | isCompileTimeEvaluatedCall(call)) = v.getInitializer().getExpr()
12352
or
12453
isZeroInitializable(v)
12554
or

‎cpp/common/src/codingstandards/cpp/Expr.qll

Copy file name to clipboardExpand all lines: cpp/common/src/codingstandards/cpp/Expr.qll
+80Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,83 @@ module MisraExpr {
189189
CValue() { isCValue(this) }
190190
}
191191
}
192+
193+
/**
194+
* An optimized set of expressions used to determine the flow through constexpr variables.
195+
*/
196+
class VariableAccessOrCallOrLiteral extends Expr {
197+
VariableAccessOrCallOrLiteral() {
198+
this instanceof VariableAccess and this.(VariableAccess).getTarget().isConstexpr()
199+
or
200+
this instanceof Call
201+
or
202+
this instanceof Literal
203+
}
204+
}
205+
206+
/**
207+
* Holds if the value of source flows through compile time evaluated variables to target.
208+
*/
209+
predicate flowsThroughConstExprVariables(
210+
VariableAccessOrCallOrLiteral source, VariableAccessOrCallOrLiteral target
211+
) {
212+
(
213+
source = target
214+
or
215+
source != target and
216+
exists(SsaDefinition intermediateDef, StackVariable intermediate |
217+
intermediateDef.getAVariable().getFunction() = source.getEnclosingFunction() and
218+
intermediateDef.getAVariable().getFunction() = target.getEnclosingFunction() and
219+
intermediateDef.getAVariable() = intermediate and
220+
intermediate.isConstexpr()
221+
|
222+
DataFlow::localExprFlow(source, intermediateDef.getDefiningValue(intermediate)) and
223+
flowsThroughConstExprVariables(intermediateDef.getAUse(intermediate), target)
224+
)
225+
)
226+
}
227+
228+
predicate isCompileTimeEvaluatedExpression(Expr expression) {
229+
forall(DataFlow::Node ultimateSource, DataFlow::Node source |
230+
source = DataFlow::exprNode(expression) and
231+
DataFlow::localFlow(ultimateSource, source) and
232+
not DataFlow::localFlowStep(_, ultimateSource)
233+
|
234+
isDirectCompileTimeEvaluatedExpression(ultimateSource.asExpr()) and
235+
// If the ultimate source is not the same as the source, then it must flow through
236+
// constexpr variables.
237+
(
238+
ultimateSource != source
239+
implies
240+
flowsThroughConstExprVariables(ultimateSource.asExpr(), source.asExpr())
241+
)
242+
)
243+
}
244+
245+
predicate isDirectCompileTimeEvaluatedExpression(Expr expression) {
246+
expression instanceof Literal
247+
or
248+
any(Call c | isCompileTimeEvaluatedCall(c)) = expression
249+
}
250+
251+
/*
252+
* Returns true if the given call may be evaluated at compile time and is compile time evaluated because
253+
* all its arguments are compile time evaluated and its default values are compile time evaluated.
254+
*/
255+
256+
predicate isCompileTimeEvaluatedCall(Call call) {
257+
// 1. The call may be evaluated at compile time, because it is constexpr, and
258+
call.getTarget().isConstexpr() and
259+
// 2. all its arguments are compile time evaluated, and
260+
forall(Expr argSource | argSource = call.getAnArgument() |
261+
isCompileTimeEvaluatedExpression(argSource)
262+
) and
263+
// 3. all the default values used are compile time evaluated.
264+
forall(Expr defaultValue, Parameter parameterUsingDefaultValue, int idx |
265+
parameterUsingDefaultValue = call.getTarget().getParameter(idx) and
266+
not exists(call.getArgument(idx)) and
267+
parameterUsingDefaultValue.getAnAssignedValue() = defaultValue
268+
|
269+
isDirectCompileTimeEvaluatedExpression(defaultValue)
270+
)
271+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.