Compare commits

...

4 Commits

Author SHA1 Message Date
idrissrio
2f793f652e C/C++: reduce predicate scope 2026-02-05 12:36:09 +01:00
idrissrio
8cfa0a3a2d C/C++: Accept new test results 2026-02-04 10:14:29 +01:00
idrissrio
d771f1ef0e C/C++: Disable constant folding of address-vs-null comparisons 2026-02-04 10:14:25 +01:00
idrissrio
a40719b660 C/C++: Add test for const folding of global vars 2026-02-03 09:34:27 +01:00
4 changed files with 56 additions and 0 deletions

View File

@@ -62,12 +62,26 @@ private predicate ignoreConstantValue(Operation op) {
op instanceof BitwiseXorExpr
}
/**
* Holds if `expr` contains an address-of expression that EDG may have constant-folded.
* We don't recurse into `sizeof` or `alignof` since they don't evaluate their operands,
* so any address-of inside them doesn't affect actual execution.
*/
private predicate containsAddressOf(Expr expr) {
expr instanceof AddressOfExpr
or
not expr instanceof SizeofOperator and
not expr instanceof AlignofOperator and
containsAddressOf(expr.getAChild())
}
/**
* Holds if `expr` is a constant of a type that can be replaced directly with
* its value in the IR. This does not include address constants as we have no
* means to express those as QL values.
*/
predicate isIRConstant(Expr expr) {
not containsAddressOf(expr) and
exists(expr.getValue()) and
// We avoid constant folding certain operations since it's often useful to
// mark one of those as a source in dataflow, and if the operation is

View File

@@ -0,0 +1,22 @@
#define NULL ((void*)0)
int global_var;
void test_address_null_comparison(int param_var) {
int local_var;
if (&global_var == NULL) {} // $ VariableAddress=global_var
if (&global_var != NULL) {} // $ VariableAddress=global_var
if (&global_var) {} // $ VariableAddress=global_var
if (!&global_var) {} // $ VariableAddress=global_var
if (&local_var == NULL) {} // $ VariableAddress=local_var
if (&local_var != NULL) {} // $ VariableAddress=local_var
if (&local_var) {} // $ VariableAddress=local_var
if (!&local_var) {} // $ VariableAddress=local_var
if (&param_var == NULL) {} // $ VariableAddress=param_var
if (&param_var != NULL) {} // $ VariableAddress=param_var
if (&param_var) {} // $ VariableAddress=param_var
if (!&param_var) {} // $ VariableAddress=param_var
}

View File

@@ -0,0 +1,20 @@
import cpp
private import utils.test.InlineExpectationsTest
private import semmle.code.cpp.ir.IR
module VariableAddressTest implements TestSig {
string getARelevantTag() { result = "VariableAddress" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(VariableAddressInstruction vai |
not vai.getAst() instanceof DeclarationEntry and
not vai.getAst() instanceof Parameter and
tag = "VariableAddress" and
value = vai.getAstVariable().getName() and
element = vai.toString() and
location = vai.getLocation()
)
}
}
import MakeTest<VariableAddressTest>