@@ -18,6 +18,7 @@ import codingstandards.cpp.autosar
1818import codingstandards.cpp.TrivialType
1919import codingstandards.cpp.SideEffect
2020import semmle.code.cpp.controlflow.SSA
21+ import codingstandards.cpp.Expr
2122
2223predicate 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-
10938from Variable v
11039where
11140 not isExcluded ( v , ConstPackage:: variableMissingConstexprQuery ( ) ) and
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
0 commit comments