Skip to content

Commit 29f66ff

Browse files
committed
C++: Use StackVariable, remove not v.isStatic()
In these files it was possible to remove calls to `isStatic` by switching from `LocalScopeVariable` to `StackVariable`. This changes semantics, hopefully for the better, to treat `thread_local` locals the same as `static` locals.
1 parent e57f98c commit 29f66ff

File tree

10 files changed

+33
-53
lines changed

10 files changed

+33
-53
lines changed

cpp/ql/src/Critical/ReturnStackAllocatedObject.ql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ class ReturnPointsToExpr extends PointsToExpr {
2020
ReturnStmt getReturnStmt() { result.getExpr().getFullyConverted() = this }
2121
}
2222

23-
from ReturnPointsToExpr ret, LocalVariable local, float confidence
23+
from ReturnPointsToExpr ret, StackVariable local, float confidence
2424
where
2525
ret.pointsTo() = local and
2626
ret.getReturnStmt().getEnclosingFunction() = local.getFunction() and
27-
not local.isStatic() and
2827
confidence = ret.confidence() and
2928
confidence > 0.01
3029
select ret,

cpp/ql/src/Critical/Unused.ql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@ class ScopeUtilityClass extends Class {
2020
Call getAUse() { result = this.getAConstructor().getACallToThisFunction() }
2121
}
2222

23-
from LocalScopeVariable v, ControlFlowNode def
23+
from StackVariable v, ControlFlowNode def
2424
where
2525
definition(v, def) and
2626
not definitionUsePair(v, def, _) and
27-
not v.isStatic() and
2827
not v.getAnAccess().isAddressOfAccess() and
2928
// parameter initializers are not in the call-graph at the moment
3029
not v.(Parameter).getInitializer().getExpr() = def and

cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ predicate hasNontrivialConversion(Expr e) {
4242
hasNontrivialConversion(e.getConversion())
4343
}
4444

45-
from LocalScopeVariable var, VariableAccess va, ReturnStmt r
45+
from StackVariable var, VariableAccess va, ReturnStmt r
4646
where
47-
not var.isStatic() and
48-
not var.isThreadLocal() and
4947
not var.getUnspecifiedType() instanceof ReferenceType and
5048
not r.isFromUninstantiatedTemplate(_) and
5149
va = var.getAnAccess() and

cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*/
1313

1414
import cpp
15-
import semmle.code.cpp.controlflow.LocalScopeVariableReachability
15+
import semmle.code.cpp.controlflow.StackVariableReachability
1616

1717
/**
1818
* Auxiliary predicate: Types that don't require initialization
@@ -40,23 +40,17 @@ DeclStmt declWithNoInit(LocalVariable v) {
4040
result.getADeclaration() = v and
4141
not exists(v.getInitializer()) and
4242
/* The type of the variable is not stack-allocated. */
43-
not allocatedType(v.getType()) and
44-
/* The variable is not static (otherwise it is zeroed). */
45-
not v.isStatic() and
46-
/* The variable is not extern (otherwise it is zeroed). */
47-
not v.hasSpecifier("extern")
43+
not allocatedType(v.getType())
4844
}
4945

50-
class UninitialisedLocalReachability extends LocalScopeVariableReachability {
46+
class UninitialisedLocalReachability extends StackVariableReachability {
5147
UninitialisedLocalReachability() { this = "UninitialisedLocal" }
5248

53-
override predicate isSource(ControlFlowNode node, LocalScopeVariable v) {
54-
node = declWithNoInit(v)
55-
}
49+
override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) }
5650

57-
override predicate isSink(ControlFlowNode node, LocalScopeVariable v) { useOfVarActual(v, node) }
51+
override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVarActual(v, node) }
5852

