Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cc38abd

Browse files
committed
C++: Ignore constant static initializers
1 parent 02f0b89 commit cc38abd

3 files changed

Lines changed: 60 additions & 37 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,37 @@ private Element getRealParent(Expr expr) {
3131
*/
3232
predicate isIRConstant(Expr expr) { exists(expr.getValue()) }
3333

34+
/**
35+
* Holds if the expression in this initializer is evaluated at compile time.
36+
*/
37+
private predicate skipInitializer(Initializer init) {
38+
exists(LocalVariable local |
39+
init = local.getInitializer() and
40+
local.isStatic() and
41+
not runtimeExprInStaticInitializer(init.getExpr())
42+
)
43+
}
44+
45+
/**
46+
* Holds if `e` is an expression in a static initializer that must be evaluated
47+
* at run time. This predicate computes "is non-const" instead of "is const" in
48+
* order to avoid recursion through forall.
49+
*/
50+
private predicate runtimeExprInStaticInitializer(Expr e) {
51+
inStaticInitializer(e) and
52+
if e instanceof AggregateLiteral
53+
then runtimeExprInStaticInitializer(e.getAChild())
54+
else not e.getFullyConverted().isConstant()
55+
}
56+
57+
/** Holds if `e` is part of the initializer of a local static variable. */
58+
private predicate inStaticInitializer(Expr e) {
59+
exists(LocalVariable local |
60+
local.isStatic() and
61+
e.getParent+() = local.getInitializer()
62+
)
63+
}
64+
3465
// Pulled out to work around QL-796
3566
private predicate isOrphan(Expr expr) { not exists(getRealParent(expr)) }
3667

@@ -50,6 +81,13 @@ private predicate ignoreExprAndDescendants(Expr expr) {
5081
// constant value.
5182
isIRConstant(getRealParent(expr))
5283
or
84+
// Only translate the initializer of a static local if it uses run-time data.
85+
// Otherwise the initializer does not run in function scope.
86+
exists(Initializer init |
87+
skipInitializer(init) and
88+
expr = init.getExpr().getFullyConverted()
89+
)
90+
or
5391
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
5492
getRealParent(expr) instanceof AssumeExpr
5593
or

cpp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6297,43 +6297,24 @@ struct_init.cpp:
62976297

62986298
# 20| void declare_static_infos()
62996299
# 20| Block 0
6300-
# 20| v20_1(void) = EnterFunction :
6301-
# 20| mu20_2(unknown) = AliasedDefinition :
6302-
# 20| mu20_3(unknown) = InitializeNonLocal :
6303-
# 20| mu20_4(unknown) = UnmodeledDefinition :
6304-
# 21| r21_1(glval<Info[2]>) = VariableAddress[static_infos] :
6305-
# 21| mu21_2(Info[2]) = Uninitialized[static_infos] : &:r21_1
6306-
# 21| r21_3(int) = Constant[0] :
6307-
# 21| r21_4(glval<Info>) = PointerAdd[16] : r21_1, r21_3
6308-
# 22| r22_1(glval<char *>) = FieldAddress[name] : r21_4
6309-
# 22| r22_2(glval<char[2]>) = StringConstant["1"] :
6310-
# 22| r22_3(char *) = Convert : r22_2
6311-
# 22| mu22_4(char *) = Store : &:r22_1, r22_3
6312-
# 22| r22_5(glval<..(*)(..)>) = FieldAddress[handler] : r21_4
6313-
# 22| r22_6(..(*)(..)) = FunctionAddress[handler1] :
6314-
# 22| mu22_7(..(*)(..)) = Store : &:r22_5, r22_6
6315-
# 21| r21_5(int) = Constant[1] :
6316-
# 21| r21_6(glval<Info>) = PointerAdd[16] : r21_1, r21_5
6317-
# 23| r23_1(glval<char *>) = FieldAddress[name] : r21_6
6318-
# 23| r23_2(glval<char[2]>) = StringConstant["2"] :
6319-
# 23| r23_3(char *) = Convert : r23_2
6320-
# 23| mu23_4(char *) = Store : &:r23_1, r23_3
6321-
# 23| r23_5(glval<..(*)(..)>) = FieldAddress[handler] : r21_6
6322-
# 23| r23_6(glval<..()(..)>) = FunctionAddress[handler2] :
6323-
# 23| r23_7(..(*)(..)) = CopyValue : r23_6
6324-
# 23| mu23_8(..(*)(..)) = Store : &:r23_5, r23_7
6325-
# 25| r25_1(glval<unknown>) = FunctionAddress[let_info_escape] :
6326-
# 25| r25_2(glval<Info[2]>) = VariableAddress[static_infos] :
6327-
# 25| r25_3(Info *) = Convert : r25_2
6328-
# 25| v25_4(void) = Call : func:r25_1, 0:r25_3
6329-
# 25| mu25_5(unknown) = ^CallSideEffect : ~mu20_4
6330-
# 25| v25_6(void) = ^BufferReadSideEffect[0] : &:r25_3, ~mu20_4
6331-
# 25| mu25_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r25_3
6332-
# 26| v26_1(void) = NoOp :
6333-
# 20| v20_5(void) = ReturnVoid :
6334-
# 20| v20_6(void) = UnmodeledUse : mu*
6335-
# 20| v20_7(void) = AliasedUse : ~mu20_4
6336-
# 20| v20_8(void) = ExitFunction :
6300+
# 20| v20_1(void) = EnterFunction :
6301+
# 20| mu20_2(unknown) = AliasedDefinition :
6302+
# 20| mu20_3(unknown) = InitializeNonLocal :
6303+
# 20| mu20_4(unknown) = UnmodeledDefinition :
6304+
# 21| r21_1(glval<Info[2]>) = VariableAddress[static_infos] :
6305+
# 21| mu21_2(Info[2]) = Uninitialized[static_infos] : &:r21_1
6306+
# 25| r25_1(glval<unknown>) = FunctionAddress[let_info_escape] :
6307+
# 25| r25_2(glval<Info[2]>) = VariableAddress[static_infos] :
6308+
# 25| r25_3(Info *) = Convert : r25_2
6309+
# 25| v25_4(void) = Call : func:r25_1, 0:r25_3
6310+
# 25| mu25_5(unknown) = ^CallSideEffect : ~mu20_4
6311+
# 25| v25_6(void) = ^BufferReadSideEffect[0] : &:r25_3, ~mu20_4
6312+
# 25| mu25_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r25_3
6313+
# 26| v26_1(void) = NoOp :
6314+
# 20| v20_5(void) = ReturnVoid :
6315+
# 20| v20_6(void) = UnmodeledUse : mu*
6316+
# 20| v20_7(void) = AliasedUse : ~mu20_4
6317+
# 20| v20_8(void) = ExitFunction :
63376318

63386319
# 28| void declare_local_infos()
63396320
# 28| Block 0

cpp/ql/test/library-tests/rangeanalysis/signanalysis/SignAnalysis.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,12 @@
137137
| test.c:109:14:109:16 | Constant: 44 | positive strictlyPositive |
138138
| test.c:110:14:110:14 | Constant: 1 | positive strictlyPositive |
139139
| test.c:110:14:110:14 | Store: 1 | positive strictlyPositive |
140+
| test.c:118:20:118:20 | Uninitialized: definition of n | positive |
141+
| test.c:119:10:119:10 | Load: n | positive |
140142
| test.c:119:10:119:12 | Add: ... ++ | positive strictlyPositive |
141143
| test.c:119:10:119:12 | Constant: ... ++ | positive strictlyPositive |
144+
| test.c:119:10:119:12 | CopyValue: ... ++ | positive |
145+
| test.c:119:10:119:12 | Store: ... ++ | positive |
142146
| test.c:119:10:119:12 | Store: ... ++ | positive strictlyPositive |
143147
| test.c:124:11:124:15 | Load: Start | positive |
144148
| test.c:124:11:124:15 | Phi: Start | positive |

0 commit comments

Comments
 (0)