59-
override predicate isBarrier(ControlFlowNode node, LocalScopeVariable v) {
53+
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
6054
// only report the _first_ possibly uninitialized use
6155
useOfVarActual(v, node) or
6256
definitionBarrier(v, node)

cpp/ql/src/jsf/4.13 Functions/AV Rule 111.ql

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,9 @@ class ReturnPointsToExpr extends PointsToExpr {
2020
ReturnStmt getReturnStmt() { result.getExpr() = this }
2121
}
2222

23-
from ReturnPointsToExpr ret, LocalVariable dest
23+
from ReturnPointsToExpr ret, StackVariable dest
2424
where
2525
ret.pointsTo() = dest and
26-
ret.getReturnStmt().getParentStmt().getEnclosingFunction() = dest.getFunction() and
27-
not dest.isStatic()
26+
ret.getReturnStmt().getParentStmt().getEnclosingFunction() = dest.getFunction()
2827
select ret.getReturnStmt(),
2928
"AV Rule 111: A function shall not return a pointer or reference to a non-static local object."

cpp/ql/src/semmle/code/cpp/dataflow/StackAddress.qll

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ predicate stackPointerFlowsToUse(Expr use, Type useType, Expr source, boolean is
6161
stackPointerFlowsToUse(use.(PointerAddExpr).getAnOperand(), useType, source, isLocal)
6262
or
6363
// Indirect use of a stack address.
64-
exists(SsaDefinition def, LocalScopeVariable var |
64+
exists(SsaDefinition def, StackVariable var |
6565
stackPointerFlowsToDef(def, var, useType, source, isLocal) and
6666
use = def.getAUse(var)
6767
)
@@ -97,8 +97,7 @@ private PointerType getExprPtrType(Expr use) { result = use.getUnspecifiedType()
9797

9898
predicate stackReferenceFlowsToUse(Expr use, Type useType, Expr source, boolean isLocal) {
9999
// Stack variables
100-
exists(LocalScopeVariable var |
101-
not var.isStatic() and
100+
exists(StackVariable var |
102101
use = source and
103102
source = var.getAnAccess() and
104103
isLocal = true and
@@ -140,7 +139,7 @@ predicate stackReferenceFlowsToUse(Expr use, Type useType, Expr source, boolean
140139
stackPointerFlowsToUse(use.(PointerDereferenceExpr).getOperand(), useType, source, isLocal)
141140
or
142141
// Indirect use of a stack reference, via a reference variable.
143-
exists(SsaDefinition def, LocalScopeVariable var |
142+
exists(SsaDefinition def, StackVariable var |
144143
stackReferenceFlowsToDef(def, var, useType, source, isLocal) and
145144
use = def.getAUse(var)
146145
)
@@ -162,7 +161,7 @@ predicate stackReferenceFlowsToUse(Expr use, Type useType, Expr source, boolean
162161
* addresses through SSA definitions.
163162
*/
164163
predicate stackPointerFlowsToDef(
165-
SsaDefinition def, LocalScopeVariable var, Type useType, Expr source, boolean isLocal
164+
SsaDefinition def, StackVariable var, Type useType, Expr source, boolean isLocal
166165
) {
167166
stackPointerFlowsToUse(def.getDefiningValue(var), useType, source, isLocal)
168167
or
@@ -184,7 +183,7 @@ predicate stackPointerFlowsToDef(
184183
* int&, rather than pointers.
185184
*/
186185
predicate stackReferenceFlowsToDef(
187-
SsaDefinition def, LocalScopeVariable var, Type useType, Expr source, boolean isLocal
186+
SsaDefinition def, StackVariable var, Type useType, Expr source, boolean isLocal
188187
) {
189188
// Check that the type of the variable is a reference type and delegate
190189
// the rest of the work to stackReferenceFlowsToDef_Impl.
@@ -197,7 +196,7 @@ predicate stackReferenceFlowsToDef(
197196
* predicate.
198197
*/
199198
predicate stackReferenceFlowsToDef_Impl(
200-
SsaDefinition def, LocalScopeVariable var, Type useType, Expr source, boolean isLocal
199+
SsaDefinition def, StackVariable var, Type useType, Expr source, boolean isLocal
201200
) {
202201
stackReferenceFlowsToUse(def.getDefiningValue(var), useType, source, isLocal)
203202
or
@@ -213,7 +212,7 @@ predicate stackReferenceFlowsToDef_Impl(
213212
}
214213

215214
/** The type of the variable is a reference type, such as int&. */
216-
predicate isReferenceVariable(LocalScopeVariable var) {
215+
predicate isReferenceVariable(StackVariable var) {
217216
var.getUnspecifiedType() instanceof ReferenceType
218217
}
219218

@@ -284,7 +283,7 @@ predicate memberFcnMightRunOnStack(MemberFunction fcn, Type useType) {
284283
predicate constructorMightRunOnStack(Constructor constructor) {
285284
exists(ConstructorCall call | call.getTarget() = constructor |
286285
// Call to a constructor from a stack variable's initializer.
287-
exists(LocalScopeVariable var | var.getInitializer().getExpr() = call)
286+
exists(StackVariable var | var.getInitializer().getExpr() = call)
288287
or
289288
// Call to a constructor from another constructor which might
290289
// also run on the stack.

cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class FlowVar extends TFlowVar {
8888
* `FlowVar` instance for the uninitialized value of that variable.
8989
*/
9090
cached
91-
abstract predicate definedByInitialValue(LocalScopeVariable v);
91+
abstract predicate definedByInitialValue(StackVariable v);
9292

9393
/** Gets a textual representation of this element. */
9494
cached
@@ -269,7 +269,7 @@ module FlowVar_internal {
269269
* Holds if `sbb` is the `SubBasicBlock` where `v` receives its initial value.
270270
* See the documentation for `FlowVar.definedByInitialValue`.
271271
*/
272-
predicate blockVarDefinedByVariable(SubBasicBlock sbb, LocalScopeVariable v) {
272+
predicate blockVarDefinedByVariable(SubBasicBlock sbb, StackVariable v) {
273273
sbb = v.(Parameter).getFunction().getEntryPoint()
274274
or
275275
exists(DeclStmt declStmt |
@@ -280,7 +280,7 @@ module FlowVar_internal {
280280
}
281281

282282
newtype TFlowVar =
283-
TSsaVar(SsaDefinition def, LocalScopeVariable v) {
283+
TSsaVar(SsaDefinition def, StackVariable v) {
284284
fullySupportedSsaVariable(v) and
285285
v = def.getAVariable()
286286
} or
@@ -304,7 +304,7 @@ module FlowVar_internal {
304304
*/
305305
class SsaVar extends TSsaVar, FlowVar {
306306
SsaDefinition def;
307-
LocalScopeVariable v;
307+
StackVariable v;
308308

309309
SsaVar() { this = TSsaVar(def, v) }
310310

@@ -344,7 +344,7 @@ module FlowVar_internal {
344344

345345
override predicate definedPartiallyAt(Expr e) { none() }
346346

347-
override predicate definedByInitialValue(LocalScopeVariable param) {
347+
override predicate definedByInitialValue(StackVariable param) {
348348
def.definedByParameter(param) and
349349
param = v
350350
}
@@ -408,7 +408,7 @@ module FlowVar_internal {
408408
getAReachedBlockVarSBB(this).getANode() = p.getFunction()
409409
}
410410

411-
override predicate definedByInitialValue(LocalScopeVariable lsv) {
411+
override predicate definedByInitialValue(StackVariable lsv) {
412412
blockVarDefinedByVariable(sbb, lsv) and
413413
lsv = v
414414
}
@@ -648,11 +648,8 @@ module FlowVar_internal {
648648
/**
649649
* A local variable that is uninitialized immediately after its declaration.
650650
*/
651-
class UninitializedLocalVariable extends LocalVariable {
652-
UninitializedLocalVariable() {
653-
not this.hasInitializer() and
654-
not this.isStatic()
655-
}
651+
class UninitializedLocalVariable extends LocalVariable, StackVariable {
652+
UninitializedLocalVariable() { not this.hasInitializer() }
656653
}
657654

658655
/** Holds if `va` may be an uninitialized access to `v`. */

cpp/ql/src/semmle/code/cpp/exprs/ArithmeticOperation.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,10 @@ abstract class CrementOperation extends UnaryArithmeticOperation {
6262
override predicate mayBeImpure() { any() }
6363

6464
override predicate mayBeGloballyImpure() {
65-
not exists(VariableAccess va, LocalScopeVariable v |
65+
not exists(VariableAccess va, StackVariable v |
6666
va = this.getOperand() and
6767
v = va.getTarget() and
68-
not va.getConversion+() instanceof ReferenceDereferenceExpr and
69-
not v.isStatic()
68+
not va.getConversion+() instanceof ReferenceDereferenceExpr
7069
)
7170
}
7271
}

cpp/ql/src/semmle/code/cpp/exprs/Assignment.qll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ abstract class Assignment extends Operation {
2121
override predicate mayBeGloballyImpure() {
2222
this.getRValue().mayBeGloballyImpure()
2323
or
24-
not exists(VariableAccess va, LocalScopeVariable v |
24+
not exists(VariableAccess va, StackVariable v |
2525
va = this.getLValue() and
2626
v = va.getTarget() and
27-
not va.getConversion+() instanceof ReferenceDereferenceExpr and
28-
not v.isStatic()
27+
not va.getConversion+() instanceof ReferenceDereferenceExpr
2928
)
3029
}
3130
}

cpp/ql/src/semmle/code/cpp/ir/internal/IRCppLanguage.qll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class StringLiteral = Cpp::StringLiteral;
3232

3333
class Variable = Cpp::Variable;
3434

35-
class AutomaticVariable = Cpp::LocalScopeVariable;
35+
class AutomaticVariable = Cpp::StackVariable;
3636

3737
class StaticVariable = Cpp::Variable;
3838

@@ -66,10 +66,7 @@ int getTypeSize(Type type) { result = type.getSize() }
6666

6767
int getPointerSize() { exists(Cpp::NullPointerType nullptr | result = nullptr.getSize()) }
6868

69-
predicate isVariableAutomatic(Variable var) {
70-
var instanceof Cpp::LocalScopeVariable and
71-
not var.(Cpp::LocalScopeVariable).isStatic()
72-
}
69+
predicate isVariableAutomatic(Cpp::StackVariable var) { any() }
7370

7471
string getStringLiteralText(StringLiteral s) {
7572
result = s.getValueText().replaceAll("\n", " ").replaceAll("\r", "").replaceAll("\t", " ")

0 commit comments

Comments
 (0)