Merge branch 'main' into redsun82/go

This commit is contained in:
Paolo Tranquilli
2024-04-30 11:00:27 +02:00
75 changed files with 902 additions and 1333 deletions

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* Deleted the deprecated `GlobalValueNumberingImpl.qll` implementation.

View File

@@ -1156,5 +1156,14 @@ private predicate add_eq(
)
}
private class IntegerOrPointerConstantInstruction extends ConstantInstruction {
IntegerOrPointerConstantInstruction() {
this instanceof IntegerConstantInstruction or
this instanceof PointerConstantInstruction
}
}
/** The int value of integer constant expression. */
private int int_value(Instruction i) { result = i.(IntegerConstantInstruction).getValue().toInt() }
private int int_value(Instruction i) {
result = i.(IntegerOrPointerConstantInstruction).getValue().toInt()
}

View File

@@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the type of the result produced by this instruction. If the instruction does not produce
* a result, its result type will be `IRVoidType`.
*/
cached
final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) }
/**
* Gets the type of the result produced by this instruction. If the
@@ -995,9 +994,8 @@ class ConstantInstruction extends ConstantValueInstruction {
*/
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
exists(IRType resultType | resultType = this.getResultIRType() |
resultType instanceof IRIntegerType or resultType instanceof IRBooleanType
)
}
}
@@ -1009,6 +1007,17 @@ class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
* An instruction whose result is a constant value of a pointer type.
*/
class PointerConstantInstruction extends ConstantInstruction {
PointerConstantInstruction() {
exists(IRType resultType | resultType = this.getResultIRType() |
resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType
)
}
}
/**
* An instruction whose result is the address of a string literal.
*/

View File

@@ -429,6 +429,11 @@ private module Cached {
instr = unreachedInstruction(_) and result = Language::getVoidType()
}
cached
IRType getInstructionResultIRType(Instruction instr) {
result = instr.getResultLanguageType().getIRType()
}
/**
* Holds if `opcode` is the opcode that specifies the operation performed by `instr`.
*

View File

@@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the type of the result produced by this instruction. If the instruction does not produce
* a result, its result type will be `IRVoidType`.
*/
cached
final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) }
/**
* Gets the type of the result produced by this instruction. If the
@@ -995,9 +994,8 @@ class ConstantInstruction extends ConstantValueInstruction {
*/
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
exists(IRType resultType | resultType = this.getResultIRType() |
resultType instanceof IRIntegerType or resultType instanceof IRBooleanType
)
}
}
@@ -1009,6 +1007,17 @@ class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
* An instruction whose result is a constant value of a pointer type.
*/
class PointerConstantInstruction extends ConstantInstruction {
PointerConstantInstruction() {
exists(IRType resultType | resultType = this.getResultIRType() |
resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType
)
}
}
/**
* An instruction whose result is the address of a string literal.
*/

View File

@@ -377,6 +377,10 @@ CppType getInstructionResultType(TStageInstruction instr) {
result = getVoidType()
}
IRType getInstructionResultIRType(Instruction instr) {
result = instr.getResultLanguageType().getIRType()
}
predicate getInstructionOpcode(Opcode opcode, TStageInstruction instr) {
getInstructionTranslatedElement(instr).hasInstruction(opcode, getInstructionTag(instr), _)
or

View File

@@ -538,6 +538,11 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy {
final override predicate producesExprResult() { any() }
private TranslatedCoreExpr getOperand() { result.getExpr() = expr }
override predicate handlesDestructorsExplicitly() {
// The destructor calls will already have been generated by the translation of `expr`.
any()
}
}
class TranslatedCommaExpr extends TranslatedNonConstantExpr {

View File

@@ -247,8 +247,7 @@ class Instruction extends Construction::TStageInstruction {
* Gets the type of the result produced by this instruction. If the instruction does not produce
* a result, its result type will be `IRVoidType`.
*/
cached
final IRType getResultIRType() { result = this.getResultLanguageType().getIRType() }
final IRType getResultIRType() { result = Construction::getInstructionResultIRType(this) }
/**
* Gets the type of the result produced by this instruction. If the
@@ -995,9 +994,8 @@ class ConstantInstruction extends ConstantValueInstruction {
*/
class IntegerConstantInstruction extends ConstantInstruction {
IntegerConstantInstruction() {
exists(IRType resultType |
resultType = this.getResultIRType() and
(resultType instanceof IRIntegerType or resultType instanceof IRBooleanType)
exists(IRType resultType | resultType = this.getResultIRType() |
resultType instanceof IRIntegerType or resultType instanceof IRBooleanType
)
}
}
@@ -1009,6 +1007,17 @@ class FloatConstantInstruction extends ConstantInstruction {
FloatConstantInstruction() { this.getResultIRType() instanceof IRFloatingPointType }
}
/**
* An instruction whose result is a constant value of a pointer type.
*/
class PointerConstantInstruction extends ConstantInstruction {
PointerConstantInstruction() {
exists(IRType resultType | resultType = this.getResultIRType() |
resultType instanceof IRAddressType or resultType instanceof IRFunctionAddressType
)
}
}
/**
* An instruction whose result is the address of a string literal.
*/

View File

@@ -429,6 +429,11 @@ private module Cached {
instr = unreachedInstruction(_) and result = Language::getVoidType()
}
cached
IRType getInstructionResultIRType(Instruction instr) {
result = instr.getResultLanguageType().getIRType()
}
/**
* Holds if `opcode` is the opcode that specifies the operation performed by `instr`.
*

View File

@@ -1,616 +0,0 @@
/**
* DEPRECATED: This library has been replaced with a newer version which
* provides better performance and precision. Use
* `semmle.code.cpp.valuenumbering.GlobalValueNumbering` instead.
*
* Provides an implementation of Global Value Numbering.
* See https://en.wikipedia.org/wiki/Global_value_numbering
*
* The predicate `globalValueNumber` converts an expression into a `GVN`,
* which is an abstract type representing the value of the expression. If
* two expressions have the same `GVN` then they compute the same value.
* For example:
*
* ```
* void f(int x, int y) {
* g(x+y, x+y);
* }
* ```
*
* In this example, both arguments in the call to `g` compute the same value,
* so both arguments have the same `GVN`. In other words, we can find
* this call with the following query:
*
* ```
* from FunctionCall call, GVN v
* where v = globalValueNumber(call.getArgument(0))
* and v = globalValueNumber(call.getArgument(1))
* select call
* ```
*
* The analysis is conservative, so two expressions might have different
* `GVN`s even though the actually always compute the same value. The most
* common reason for this is that the analysis cannot prove that there
* are no side-effects that might cause the computed value to change.
*/
/*
* Note to developers: the correctness of this module depends on the
* definitions of GVN, globalValueNumber, and analyzableExpr being kept in
* sync with each other. If you change this module then make sure that the
* change is symmetric across all three.
*/
import cpp
private import semmle.code.cpp.controlflow.SSA
/**
* Holds if the result is a control flow node that might change the
* value of any global variable. This is used in the implementation
* of `GVN_OtherVariable`, because we need to be quite conservative when
* we assign a value number to a global variable. For example:
*
* ```
* x = g+1;
* dosomething();
* y = g+1;
* ```
*
* It is not safe to assign the same value number to both instances
* of `g+1` in this example, because the call to `dosomething` might
* change the value of `g`.
*/
private ControlFlowNode nodeWithPossibleSideEffect() {
result instanceof Call
or
// If the lhs of an assignment is not analyzable by SSA, then
// we need to treat the assignment as having a possible side-effect.
result instanceof Assignment and not result instanceof SsaDefinition
or
result instanceof CrementOperation and not result instanceof SsaDefinition
or
exists(LocalVariable v |
result = v.getInitializer().getExpr() and not result instanceof SsaDefinition
)
or
result instanceof AsmStmt
}
/**
* Gets the entry node of the control flow graph of which `node` is a
* member.
*/
cached
private ControlFlowNode getControlFlowEntry(ControlFlowNode node) {
result = node.getControlFlowScope().getEntryPoint() and
result.getASuccessor*() = node
}
/**
* Holds if there is a control flow edge from `src` to `dst` or
* if `dst` is an expression with a possible side-effect. The idea
* is to treat side effects as entry points in the control flow
* graph so that we can use the dominator tree to find the most recent
* side-effect.
*/
private predicate sideEffectCfg(ControlFlowNode src, ControlFlowNode dst) {
src.getASuccessor() = dst
or
// Add an edge from the entry point to any node that might have a side
// effect.
dst = nodeWithPossibleSideEffect() and
src = getControlFlowEntry(dst)
}
/**
* Holds if `dominator` is the immediate dominator of `node` in
* the side-effect CFG.
*/
private predicate iDomEffect(ControlFlowNode dominator, ControlFlowNode node) =
idominance(functionEntry/1, sideEffectCfg/2)(_, dominator, node)
/**
* Gets the most recent side effect. To be more precise, `result` is a
* dominator of `node` and no side-effects can occur between `result` and
* `node`.
*
* `sideEffectCFG` has an edge from the function entry to every node with a
* side-effect. This means that every node with a side-effect has the
* function entry as its immediate dominator. So if node `x` dominates node
* `y` then there can be no side effects between `x` and `y` unless `x` is
* the function entry. So the optimal choice for `result` has the function
* entry as its immediate dominator.
*
* Example:
*
* ```
* 000: int f(int a, int b, int *p) {
* 001: int r = 0;
* 002: if (a) {
* 003: if (b) {
* 004: sideEffect1();
* 005: }
* 006: } else {
* 007: sideEffect2();
* 008: }
* 009: if (a) {
* 010: r++; // Not a side-effect, because r is an SSA variable.
* 011: }
* 012: if (b) {
* 013: r++; // Not a side-effect, because r is an SSA variable.
* 014: }
* 015: return *p;
* 016: }
* ```
*
* Suppose we want to find the most recent side-effect for the dereference
* of `p` on line 015. The `sideEffectCFG` has an edge from the function
* entry (line 000) to the side effects at lines 004 and 007. Therefore,
* the immediate dominator tree looks like this:
*
* 000 - 001 - 002 - 003
* - 004
* - 007
* - 009 - 010
* - 012 - 013
* - 015
*
* The immediate dominator path to line 015 is 000 - 009 - 012 - 015.
* Therefore, the most recent side effect for line 015 is line 009.
*/
cached
private ControlFlowNode mostRecentSideEffect(ControlFlowNode node) {
exists(ControlFlowNode entry |
functionEntry(entry) and
iDomEffect(entry, result) and
iDomEffect*(result, node)
)
}
/** Used to represent the "global value number" of an expression. */
cached
private newtype GvnBase =
GVN_IntConst(int val, Type t) { mk_IntConst(val, t, _) } or
GVN_FloatConst(float val, Type t) { mk_FloatConst(val, t, _) } or
// If the local variable does not have a defining value, then
// we use the SsaDefinition as its global value number.
GVN_UndefinedStackVariable(StackVariable x, SsaDefinition def) {
mk_UndefinedStackVariable(x, def, _)
} or
// Variables with no SSA information. As a crude (but safe)
// approximation, we use `mostRecentSideEffect` to compute a definition
// location for the variable. This ensures that two instances of the same
// global variable will only get the same value number if they are
// guaranteed to have the same value.
GVN_OtherVariable(Variable x, ControlFlowNode dominator) { mk_OtherVariable(x, dominator, _) } or
deprecated GVN_FieldAccess(GVN s, Field f) {
mk_DotFieldAccess(s, f, _) or
mk_PointerFieldAccess_with_deref(s, f, _) or
mk_ImplicitThisFieldAccess_with_deref(s, f, _)
} or
// Dereference a pointer. The value might have changed since the last
// time the pointer was dereferenced, so we need to include a definition
// location. As a crude (but safe) approximation, we use
// `mostRecentSideEffect` to compute a definition location.
deprecated GVN_Deref(GVN p, ControlFlowNode dominator) {
mk_Deref(p, dominator, _) or
mk_PointerFieldAccess(p, _, dominator, _) or
mk_ImplicitThisFieldAccess_with_qualifier(p, _, dominator, _)
} or
GVN_ThisExpr(Function fcn) {
mk_ThisExpr(fcn, _) or
mk_ImplicitThisFieldAccess(fcn, _, _, _)
} or
deprecated GVN_Conversion(Type t, GVN child) { mk_Conversion(t, child, _) } or
deprecated GVN_BinaryOp(GVN lhs, GVN rhs, string opname) { mk_BinaryOp(lhs, rhs, opname, _) } or
deprecated GVN_UnaryOp(GVN child, string opname) { mk_UnaryOp(child, opname, _) } or
deprecated GVN_ArrayAccess(GVN x, GVN i, ControlFlowNode dominator) {
mk_ArrayAccess(x, i, dominator, _)
} or
// Any expression that is not handled by the cases above is
// given a unique number based on the expression itself.
GVN_Unanalyzable(Expr e) { not analyzableExpr(e) }
/**
* A Global Value Number. A GVN is an abstract representation of the value
* computed by an expression. The relationship between `Expr` and `GVN` is
* many-to-one: every `Expr` has exactly one `GVN`, but multiple
* expressions can have the same `GVN`. If two expressions have the same
* `GVN`, it means that they compute the same value at run time. The `GVN`
* is an opaque value, so you cannot deduce what the run-time value of an
* expression will be from its `GVN`. The only use for the `GVN` of an
* expression is to find other expressions that compute the same value.
* Use the predicate `globalValueNumber` to get the `GVN` for an `Expr`.
*
* Note: `GVN` has `toString` and `getLocation` methods, so that it can be
* displayed in a results list. These work by picking an arbitrary
* expression with this `GVN` and using its `toString` and `getLocation`
* methods.
*/
deprecated class GVN extends GvnBase {
GVN() { this instanceof GvnBase }
/** Gets an expression that has this GVN. */
Expr getAnExpr() { this = globalValueNumber(result) }
/** Gets the kind of the GVN. This can be useful for debugging. */
string getKind() {
if this instanceof GVN_IntConst
then result = "IntConst"
else
if this instanceof GVN_FloatConst
then result = "FloatConst"
else
if this instanceof GVN_UndefinedStackVariable
then result = "UndefinedStackVariable"
else
if this instanceof GVN_OtherVariable
then result = "OtherVariable"
else
if this instanceof GVN_FieldAccess
then result = "FieldAccess"
else
if this instanceof GVN_Deref
then result = "Deref"
else
if this instanceof GVN_ThisExpr
then result = "ThisExpr"
else
if this instanceof GVN_Conversion
then result = "Conversion"
else
if this instanceof GVN_BinaryOp
then result = "BinaryOp"
else
if this instanceof GVN_UnaryOp
then result = "UnaryOp"
else
if this instanceof GVN_ArrayAccess
then result = "ArrayAccess"
else
if this instanceof GVN_Unanalyzable
then result = "Unanalyzable"
else result = "error"
}
/**
* Gets an example of an expression with this GVN.
* This is useful for things like implementing toString().
*/
private Expr exampleExpr() {
// Pick the expression with the minimum source location string. This is
// just an arbitrary way to pick an expression with this `GVN`.
result = min(Expr e | this = globalValueNumber(e) | e order by e.getLocation().toString())
}
/** Gets a textual representation of this element. */
string toString() { result = this.exampleExpr().toString() }
/** Gets the primary location of this element. */
Location getLocation() { result = this.exampleExpr().getLocation() }
}
private predicate analyzableIntConst(Expr e) {
strictcount(e.getValue().toInt()) = 1 and
strictcount(e.getUnspecifiedType()) = 1
}
private predicate mk_IntConst(int val, Type t, Expr e) {
analyzableIntConst(e) and
val = e.getValue().toInt() and
t = e.getUnspecifiedType()
}
private predicate analyzableFloatConst(Expr e) {
strictcount(e.getValue().toFloat()) = 1 and
strictcount(e.getUnspecifiedType()) = 1 and
not analyzableIntConst(e)
}
private predicate mk_FloatConst(float val, Type t, Expr e) {
analyzableFloatConst(e) and
val = e.getValue().toFloat() and
t = e.getUnspecifiedType()
}
private predicate analyzableStackVariable(VariableAccess access) {
strictcount(SsaDefinition def | def.getAUse(_) = access | def) = 1 and
strictcount(SsaDefinition def, Variable v | def.getAUse(v) = access | v) = 1 and
count(SsaDefinition def, Variable v |
def.getAUse(v) = access
|
def.getDefiningValue(v).getFullyConverted()
) <= 1 and
not analyzableConst(access)
}
// Note: this predicate only has a result if the access has no
// defining value. If there is a defining value, then there is no
// need to generate a fresh `GVN` for the access because `globalValueNumber`
// will follow the chain and use the GVN of the defining value.
private predicate mk_UndefinedStackVariable(
StackVariable x, SsaDefinition def, VariableAccess access
) {
analyzableStackVariable(access) and
access = def.getAUse(x) and
not exists(def.getDefiningValue(x))
}
private predicate analyzableDotFieldAccess(DotFieldAccess access) {
strictcount(access.getTarget()) = 1 and
strictcount(access.getQualifier().getFullyConverted()) = 1 and
not analyzableConst(access)
}
deprecated private predicate mk_DotFieldAccess(GVN qualifier, Field target, DotFieldAccess access) {
analyzableDotFieldAccess(access) and
target = access.getTarget() and
qualifier = globalValueNumber(access.getQualifier().getFullyConverted())
}
private predicate analyzablePointerFieldAccess(PointerFieldAccess access) {
strictcount(mostRecentSideEffect(access)) = 1 and
strictcount(access.getTarget()) = 1 and
strictcount(access.getQualifier().getFullyConverted()) = 1 and
not analyzableConst(access)
}
deprecated private predicate mk_PointerFieldAccess(
GVN qualifier, Field target, ControlFlowNode dominator, PointerFieldAccess access
) {
analyzablePointerFieldAccess(access) and
dominator = mostRecentSideEffect(access) and
target = access.getTarget() and
qualifier = globalValueNumber(access.getQualifier().getFullyConverted())
}
/**
* `obj->field` is equivalent to `(*obj).field`, so we need to wrap an
* extra `GVN_Deref` around the qualifier.
*/
deprecated private predicate mk_PointerFieldAccess_with_deref(
GVN new_qualifier, Field target, PointerFieldAccess access
) {
exists(GVN qualifier, ControlFlowNode dominator |
mk_PointerFieldAccess(qualifier, target, dominator, access) and
new_qualifier = GVN_Deref(qualifier, dominator)
)
}
private predicate analyzableImplicitThisFieldAccess(ImplicitThisFieldAccess access) {
strictcount(mostRecentSideEffect(access)) = 1 and
strictcount(access.getTarget()) = 1 and
strictcount(access.getEnclosingFunction()) = 1 and
not analyzableConst(access)
}
private predicate mk_ImplicitThisFieldAccess(
Function fcn, Field target, ControlFlowNode dominator, ImplicitThisFieldAccess access
) {
analyzableImplicitThisFieldAccess(access) and
dominator = mostRecentSideEffect(access) and
target = access.getTarget() and
fcn = access.getEnclosingFunction()
}
deprecated private predicate mk_ImplicitThisFieldAccess_with_qualifier(
GVN qualifier, Field target, ControlFlowNode dominator, ImplicitThisFieldAccess access
) {
exists(Function fcn |
mk_ImplicitThisFieldAccess(fcn, target, dominator, access) and
qualifier = GVN_ThisExpr(fcn)
)
}
deprecated private predicate mk_ImplicitThisFieldAccess_with_deref(
GVN new_qualifier, Field target, ImplicitThisFieldAccess access
) {
exists(GVN qualifier, ControlFlowNode dominator |
mk_ImplicitThisFieldAccess_with_qualifier(qualifier, target, dominator, access) and
new_qualifier = GVN_Deref(qualifier, dominator)
)
}
/**
* Holds if `access` is an access of a variable that does
* not have SSA information. (For example, because the variable
* is global.)
*/
private predicate analyzableOtherVariable(VariableAccess access) {
not access instanceof FieldAccess and
not exists(SsaDefinition def | access = def.getAUse(_)) and
strictcount(access.getTarget()) = 1 and
strictcount(mostRecentSideEffect(access)) = 1 and
not analyzableConst(access)
}
private predicate mk_OtherVariable(Variable x, ControlFlowNode dominator, VariableAccess access) {
analyzableOtherVariable(access) and
x = access.getTarget() and
dominator = mostRecentSideEffect(access)
}
private predicate analyzableConversion(Conversion conv) {
strictcount(conv.getUnspecifiedType()) = 1 and
strictcount(conv.getExpr()) = 1 and
not analyzableConst(conv)
}
deprecated private predicate mk_Conversion(Type t, GVN child, Conversion conv) {
analyzableConversion(conv) and
t = conv.getUnspecifiedType() and
child = globalValueNumber(conv.getExpr())
}
private predicate analyzableBinaryOp(BinaryOperation op) {
op.isPure() and
strictcount(op.getLeftOperand().getFullyConverted()) = 1 and
strictcount(op.getRightOperand().getFullyConverted()) = 1 and
strictcount(op.getOperator()) = 1 and
not analyzableConst(op)
}
deprecated private predicate mk_BinaryOp(GVN lhs, GVN rhs, string opname, BinaryOperation op) {
analyzableBinaryOp(op) and
lhs = globalValueNumber(op.getLeftOperand().getFullyConverted()) and
rhs = globalValueNumber(op.getRightOperand().getFullyConverted()) and
opname = op.getOperator()
}
private predicate analyzableUnaryOp(UnaryOperation op) {
not op instanceof PointerDereferenceExpr and
op.isPure() and
strictcount(op.getOperand().getFullyConverted()) = 1 and
strictcount(op.getOperator()) = 1 and
not analyzableConst(op)
}
deprecated private predicate mk_UnaryOp(GVN child, string opname, UnaryOperation op) {
analyzableUnaryOp(op) and
child = globalValueNumber(op.getOperand().getFullyConverted()) and
opname = op.getOperator()
}
private predicate analyzableThisExpr(ThisExpr thisExpr) {
strictcount(thisExpr.getEnclosingFunction()) = 1 and
not analyzableConst(thisExpr)
}
private predicate mk_ThisExpr(Function fcn, ThisExpr thisExpr) {
analyzableThisExpr(thisExpr) and
fcn = thisExpr.getEnclosingFunction()
}
private predicate analyzableArrayAccess(ArrayExpr ae) {
strictcount(ae.getArrayBase().getFullyConverted()) = 1 and
strictcount(ae.getArrayOffset().getFullyConverted()) = 1 and
strictcount(mostRecentSideEffect(ae)) = 1 and
not analyzableConst(ae)
}
deprecated private predicate mk_ArrayAccess(
GVN base, GVN offset, ControlFlowNode dominator, ArrayExpr ae
) {
analyzableArrayAccess(ae) and
base = globalValueNumber(ae.getArrayBase().getFullyConverted()) and
offset = globalValueNumber(ae.getArrayOffset().getFullyConverted()) and
dominator = mostRecentSideEffect(ae)
}
private predicate analyzablePointerDereferenceExpr(PointerDereferenceExpr deref) {
strictcount(deref.getOperand().getFullyConverted()) = 1 and
strictcount(mostRecentSideEffect(deref)) = 1 and
not analyzableConst(deref)
}
deprecated private predicate mk_Deref(GVN p, ControlFlowNode dominator, PointerDereferenceExpr deref) {
analyzablePointerDereferenceExpr(deref) and
p = globalValueNumber(deref.getOperand().getFullyConverted()) and
dominator = mostRecentSideEffect(deref)
}
/** Gets the global value number of expression `e`. */
cached
deprecated GVN globalValueNumber(Expr e) {
exists(int val, Type t |
mk_IntConst(val, t, e) and
result = GVN_IntConst(val, t)
)
or
exists(float val, Type t |
mk_FloatConst(val, t, e) and
result = GVN_FloatConst(val, t)
)
or
// Local variable with a defining value.
exists(StackVariable x, SsaDefinition def |
analyzableStackVariable(e) and
e = def.getAUse(x) and
result = globalValueNumber(def.getDefiningValue(x).getFullyConverted())
)
or
// Local variable without a defining value.
exists(StackVariable x, SsaDefinition def |
mk_UndefinedStackVariable(x, def, e) and
result = GVN_UndefinedStackVariable(x, def)
)
or
// Variable with no SSA information.
exists(Variable x, ControlFlowNode dominator |
mk_OtherVariable(x, dominator, e) and
result = GVN_OtherVariable(x, dominator)
)
or
exists(GVN qualifier, Field target |
mk_DotFieldAccess(qualifier, target, e) and
result = GVN_FieldAccess(qualifier, target)
)
or
exists(GVN qualifier, Field target |
mk_PointerFieldAccess_with_deref(qualifier, target, e) and
result = GVN_FieldAccess(qualifier, target)
)
or
exists(GVN qualifier, Field target |
mk_ImplicitThisFieldAccess_with_deref(qualifier, target, e) and
result = GVN_FieldAccess(qualifier, target)
)
or
exists(Function fcn |
mk_ThisExpr(fcn, e) and
result = GVN_ThisExpr(fcn)
)
or
exists(Type t, GVN child |
mk_Conversion(t, child, e) and
result = GVN_Conversion(t, child)
)
or
exists(GVN lhs, GVN rhs, string opname |
mk_BinaryOp(lhs, rhs, opname, e) and
result = GVN_BinaryOp(lhs, rhs, opname)
)
or
exists(GVN child, string opname |
mk_UnaryOp(child, opname, e) and
result = GVN_UnaryOp(child, opname)
)
or
exists(GVN x, GVN i, ControlFlowNode dominator |
mk_ArrayAccess(x, i, dominator, e) and
result = GVN_ArrayAccess(x, i, dominator)
)
or
exists(GVN p, ControlFlowNode dominator |
mk_Deref(p, dominator, e) and
result = GVN_Deref(p, dominator)
)
or
not analyzableExpr(e) and result = GVN_Unanalyzable(e)
}
private predicate analyzableConst(Expr e) {
analyzableIntConst(e) or
analyzableFloatConst(e)
}
/**
* Holds if the expression is explicitly handled by `globalValueNumber`.
* Unanalyzable expressions still need to be given a global value number,
* but it will be a unique number that is not shared with any other
* expression.
*/
private predicate analyzableExpr(Expr e) {
analyzableConst(e) or
analyzableStackVariable(e) or
analyzableDotFieldAccess(e) or
analyzablePointerFieldAccess(e) or
analyzableImplicitThisFieldAccess(e) or
analyzableOtherVariable(e) or
analyzableConversion(e) or
analyzableBinaryOp(e) or
analyzableUnaryOp(e) or
analyzableThisExpr(e) or
analyzableArrayAccess(e) or
analyzablePointerDereferenceExpr(e)
}

View File

@@ -56,6 +56,8 @@ astGuardsCompare
| 17 | y < 1+1 when ... > ... is false |
| 17 | y >= 1+1 when ... && ... is true |
| 17 | y >= 1+1 when ... > ... is true |
| 18 | call to get != 0 when call to get is true |
| 18 | call to get == 0 when call to get is false |
| 26 | 0 < x+0 when ... > ... is true |
| 26 | 0 >= x+0 when ... > ... is false |
| 26 | x < 0+1 when ... > ... is false |
@@ -487,6 +489,7 @@ astGuardsEnsure_const
| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 |
| test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | != | 0 | 175 | 175 |
| test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | 0 | 175 | 175 |
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
@@ -545,6 +548,8 @@ irGuardsCompare
| 17 | y < 2 when CompareGT: ... > ... is false |
| 17 | y >= 1+1 when CompareGT: ... > ... is true |
| 17 | y >= 2 when CompareGT: ... > ... is true |
| 18 | call to get != 0 when CompareNE: (bool)... is true |
| 18 | call to get == 0 when CompareNE: (bool)... is false |
| 26 | 0 < x+0 when CompareGT: ... > ... is true |
| 26 | 0 >= x+0 when CompareGT: ... > ... is false |
| 26 | x < 0+1 when CompareGT: ... > ... is false |
@@ -996,6 +1001,7 @@ irGuardsEnsure_const
| test.c:109:19:109:23 | CompareLT: ... < ... | test.c:109:19:109:19 | Load: y | >= | 0 | 113 | 113 |
| test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | != | 0 | 175 | 175 |
| test.c:175:13:175:32 | CompareEQ: ... == ... | test.c:175:13:175:15 | Call: call to foo | == | 0 | 175 | 175 |
| test.cpp:18:8:18:12 | CompareNE: (bool)... | test.cpp:18:8:18:10 | Call: call to get | != | 0 | 19 | 19 |
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | CompareEQ: ... == ... | test.cpp:31:7:31:7 | Load: x | == | -1 | 32 | 32 |

View File

@@ -32,3 +32,7 @@
| test.cpp:61:10:61:10 | i |
| test.cpp:74:10:74:10 | i |
| test.cpp:84:10:84:10 | i |
| test.cpp:93:6:93:6 | c |
| test.cpp:99:6:99:6 | f |
| test.cpp:105:6:105:14 | ... != ... |
| test.cpp:111:6:111:14 | ... != ... |

View File

@@ -22,6 +22,8 @@
| 17 | y >= 1+1 when ... > ... is true |
| 17 | y >= 2 when ... && ... is true |
| 17 | y >= 2 when ... > ... is true |
| 18 | call to get != 0 when call to get is true |
| 18 | call to get == 0 when call to get is false |
| 26 | 0 < x+0 when ... > ... is true |
| 26 | 0 >= x+0 when ... > ... is false |
| 26 | x < 0+1 when ... > ... is false |
@@ -107,6 +109,8 @@
| 85 | y != 0+0 when ... && ... is true |
| 85 | y == 0 when ... != ... is false |
| 85 | y == 0+0 when ... != ... is false |
| 93 | c != 0 when c is true |
| 93 | c == 0 when c is false |
| 94 | 0 != x+0 when ... != ... is true |
| 94 | 0 == x+0 when ... != ... is false |
| 94 | x != 0 when ... != ... is true |
@@ -119,6 +123,10 @@
| 102 | j < 10+0 when ... < ... is true |
| 102 | j >= 10 when ... < ... is false |
| 102 | j >= 10+0 when ... < ... is false |
| 105 | 0.0 != f+0 when ... != ... is true |
| 105 | 0.0 == f+0 when ... != ... is false |
| 105 | f != 0.0+0 when ... != ... is true |
| 105 | f == 0.0+0 when ... != ... is false |
| 109 | 0 != x+0 when ... == ... is false |
| 109 | 0 != x+0 when ... \|\| ... is false |
| 109 | 0 < y+1 when ... < ... is false |
@@ -137,3 +145,7 @@
| 109 | y >= 0 when ... \|\| ... is false |
| 109 | y >= 0+0 when ... < ... is false |
| 109 | y >= 0+0 when ... \|\| ... is false |
| 111 | 0.0 != i+0 when ... != ... is true |
| 111 | 0.0 == i+0 when ... != ... is false |
| 111 | i != 0.0+0 when ... != ... is true |
| 111 | i == 0.0+0 when ... != ... is false |

View File

@@ -90,3 +90,7 @@
| test.cpp:61:10:61:10 | i | Case[1] | 65 | 66 |
| test.cpp:74:10:74:10 | i | Case[0..10] | 75 | 77 |
| test.cpp:74:10:74:10 | i | Case[11..20] | 78 | 79 |
| test.cpp:93:6:93:6 | c | true | 93 | 94 |
| test.cpp:99:6:99:6 | f | true | 99 | 100 |
| test.cpp:105:6:105:14 | ... != ... | true | 105 | 106 |
| test.cpp:111:6:111:14 | ... != ... | true | 111 | 112 |

View File

@@ -1,3 +1,4 @@
binary
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | test.c:7:13:7:13 | 0 | 1 | 10 | 11 |
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | test.c:7:13:7:13 | 0 | 1 | 7 | 9 |
| test.c:7:9:7:13 | ... > ... | test.c:7:13:7:13 | 0 | < | test.c:7:9:7:9 | x | 0 | 7 | 9 |
@@ -154,3 +155,94 @@
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 |
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | 105 | 106 |
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | 105 | 106 |
| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:6:111:6 | i | != | test.cpp:111:11:111:14 | 0.0 | 0 | 111 | 112 |
| test.cpp:111:6:111:14 | ... != ... | test.cpp:111:11:111:14 | 0.0 | != | test.cpp:111:6:111:6 | i | 0 | 111 | 112 |
unary
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | < | 1 | 10 | 11 |
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:9 | x | >= | 1 | 7 | 9 |
| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 17 | 17 |
| test.c:17:8:17:12 | ... < ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 |
| test.c:17:8:17:21 | ... && ... | test.c:17:8:17:8 | x | < | 0 | 18 | 18 |
| test.c:17:8:17:21 | ... && ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 |
| test.c:17:17:17:21 | ... > ... | test.c:17:17:17:17 | y | >= | 2 | 18 | 18 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 2 | 2 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 31 | 34 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 34 | 34 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 39 | 42 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 42 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 42 | 44 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 45 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 45 | 47 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 51 | 53 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 56 | 58 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 58 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 58 | 66 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | < | 1 | 62 | 62 |
| test.c:26:11:26:15 | ... > ... | test.c:26:11:26:11 | x | >= | 1 | 26 | 28 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | < | 10 | 34 | 34 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 2 | 2 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 39 | 42 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 42 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 42 | 44 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 45 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 45 | 47 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 51 | 53 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 56 | 58 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 58 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 58 | 66 |
| test.c:34:16:34:21 | ... < ... | test.c:34:16:34:16 | j | >= | 10 | 62 | 62 |
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 42 |
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 42 | 44 |
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 45 |
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 45 | 47 |
| test.c:42:16:42:21 | ... < ... | test.c:42:16:42:16 | j | < | 10 | 51 | 53 |
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 42 | 42 |
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | < | 1 | 51 | 53 |
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 45 |
| test.c:44:12:44:16 | ... > ... | test.c:44:12:44:12 | z | >= | 1 | 45 | 47 |
| test.c:45:16:45:20 | ... > ... | test.c:45:16:45:16 | y | >= | 1 | 45 | 47 |
| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 58 | 58 |
| test.c:58:9:58:14 | ... == ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 |
| test.c:58:9:58:23 | ... \|\| ... | test.c:58:9:58:9 | x | != | 0 | 62 | 62 |
| test.c:58:9:58:23 | ... \|\| ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 |
| test.c:58:19:58:23 | ... < ... | test.c:58:19:58:19 | y | >= | 0 | 62 | 62 |
| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | != | 0 | 78 | 79 |
| test.c:75:9:75:14 | ... == ... | test.c:75:9:75:9 | x | == | 0 | 75 | 77 |
| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 85 | 85 |
| test.c:85:8:85:13 | ... == ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 |
| test.c:85:8:85:23 | ... && ... | test.c:85:8:85:8 | x | == | 0 | 86 | 86 |
| test.c:85:8:85:23 | ... && ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 |
| test.c:85:18:85:23 | ... != ... | test.c:85:18:85:18 | y | != | 0 | 86 | 86 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | != | 0 | 94 | 96 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 70 | 70 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 99 | 102 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 102 | 102 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 107 | 109 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 109 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 109 | 117 |
| test.c:94:11:94:16 | ... != ... | test.c:94:11:94:11 | x | == | 0 | 113 | 113 |
| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | < | 10 | 102 | 102 |
| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 70 | 70 |
| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 107 | 109 |
| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 109 |
| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 109 | 117 |
| test.c:102:16:102:21 | ... < ... | test.c:102:16:102:16 | j | >= | 10 | 113 | 113 |
| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 109 | 109 |
| test.c:109:9:109:14 | ... == ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 |
| test.c:109:9:109:23 | ... \|\| ... | test.c:109:9:109:9 | x | != | 0 | 113 | 113 |
| test.c:109:9:109:23 | ... \|\| ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 |
| test.c:109:19:109:23 | ... < ... | test.c:109:19:109:19 | y | >= | 0 | 113 | 113 |
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 |
| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 0 | 62 | 64 |
| test.cpp:61:10:61:10 | i | test.cpp:61:10:61:10 | i | == | 1 | 65 | 66 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 11 | 75 | 77 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | < | 21 | 78 | 79 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 0 | 75 | 77 |
| test.cpp:74:10:74:10 | i | test.cpp:74:10:74:10 | i | >= | 11 | 78 | 79 |
| test.cpp:93:6:93:6 | c | test.cpp:93:6:93:6 | c | != | 0 | 93 | 94 |

View File

@@ -7,8 +7,9 @@
import cpp
import semmle.code.cpp.controlflow.Guards
from GuardCondition guard, Expr left, Expr right, int k, int start, int end, string op
where
query predicate binary(
GuardCondition guard, Expr left, string op, Expr right, int k, int start, int end
) {
exists(BasicBlock block |
guard.ensuresLt(left, right, k, block, true) and op = "<"
or
@@ -20,4 +21,18 @@ where
|
block.hasLocationInfo(_, start, _, end, _)
)
select guard, left, op, right, k, start, end
}
query predicate unary(GuardCondition guard, Expr left, string op, int k, int start, int end) {
exists(BasicBlock block |
guard.ensuresLt(left, k, block, true) and op = "<"
or
guard.ensuresLt(left, k, block, false) and op = ">="
or
guard.ensuresEq(left, k, block, true) and op = "=="
or
guard.ensuresEq(left, k, block, false) and op = "!="
|
block.hasLocationInfo(_, start, _, end, _)
)
}

View File

@@ -86,3 +86,29 @@ void test_switches_default(int i) {
use1(i);
}
}
void use(...);
void pointer_comparison(char* c) {
if(c) {
use(c);
}
}
void implicit_float_comparison(float f) {
if(f) {
use(f);
}
}
void explicit_float_comparison(float f) {
if(f != 0.0f) {
use(f);
}
}
void int_float_comparison(int i) {
if(i != 0.0f) {
use(i);
}
}

View File

@@ -19565,12 +19565,6 @@ ir.cpp:
# 2216| Type = [PlainCharType] char
# 2216| Value = [CharLiteral] 97
# 2216| ValueCategory = prvalue
# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2215| Type = [VoidType] void
# 2215| ValueCategory = prvalue
# 2215| getQualifier(): [VariableAccess] y
# 2215| Type = [Class] ClassWithDestructor
# 2215| ValueCategory = lvalue
# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~vector
# 2215| Type = [VoidType] void
# 2215| ValueCategory = prvalue
@@ -19580,6 +19574,12 @@ ir.cpp:
# 2215| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2215| Type = [ClassTemplateInstantiation,Struct] iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>
# 2215| ValueCategory = lvalue
# 2215| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2215| Type = [VoidType] void
# 2215| ValueCategory = prvalue
# 2215| getQualifier(): [VariableAccess] y
# 2215| Type = [Class] ClassWithDestructor
# 2215| ValueCategory = lvalue
# 2218| getStmt(6): [RangeBasedForStmt] for(...:...) ...
# 2218| getInitialization(): [DeclStmt] declaration
# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys
@@ -19746,12 +19746,6 @@ ir.cpp:
# 2233| getQualifier(): [VariableAccess] x
# 2233| Type = [Class] ClassWithDestructor
# 2233| ValueCategory = lvalue
# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2218| Type = [VoidType] void
# 2218| ValueCategory = prvalue
# 2218| getQualifier(): [VariableAccess] y
# 2218| Type = [Class] ClassWithDestructor
# 2218| ValueCategory = lvalue
# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~vector
# 2218| Type = [VoidType] void
# 2218| ValueCategory = prvalue
@@ -19761,6 +19755,12 @@ ir.cpp:
# 2218| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2218| Type = [ClassTemplateInstantiation,Struct] iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>
# 2218| ValueCategory = lvalue
# 2218| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2218| Type = [VoidType] void
# 2218| ValueCategory = prvalue
# 2218| getQualifier(): [VariableAccess] y
# 2218| Type = [Class] ClassWithDestructor
# 2218| ValueCategory = lvalue
# 2224| getStmt(7): [RangeBasedForStmt] for(...:...) ...
# 2224| getInitialization(): [DeclStmt] declaration
# 2224| getDeclarationEntry(0): [VariableDeclarationEntry] definition of ys
@@ -20038,12 +20038,6 @@ ir.cpp:
# 2232| getQualifier(): [VariableAccess] z1
# 2232| Type = [Class] ClassWithDestructor
# 2232| ValueCategory = lvalue
# 2229| getImplicitDestructorCall(2): [DestructorCall] call to ~ClassWithDestructor
# 2229| Type = [VoidType] void
# 2229| ValueCategory = prvalue
# 2229| getQualifier(): [VariableAccess] y
# 2229| Type = [Class] ClassWithDestructor
# 2229| ValueCategory = lvalue
# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~vector
# 2229| Type = [VoidType] void
# 2229| ValueCategory = prvalue
@@ -20053,6 +20047,12 @@ ir.cpp:
# 2229| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2229| Type = [ClassTemplateInstantiation,Struct] iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>
# 2229| ValueCategory = lvalue
# 2229| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2229| Type = [VoidType] void
# 2229| ValueCategory = prvalue
# 2229| getQualifier(): [VariableAccess] y
# 2229| Type = [Class] ClassWithDestructor
# 2229| ValueCategory = lvalue
# 2233| getStmt(9): [ReturnStmt] return ...
# 2233| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2233| Type = [VoidType] void
@@ -20662,15 +20662,15 @@ ir.cpp:
# 2309| getQualifier(): [VariableAccess] s2
# 2309| Type = [Struct] String
# 2309| ValueCategory = lvalue
# 2307| getImplicitDestructorCall(1): [DestructorCall] call to ~String
# 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2307| Type = [ClassTemplateInstantiation,Struct] iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>
# 2307| ValueCategory = lvalue
# 2307| getImplicitDestructorCall(0): [DestructorCall] call to ~String
# 2307| Type = [VoidType] void
# 2307| ValueCategory = prvalue
# 2307| getQualifier(): [VariableAccess] s
# 2307| Type = [Struct] String
# 2307| ValueCategory = lvalue
# 2307| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2307| Type = [ClassTemplateInstantiation,Struct] iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>
# 2307| ValueCategory = lvalue
# 2311| getStmt(3): [ForStmt] for(...;...;...) ...
# 2311| getInitialization(): [DeclStmt] declaration
# 2311| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s

View File

@@ -15372,7 +15372,7 @@ ir.cpp:
#-----| True -> Block 2
# 2198| Block 1
# 2198| m2198_9(unknown) = Phi : from 13:~m2233_5, from 19:~m2233_13, from 23:~m2233_22
# 2198| m2198_9(unknown) = Phi : from 14:~m2233_5, from 19:~m2233_13, from 23:~m2233_22
# 2198| v2198_10(void) = ReturnVoid :
# 2198| v2198_11(void) = AliasedUse : ~m2198_9
# 2198| v2198_12(void) = ExitFunction :
@@ -15524,8 +15524,8 @@ ir.cpp:
#-----| Goto -> Block 8
# 2215| Block 8
# 2215| m2215_40(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Phi : from 7:m2215_32, from 9:m2215_72
# 2215| m2215_41(unknown) = Phi : from 7:~m2215_39, from 9:~m2215_63
# 2215| m2215_40(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Phi : from 7:m2215_32, from 9:m2215_64
# 2215| m2215_41(unknown) = Phi : from 7:~m2215_39, from 9:~m2215_69
# 2215| r2215_42(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_7(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2215_42
# 2215| r2215_43(glval<unknown>) = FunctionAddress[operator!=] :
@@ -15567,21 +15567,21 @@ ir.cpp:
# 2216| v2216_7(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, m2215_58
# 2216| m2216_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1
# 2216| m2216_9(ClassWithDestructor) = Chi : total:m2215_58, partial:m2216_8
# 2215| r2215_59(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2215| r2215_60(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2215| v2215_61(void) = Call[~ClassWithDestructor] : func:r2215_60, this:r2215_59
# 2215| m2215_62(unknown) = ^CallSideEffect : ~m2216_6
# 2215| m2215_63(unknown) = Chi : total:m2216_6, partial:m2215_62
# 2215| v2215_64(void) = ^IndirectReadSideEffect[-1] : &:r2215_59, m2216_9
# 2215| m2215_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_59
# 2215| m2215_66(ClassWithDestructor) = Chi : total:m2216_9, partial:m2215_65
# 2215| r2215_67(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2215| r2215_68(glval<unknown>) = FunctionAddress[operator++] :
# 2215| r2215_69(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2215_68, this:r2215_67
# 2215| v2215_70(void) = ^IndirectReadSideEffect[-1] : &:r2215_67, m2215_40
# 2215| m2215_71(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2215_67
# 2215| m2215_72(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Chi : total:m2215_40, partial:m2215_71
# 2215| r2215_73(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2215_69
# 2215| r2215_59(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2215| r2215_60(glval<unknown>) = FunctionAddress[operator++] :
# 2215| r2215_61(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2215_60, this:r2215_59
# 2215| v2215_62(void) = ^IndirectReadSideEffect[-1] : &:r2215_59, m2215_40
# 2215| m2215_63(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2215_59
# 2215| m2215_64(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Chi : total:m2215_40, partial:m2215_63
# 2215| r2215_65(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2215| r2215_66(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2215| v2215_67(void) = Call[~ClassWithDestructor] : func:r2215_66, this:r2215_65
# 2215| m2215_68(unknown) = ^CallSideEffect : ~m2216_6
# 2215| m2215_69(unknown) = Chi : total:m2216_6, partial:m2215_68
# 2215| v2215_70(void) = ^IndirectReadSideEffect[-1] : &:r2215_65, m2216_9
# 2215| m2215_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_65
# 2215| m2215_72(ClassWithDestructor) = Chi : total:m2216_9, partial:m2215_71
# 2215| r2215_73(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2215_61
#-----| Goto (back edge) -> Block 8
# 2218| Block 10
@@ -15633,8 +15633,8 @@ ir.cpp:
#-----| Goto -> Block 11
# 2218| Block 11
# 2218| m2218_40(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Phi : from 10:m2218_32, from 14:m2218_88
# 2218| m2218_41(unknown) = Phi : from 10:~m2218_39, from 14:~m2218_79
# 2218| m2218_40(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Phi : from 10:m2218_32, from 12:m2218_58
# 2218| m2218_41(unknown) = Phi : from 10:~m2218_39, from 12:~m2218_63
# 2218| r2218_42(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_24(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2218_42
# 2218| r2218_43(glval<unknown>) = FunctionAddress[operator!=] :
@@ -15656,26 +15656,44 @@ ir.cpp:
#-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_24, m2218_40
# 2218| v2218_52(void) = ConditionalBranch : r2218_51
#-----| False -> Block 15
#-----| True -> Block 12
#-----| True -> Block 13
# 2218| Block 12
# 2218| r2218_53(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_54(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_33(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2218_54
# 2218| r2218_55(glval<unknown>) = FunctionAddress[operator*] :
# 2218| r2218_56(ClassWithDestructor &) = Call[operator*] : func:r2218_55, this:r0_33
# 2218| r2218_53(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2218| r2218_54(glval<unknown>) = FunctionAddress[operator++] :
# 2218| r2218_55(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2218_54, this:r2218_53
# 2218| v2218_56(void) = ^IndirectReadSideEffect[-1] : &:r2218_53, m2218_40
# 2218| m2218_57(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_53
# 2218| m2218_58(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Chi : total:m2218_40, partial:m2218_57
# 2218| r2218_59(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_60(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_61(void) = Call[~ClassWithDestructor] : func:r2218_60, this:r2218_59
# 2218| m2218_62(unknown) = ^CallSideEffect : ~m2220_5
# 2218| m2218_63(unknown) = Chi : total:m2220_5, partial:m2218_62
# 2218| v2218_64(void) = ^IndirectReadSideEffect[-1] : &:r2218_59, m2220_8
# 2218| m2218_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_59
# 2218| m2218_66(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_65
# 2218| r2218_67(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2218_55
#-----| Goto (back edge) -> Block 11
# 2218| Block 13
# 2218| r2218_68(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_69(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_33(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2218_69
# 2218| r2218_70(glval<unknown>) = FunctionAddress[operator*] :
# 2218| r2218_71(ClassWithDestructor &) = Call[operator*] : func:r2218_70, this:r0_33
#-----| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_33, m2218_40
# 2218| r2218_57(ClassWithDestructor) = Load[?] : &:r2218_56, ~m2218_50
# 2218| m2218_58(ClassWithDestructor) = Store[y] : &:r2218_53, r2218_57
# 2218| r2218_72(ClassWithDestructor) = Load[?] : &:r2218_71, ~m2218_50
# 2218| m2218_73(ClassWithDestructor) = Store[y] : &:r2218_68, r2218_72
# 2219| r2219_1(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2219| r2219_2(glval<unknown>) = FunctionAddress[set_x] :
# 2219| r2219_3(char) = Constant[97] :
# 2219| v2219_4(void) = Call[set_x] : func:r2219_2, this:r2219_1, 0:r2219_3
# 2219| m2219_5(unknown) = ^CallSideEffect : ~m2218_50
# 2219| m2219_6(unknown) = Chi : total:m2218_50, partial:m2219_5
# 2219| v2219_7(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, m2218_58
# 2219| v2219_7(void) = ^IndirectReadSideEffect[-1] : &:r2219_1, m2218_73
# 2219| m2219_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2219_1
# 2219| m2219_9(ClassWithDestructor) = Chi : total:m2218_58, partial:m2219_8
# 2219| m2219_9(ClassWithDestructor) = Chi : total:m2218_73, partial:m2219_8
# 2220| r2220_1(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2220| r2220_2(glval<unknown>) = FunctionAddress[get_x] :
# 2220| r2220_3(char) = Call[get_x] : func:r2220_2, this:r2220_1
@@ -15688,55 +15706,37 @@ ir.cpp:
# 2220| r2220_10(int) = Constant[98] :
# 2220| r2220_11(bool) = CompareEQ : r2220_9, r2220_10
# 2220| v2220_12(void) = ConditionalBranch : r2220_11
#-----| False -> Block 14
#-----| True -> Block 13
#-----| False -> Block 12
#-----| True -> Block 14
# 2221| Block 13
# 2221| Block 14
# 2221| v2221_1(void) = NoOp :
# 2218| r2218_59(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_60(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_61(void) = Call[~ClassWithDestructor] : func:r2218_60, this:r2218_59
# 2218| m2218_62(unknown) = ^CallSideEffect : ~m2220_5
# 2218| m2218_63(unknown) = Chi : total:m2220_5, partial:m2218_62
# 2218| v2218_64(void) = ^IndirectReadSideEffect[-1] : &:r2218_59, m2220_8
# 2218| m2218_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_59
# 2218| m2218_66(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_65
# 2218| r2218_67(glval<vector<ClassWithDestructor>>) = VariableAddress[ys] :
# 2218| r2218_68(glval<unknown>) = FunctionAddress[~vector] :
# 2218| v2218_69(void) = Call[~vector] : func:r2218_68, this:r2218_67
# 2218| m2218_70(unknown) = ^CallSideEffect : ~m2218_63
# 2218| m2218_71(unknown) = Chi : total:m2218_63, partial:m2218_70
# 2218| v2218_72(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m2218_71
# 2218| m2218_73(vector<ClassWithDestructor>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67
# 2218| m2218_74(unknown) = Chi : total:m2218_71, partial:m2218_73
# 2218| r2218_74(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_75(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_76(void) = Call[~ClassWithDestructor] : func:r2218_75, this:r2218_74
# 2218| m2218_77(unknown) = ^CallSideEffect : ~m2220_5
# 2218| m2218_78(unknown) = Chi : total:m2220_5, partial:m2218_77
# 2218| v2218_79(void) = ^IndirectReadSideEffect[-1] : &:r2218_74, m2220_8
# 2218| m2218_80(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_74
# 2218| m2218_81(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_80
# 2218| r2218_82(glval<vector<ClassWithDestructor>>) = VariableAddress[ys] :
# 2218| r2218_83(glval<unknown>) = FunctionAddress[~vector] :
# 2218| v2218_84(void) = Call[~vector] : func:r2218_83, this:r2218_82
# 2218| m2218_85(unknown) = ^CallSideEffect : ~m2218_78
# 2218| m2218_86(unknown) = Chi : total:m2218_78, partial:m2218_85
# 2218| v2218_87(void) = ^IndirectReadSideEffect[-1] : &:r2218_82, ~m2218_86
# 2218| m2218_88(vector<ClassWithDestructor>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_82
# 2218| m2218_89(unknown) = Chi : total:m2218_86, partial:m2218_88
# 2233| r2233_1(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2233| r2233_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1
# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2218_74
# 2233| m2233_5(unknown) = Chi : total:m2218_74, partial:m2233_4
# 2233| m2233_4(unknown) = ^CallSideEffect : ~m2218_89
# 2233| m2233_5(unknown) = Chi : total:m2218_89, partial:m2233_4
# 2233| v2233_6(void) = ^IndirectReadSideEffect[-1] : &:r2233_1, m2214_8
# 2233| m2233_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1
# 2233| m2233_8(ClassWithDestructor) = Chi : total:m2214_8, partial:m2233_7
#-----| Goto -> Block 1
# 2218| Block 14
# 2218| r2218_75(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_76(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_77(void) = Call[~ClassWithDestructor] : func:r2218_76, this:r2218_75
# 2218| m2218_78(unknown) = ^CallSideEffect : ~m2220_5
# 2218| m2218_79(unknown) = Chi : total:m2220_5, partial:m2218_78
# 2218| v2218_80(void) = ^IndirectReadSideEffect[-1] : &:r2218_75, m2220_8
# 2218| m2218_81(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_75
# 2218| m2218_82(ClassWithDestructor) = Chi : total:m2220_8, partial:m2218_81
# 2218| r2218_83(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2218| r2218_84(glval<unknown>) = FunctionAddress[operator++] :
# 2218| r2218_85(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2218_84, this:r2218_83
# 2218| v2218_86(void) = ^IndirectReadSideEffect[-1] : &:r2218_83, m2218_40
# 2218| m2218_87(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_83
# 2218| m2218_88(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Chi : total:m2218_40, partial:m2218_87
# 2218| r2218_89(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2218_85
#-----| Goto (back edge) -> Block 11
# 2224| Block 15
# 2224| r2224_1(glval<vector<int>>) = VariableAddress[ys] :
# 2224| m2224_2(vector<int>) = Uninitialized[ys] : &:r2224_1
@@ -15895,8 +15895,8 @@ ir.cpp:
#-----| Goto -> Block 21
# 2229| Block 21
# 2229| m2229_40(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Phi : from 20:m2229_32, from 22:m2229_72
# 2229| m2229_41(unknown) = Phi : from 20:~m2229_39, from 22:~m2229_63
# 2229| m2229_40(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Phi : from 20:m2229_32, from 22:m2229_64
# 2229| m2229_41(unknown) = Phi : from 20:~m2229_39, from 22:~m2229_69
# 2229| r2229_42(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_58(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2229_42
# 2229| r2229_43(glval<unknown>) = FunctionAddress[operator!=] :
@@ -15961,21 +15961,21 @@ ir.cpp:
# 2232| v2232_14(void) = ^IndirectReadSideEffect[-1] : &:r2232_9, m2230_8
# 2232| m2232_15(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_9
# 2232| m2232_16(ClassWithDestructor) = Chi : total:m2230_8, partial:m2232_15
# 2229| r2229_59(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2229| r2229_60(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2229| v2229_61(void) = Call[~ClassWithDestructor] : func:r2229_60, this:r2229_59
# 2229| m2229_62(unknown) = ^CallSideEffect : ~m2232_13
# 2229| m2229_63(unknown) = Chi : total:m2232_13, partial:m2229_62
# 2229| v2229_64(void) = ^IndirectReadSideEffect[-1] : &:r2229_59, m2229_58
# 2229| m2229_65(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_59
# 2229| m2229_66(ClassWithDestructor) = Chi : total:m2229_58, partial:m2229_65
# 2229| r2229_67(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2229| r2229_68(glval<unknown>) = FunctionAddress[operator++] :
# 2229| r2229_69(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2229_68, this:r2229_67
# 2229| v2229_70(void) = ^IndirectReadSideEffect[-1] : &:r2229_67, m2229_40
# 2229| m2229_71(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2229_67
# 2229| m2229_72(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Chi : total:m2229_40, partial:m2229_71
# 2229| r2229_73(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2229_69
# 2229| r2229_59(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2229| r2229_60(glval<unknown>) = FunctionAddress[operator++] :
# 2229| r2229_61(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2229_60, this:r2229_59
# 2229| v2229_62(void) = ^IndirectReadSideEffect[-1] : &:r2229_59, m2229_40
# 2229| m2229_63(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2229_59
# 2229| m2229_64(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = Chi : total:m2229_40, partial:m2229_63
# 2229| r2229_65(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2229| r2229_66(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2229| v2229_67(void) = Call[~ClassWithDestructor] : func:r2229_66, this:r2229_65
# 2229| m2229_68(unknown) = ^CallSideEffect : ~m2232_13
# 2229| m2229_69(unknown) = Chi : total:m2232_13, partial:m2229_68
# 2229| v2229_70(void) = ^IndirectReadSideEffect[-1] : &:r2229_65, m2229_58
# 2229| m2229_71(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_65
# 2229| m2229_72(ClassWithDestructor) = Chi : total:m2229_58, partial:m2229_71
# 2229| r2229_73(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2229_61
#-----| Goto (back edge) -> Block 21
# 2233| Block 23
@@ -16684,8 +16684,8 @@ ir.cpp:
#-----| Goto -> Block 4
# 2307| Block 4
# 2307| m2307_47(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = Phi : from 3:m2307_39, from 5:m2307_89
# 2307| m2307_48(unknown) = Phi : from 3:~m2307_46, from 5:~m2307_83
# 2307| m2307_47(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = Phi : from 3:m2307_39, from 5:m2307_81
# 2307| m2307_48(unknown) = Phi : from 3:~m2307_46, from 5:~m2307_89
# 2307| r2307_49(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = VariableAddress[(__begin)] :
#-----| r0_7(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = Convert : r2307_49
# 2307| r2307_50(glval<unknown>) = FunctionAddress[operator!=] :
@@ -16745,21 +16745,21 @@ ir.cpp:
# 2309| v2309_6(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m2309_5
# 2309| m2309_7(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1
# 2309| m2309_8(unknown) = Chi : total:m2309_5, partial:m2309_7
# 2307| r2307_76(glval<String>) = VariableAddress[s] :
# 2307| r2307_77(glval<unknown>) = FunctionAddress[~String] :
# 2307| v2307_78(void) = Call[~String] : func:r2307_77, this:r2307_76
# 2307| m2307_79(unknown) = ^CallSideEffect : ~m2309_8
# 2307| m2307_80(unknown) = Chi : total:m2309_8, partial:m2307_79
# 2307| v2307_81(void) = ^IndirectReadSideEffect[-1] : &:r2307_76, ~m2307_80
# 2307| m2307_82(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_76
# 2307| m2307_83(unknown) = Chi : total:m2307_80, partial:m2307_82
# 2307| r2307_84(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = VariableAddress[(__begin)] :
# 2307| r2307_85(glval<unknown>) = FunctionAddress[operator++] :
# 2307| r2307_86(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &> &) = Call[operator++] : func:r2307_85, this:r2307_84
# 2307| v2307_87(void) = ^IndirectReadSideEffect[-1] : &:r2307_84, m2307_47
# 2307| m2307_88(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = ^IndirectMayWriteSideEffect[-1] : &:r2307_84
# 2307| m2307_89(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = Chi : total:m2307_47, partial:m2307_88
# 2307| r2307_90(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = CopyValue : r2307_86
# 2307| r2307_76(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = VariableAddress[(__begin)] :
# 2307| r2307_77(glval<unknown>) = FunctionAddress[operator++] :
# 2307| r2307_78(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &> &) = Call[operator++] : func:r2307_77, this:r2307_76
# 2307| v2307_79(void) = ^IndirectReadSideEffect[-1] : &:r2307_76, m2307_47
# 2307| m2307_80(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = ^IndirectMayWriteSideEffect[-1] : &:r2307_76
# 2307| m2307_81(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = Chi : total:m2307_47, partial:m2307_80
# 2307| r2307_82(glval<String>) = VariableAddress[s] :
# 2307| r2307_83(glval<unknown>) = FunctionAddress[~String] :
# 2307| v2307_84(void) = Call[~String] : func:r2307_83, this:r2307_82
# 2307| m2307_85(unknown) = ^CallSideEffect : ~m2309_8
# 2307| m2307_86(unknown) = Chi : total:m2309_8, partial:m2307_85
# 2307| v2307_87(void) = ^IndirectReadSideEffect[-1] : &:r2307_82, ~m2307_86
# 2307| m2307_88(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_82
# 2307| m2307_89(unknown) = Chi : total:m2307_86, partial:m2307_88
# 2307| r2307_90(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = CopyValue : r2307_78
#-----| Goto (back edge) -> Block 4
# 2311| Block 6

View File

@@ -14325,18 +14325,18 @@ ir.cpp:
# 2216| mu2216_5(unknown) = ^CallSideEffect : ~m?
# 2216| v2216_6(void) = ^IndirectReadSideEffect[-1] : &:r2216_1, ~m?
# 2216| mu2216_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2216_1
# 2215| r2215_49(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2215| r2215_50(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2215| v2215_51(void) = Call[~ClassWithDestructor] : func:r2215_50, this:r2215_49
# 2215| mu2215_52(unknown) = ^CallSideEffect : ~m?
# 2215| v2215_53(void) = ^IndirectReadSideEffect[-1] : &:r2215_49, ~m?
# 2215| mu2215_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_49
# 2215| r2215_55(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2215| r2215_56(glval<unknown>) = FunctionAddress[operator++] :
# 2215| r2215_57(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2215_56, this:r2215_55
# 2215| v2215_58(void) = ^IndirectReadSideEffect[-1] : &:r2215_55, ~m?
# 2215| mu2215_59(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2215_55
# 2215| r2215_60(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2215_57
# 2215| r2215_49(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2215| r2215_50(glval<unknown>) = FunctionAddress[operator++] :
# 2215| r2215_51(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2215_50, this:r2215_49
# 2215| v2215_52(void) = ^IndirectReadSideEffect[-1] : &:r2215_49, ~m?
# 2215| mu2215_53(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2215_49
# 2215| r2215_54(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2215| r2215_55(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2215| v2215_56(void) = Call[~ClassWithDestructor] : func:r2215_55, this:r2215_54
# 2215| mu2215_57(unknown) = ^CallSideEffect : ~m?
# 2215| v2215_58(void) = ^IndirectReadSideEffect[-1] : &:r2215_54, ~m?
# 2215| mu2215_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2215_54
# 2215| r2215_60(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2215_51
#-----| Goto (back edge) -> Block 11
# 2215| Block 13
@@ -14409,17 +14409,32 @@ ir.cpp:
#-----| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~m?
# 2218| v2218_42(void) = ConditionalBranch : r2218_41
#-----| False -> Block 20
#-----| True -> Block 16
#-----| True -> Block 17
# 2218| Block 16
# 2218| r2218_43(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_44(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_31(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2218_44
# 2218| r2218_45(glval<unknown>) = FunctionAddress[operator*] :
# 2218| r2218_46(ClassWithDestructor &) = Call[operator*] : func:r2218_45, this:r0_31
# 2218| r2218_43(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2218| r2218_44(glval<unknown>) = FunctionAddress[operator++] :
# 2218| r2218_45(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2218_44, this:r2218_43
# 2218| v2218_46(void) = ^IndirectReadSideEffect[-1] : &:r2218_43, ~m?
# 2218| mu2218_47(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_43
# 2218| r2218_48(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_49(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_50(void) = Call[~ClassWithDestructor] : func:r2218_49, this:r2218_48
# 2218| mu2218_51(unknown) = ^CallSideEffect : ~m?
# 2218| v2218_52(void) = ^IndirectReadSideEffect[-1] : &:r2218_48, ~m?
# 2218| mu2218_53(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_48
# 2218| r2218_54(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2218_45
#-----| Goto (back edge) -> Block 15
# 2218| Block 17
# 2218| r2218_55(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_56(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
#-----| r0_31(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = Convert : r2218_56
# 2218| r2218_57(glval<unknown>) = FunctionAddress[operator*] :
# 2218| r2218_58(ClassWithDestructor &) = Call[operator*] : func:r2218_57, this:r0_31
#-----| v0_32(void) = ^IndirectReadSideEffect[-1] : &:r0_31, ~m?
# 2218| r2218_47(ClassWithDestructor) = Load[?] : &:r2218_46, ~m?
# 2218| mu2218_48(ClassWithDestructor) = Store[y] : &:r2218_43, r2218_47
# 2218| r2218_59(ClassWithDestructor) = Load[?] : &:r2218_58, ~m?
# 2218| mu2218_60(ClassWithDestructor) = Store[y] : &:r2218_55, r2218_59
# 2219| r2219_1(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2219| r2219_2(glval<unknown>) = FunctionAddress[set_x] :
# 2219| r2219_3(char) = Constant[97] :
@@ -14437,23 +14452,23 @@ ir.cpp:
# 2220| r2220_8(int) = Constant[98] :
# 2220| r2220_9(bool) = CompareEQ : r2220_7, r2220_8
# 2220| v2220_10(void) = ConditionalBranch : r2220_9
#-----| False -> Block 18
#-----| True -> Block 17
#-----| False -> Block 16
#-----| True -> Block 18
# 2221| Block 17
# 2221| Block 18
# 2221| v2221_1(void) = NoOp :
# 2218| r2218_49(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_50(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_51(void) = Call[~ClassWithDestructor] : func:r2218_50, this:r2218_49
# 2218| mu2218_52(unknown) = ^CallSideEffect : ~m?
# 2218| v2218_53(void) = ^IndirectReadSideEffect[-1] : &:r2218_49, ~m?
# 2218| mu2218_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_49
# 2218| r2218_55(glval<vector<ClassWithDestructor>>) = VariableAddress[ys] :
# 2218| r2218_56(glval<unknown>) = FunctionAddress[~vector] :
# 2218| v2218_57(void) = Call[~vector] : func:r2218_56, this:r2218_55
# 2218| mu2218_58(unknown) = ^CallSideEffect : ~m?
# 2218| v2218_59(void) = ^IndirectReadSideEffect[-1] : &:r2218_55, ~m?
# 2218| mu2218_60(vector<ClassWithDestructor>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_55
# 2218| r2218_61(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_62(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_63(void) = Call[~ClassWithDestructor] : func:r2218_62, this:r2218_61
# 2218| mu2218_64(unknown) = ^CallSideEffect : ~m?
# 2218| v2218_65(void) = ^IndirectReadSideEffect[-1] : &:r2218_61, ~m?
# 2218| mu2218_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_61
# 2218| r2218_67(glval<vector<ClassWithDestructor>>) = VariableAddress[ys] :
# 2218| r2218_68(glval<unknown>) = FunctionAddress[~vector] :
# 2218| v2218_69(void) = Call[~vector] : func:r2218_68, this:r2218_67
# 2218| mu2218_70(unknown) = ^CallSideEffect : ~m?
# 2218| v2218_71(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m?
# 2218| mu2218_72(vector<ClassWithDestructor>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67
# 2233| r2233_1(glval<ClassWithDestructor>) = VariableAddress[x] :
# 2233| r2233_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2233| v2233_3(void) = Call[~ClassWithDestructor] : func:r2233_2, this:r2233_1
@@ -14462,21 +14477,6 @@ ir.cpp:
# 2233| mu2233_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2233_1
#-----| Goto -> Block 1
# 2218| Block 18
# 2218| r2218_61(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2218| r2218_62(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2218| v2218_63(void) = Call[~ClassWithDestructor] : func:r2218_62, this:r2218_61
# 2218| mu2218_64(unknown) = ^CallSideEffect : ~m?
# 2218| v2218_65(void) = ^IndirectReadSideEffect[-1] : &:r2218_61, ~m?
# 2218| mu2218_66(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2218_61
# 2218| r2218_67(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2218| r2218_68(glval<unknown>) = FunctionAddress[operator++] :
# 2218| r2218_69(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2218_68, this:r2218_67
# 2218| v2218_70(void) = ^IndirectReadSideEffect[-1] : &:r2218_67, ~m?
# 2218| mu2218_71(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2218_67
# 2218| r2218_72(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2218_69
#-----| Goto (back edge) -> Block 15
# 2218| Block 19
# 2218| r2218_73(glval<vector<ClassWithDestructor>>) = VariableAddress[ys] :
# 2218| r2218_74(glval<unknown>) = FunctionAddress[~vector] :
@@ -14686,18 +14686,18 @@ ir.cpp:
# 2232| mu2232_10(unknown) = ^CallSideEffect : ~m?
# 2232| v2232_11(void) = ^IndirectReadSideEffect[-1] : &:r2232_7, ~m?
# 2232| mu2232_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2232_7
# 2229| r2229_49(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2229| r2229_50(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2229| v2229_51(void) = Call[~ClassWithDestructor] : func:r2229_50, this:r2229_49
# 2229| mu2229_52(unknown) = ^CallSideEffect : ~m?
# 2229| v2229_53(void) = ^IndirectReadSideEffect[-1] : &:r2229_49, ~m?
# 2229| mu2229_54(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_49
# 2229| r2229_55(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2229| r2229_56(glval<unknown>) = FunctionAddress[operator++] :
# 2229| r2229_57(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2229_56, this:r2229_55
# 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_55, ~m?
# 2229| mu2229_59(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2229_55
# 2229| r2229_60(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2229_57
# 2229| r2229_49(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = VariableAddress[(__begin)] :
# 2229| r2229_50(glval<unknown>) = FunctionAddress[operator++] :
# 2229| r2229_51(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &> &) = Call[operator++] : func:r2229_50, this:r2229_49
# 2229| v2229_52(void) = ^IndirectReadSideEffect[-1] : &:r2229_49, ~m?
# 2229| mu2229_53(iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>) = ^IndirectMayWriteSideEffect[-1] : &:r2229_49
# 2229| r2229_54(glval<ClassWithDestructor>) = VariableAddress[y] :
# 2229| r2229_55(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2229| v2229_56(void) = Call[~ClassWithDestructor] : func:r2229_55, this:r2229_54
# 2229| mu2229_57(unknown) = ^CallSideEffect : ~m?
# 2229| v2229_58(void) = ^IndirectReadSideEffect[-1] : &:r2229_54, ~m?
# 2229| mu2229_59(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2229_54
# 2229| r2229_60(glval<iterator<random_access_iterator_tag, ClassWithDestructor, ptrdiff_t, ClassWithDestructor *, ClassWithDestructor &>>) = CopyValue : r2229_51
#-----| Goto (back edge) -> Block 27
# 2229| Block 29
@@ -15339,18 +15339,18 @@ ir.cpp:
# 2309| mu2309_4(unknown) = ^CallSideEffect : ~m?
# 2309| v2309_5(void) = ^IndirectReadSideEffect[-1] : &:r2309_1, ~m?
# 2309| mu2309_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r2309_1
# 2307| r2307_60(glval<String>) = VariableAddress[s] :
# 2307| r2307_61(glval<unknown>) = FunctionAddress[~String] :
# 2307| v2307_62(void) = Call[~String] : func:r2307_61, this:r2307_60
# 2307| mu2307_63(unknown) = ^CallSideEffect : ~m?
# 2307| v2307_64(void) = ^IndirectReadSideEffect[-1] : &:r2307_60, ~m?
# 2307| mu2307_65(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60
# 2307| r2307_66(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = VariableAddress[(__begin)] :
# 2307| r2307_67(glval<unknown>) = FunctionAddress[operator++] :
# 2307| r2307_68(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &> &) = Call[operator++] : func:r2307_67, this:r2307_66
# 2307| v2307_69(void) = ^IndirectReadSideEffect[-1] : &:r2307_66, ~m?
# 2307| mu2307_70(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = ^IndirectMayWriteSideEffect[-1] : &:r2307_66
# 2307| r2307_71(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = CopyValue : r2307_68
# 2307| r2307_60(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = VariableAddress[(__begin)] :
# 2307| r2307_61(glval<unknown>) = FunctionAddress[operator++] :
# 2307| r2307_62(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &> &) = Call[operator++] : func:r2307_61, this:r2307_60
# 2307| v2307_63(void) = ^IndirectReadSideEffect[-1] : &:r2307_60, ~m?
# 2307| mu2307_64(iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>) = ^IndirectMayWriteSideEffect[-1] : &:r2307_60
# 2307| r2307_65(glval<String>) = VariableAddress[s] :
# 2307| r2307_66(glval<unknown>) = FunctionAddress[~String] :
# 2307| v2307_67(void) = Call[~String] : func:r2307_66, this:r2307_65
# 2307| mu2307_68(unknown) = ^CallSideEffect : ~m?
# 2307| v2307_69(void) = ^IndirectReadSideEffect[-1] : &:r2307_65, ~m?
# 2307| mu2307_70(String) = ^IndirectMayWriteSideEffect[-1] : &:r2307_65
# 2307| r2307_71(glval<iterator<random_access_iterator_tag, String, ptrdiff_t, String *, String &>>) = CopyValue : r2307_62
#-----| Goto (back edge) -> Block 4
# 2311| Block 6

View File

@@ -1,41 +0,0 @@
WARNING: Type GVN has been deprecated and may be removed in future (ast_gvn.ql:4,6-9)
| test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 |
| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 |
| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 |
| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 |
| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 |
| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 |
| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 |
| test.cpp:16:7:16:24 | ... + ... | 16:c7-c24 17:c7-c24 18:c7-c7 |
| test.cpp:16:12:16:13 | p1 | 16:c12-c13 17:c12-c13 |
| test.cpp:16:17:16:24 | global01 | 16:c17-c24 17:c17-c24 |
| test.cpp:29:7:29:8 | p0 | 29:c7-c8 31:c7-c8 |
| test.cpp:29:7:29:13 | ... + ... | 29:c7-c13 31:c7-c13 |
| test.cpp:29:12:29:13 | p1 | 29:c12-c13 31:c12-c13 |
| test.cpp:31:7:31:24 | ... + ... | 31:c7-c24 32:c7-c7 |
| test.cpp:43:7:43:8 | p0 | 43:c7-c8 45:c7-c8 |
| test.cpp:43:7:43:13 | ... + ... | 43:c7-c13 45:c7-c13 |
| test.cpp:43:12:43:13 | p1 | 43:c12-c13 45:c12-c13 |
| test.cpp:44:9:44:9 | 0 | 44:c9-c9 51:c25-c25 53:c18-c21 56:c39-c42 59:c17-c20 88:c12-c12 |
| test.cpp:45:7:45:24 | ... + ... | 45:c7-c24 46:c7-c7 |
| test.cpp:53:10:53:13 | (int)... | 53:c10-c13 56:c21-c24 |
| test.cpp:53:10:53:13 | * ... | 53:c10-c13 56:c21-c24 |
| test.cpp:53:11:53:13 | str | 53:c11-c13 56:c22-c24 |
| test.cpp:53:18:53:21 | 0 | 53:c18-c21 56:c39-c42 59:c17-c20 |
| test.cpp:56:13:56:16 | (int)... | 56:c13-c16 56:c31-c34 59:c9-c12 |
| test.cpp:56:13:56:16 | * ... | 56:c13-c16 56:c31-c34 59:c9-c12 |
| test.cpp:56:14:56:16 | ptr | 56:c14-c16 56:c32-c34 56:c47-c49 59:c10-c12 |
| test.cpp:62:5:62:10 | result | 62:c5-c10 65:c10-c15 |
| test.cpp:77:20:77:30 | (signed short)... | 77:c20-c30 79:c7-c7 |
| test.cpp:79:11:79:14 | vals | 79:c11-c14 79:c24-c27 |
| test.cpp:105:11:105:12 | (Base *)... | 105:c11-c12 106:c14-c35 107:c11-c12 |
| test.cpp:105:11:105:12 | pd | 105:c11-c12 106:c33-c34 |
| test.cpp:105:15:105:15 | b | 105:c15-c15 107:c15-c15 109:c10-c10 |
| test.cpp:125:11:125:12 | pa | 125:c11-c12 126:c11-c12 128:c3-c4 129:c11-c12 |
| test.cpp:125:15:125:15 | x | 125:c15-c15 126:c15-c15 128:c7-c7 |
| test.cpp:136:11:136:18 | global_a | 136:c11-c18 137:c11-c18 139:c3-c10 |
| test.cpp:136:21:136:21 | x | 136:c21-c21 137:c21-c21 139:c13-c13 |
| test.cpp:144:11:144:12 | pa | 144:c11-c12 145:c11-c12 147:c3-c4 149:c11-c12 |
| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 |
| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 |
| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 |

View File

@@ -1,11 +0,0 @@
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl
from GVN g
where strictcount(g.getAnExpr()) > 1
select g,
strictconcat(Location loc |
loc = g.getAnExpr().getLocation()
|
loc.getStartLine() + ":c" + loc.getStartColumn() + "-c" + loc.getEndColumn(), " "
)

View File

@@ -1,3 +0,0 @@
WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:7,13-30)
WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:8,30-47)
WARNING: Type GVN has been deprecated and may be removed in future (ast_uniqueness.ql:8,18-21)

View File

@@ -1,8 +0,0 @@
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl
// Every expression should have exactly one GVN.
// So this query should have zero results.
from Expr e
where count(globalValueNumber(e)) != 1
select e, concat(GVN g | g = globalValueNumber(e) | g.getKind(), ", ")

View File

@@ -1,130 +0,0 @@
WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (diff_ir_expr.ql:8,29-51)
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |
| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only |
| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only |
| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only |
| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only |
| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only |
| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only |
| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only |
| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only |
| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only |
| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only |
| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only |
| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only |
| test.cpp:43:7:43:24 | ... + ... | test.cpp:46:7:46:7 | x | IR only |
| test.cpp:43:17:43:24 | global03 | test.cpp:45:17:45:24 | global03 | IR only |
| test.cpp:44:3:44:5 | * ... | test.cpp:44:4:44:5 | p2 | IR only |
| test.cpp:44:3:44:9 | ... = ... | test.cpp:44:3:44:9 | ... = ... | AST only |
| test.cpp:44:4:44:5 | p2 | test.cpp:44:3:44:5 | * ... | IR only |
| test.cpp:44:9:44:9 | 0 | test.cpp:51:25:51:25 | 0 | AST only |
| test.cpp:44:9:44:9 | 0 | test.cpp:53:18:53:21 | (int)... | AST only |
| test.cpp:44:9:44:9 | 0 | test.cpp:56:39:56:42 | (int)... | AST only |
| test.cpp:44:9:44:9 | 0 | test.cpp:59:17:59:20 | (int)... | AST only |
| test.cpp:44:9:44:9 | 0 | test.cpp:88:12:88:12 | 0 | AST only |
| test.cpp:45:3:45:3 | x | test.cpp:43:3:43:3 | x | IR only |
| test.cpp:45:3:45:24 | ... = ... | test.cpp:45:3:45:24 | ... = ... | AST only |
| test.cpp:45:7:45:24 | ... + ... | test.cpp:43:7:43:24 | ... + ... | IR only |
| test.cpp:45:17:45:24 | global03 | test.cpp:43:17:43:24 | global03 | IR only |
| test.cpp:46:3:46:7 | ... = ... | test.cpp:46:3:46:7 | ... = ... | AST only |
| test.cpp:46:7:46:7 | x | test.cpp:43:7:43:24 | ... + ... | IR only |
| test.cpp:51:25:51:25 | 0 | test.cpp:44:9:44:9 | 0 | AST only |
| test.cpp:51:25:51:25 | 0 | test.cpp:53:18:53:21 | (int)... | AST only |
| test.cpp:51:25:51:25 | 0 | test.cpp:56:39:56:42 | (int)... | AST only |
| test.cpp:51:25:51:25 | 0 | test.cpp:59:17:59:20 | (int)... | AST only |
| test.cpp:51:25:51:25 | 0 | test.cpp:88:12:88:12 | 0 | AST only |
| test.cpp:51:25:51:25 | (unsigned int)... | test.cpp:51:25:51:25 | (unsigned int)... | AST only |
| test.cpp:53:10:53:13 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only |
| test.cpp:53:10:53:13 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only |
| test.cpp:53:18:53:21 | (int)... | test.cpp:44:9:44:9 | 0 | AST only |
| test.cpp:53:18:53:21 | (int)... | test.cpp:51:25:51:25 | 0 | AST only |
| test.cpp:53:18:53:21 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only |
| test.cpp:53:18:53:21 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only |
| test.cpp:53:18:53:21 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only |
| test.cpp:53:18:53:21 | (int)... | test.cpp:88:12:88:12 | 0 | AST only |
| test.cpp:55:5:55:15 | ... = ... | test.cpp:55:5:55:15 | ... = ... | AST only |
| test.cpp:56:12:56:25 | (...) | test.cpp:56:12:56:25 | (...) | AST only |
| test.cpp:56:12:56:43 | ... && ... | test.cpp:56:12:56:43 | ... && ... | AST only |
| test.cpp:56:13:56:16 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only |
| test.cpp:56:13:56:16 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only |
| test.cpp:56:13:56:16 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only |
| test.cpp:56:21:56:24 | (int)... | test.cpp:53:10:53:13 | (int)... | AST only |
| test.cpp:56:21:56:24 | (int)... | test.cpp:56:21:56:24 | (int)... | AST only |
| test.cpp:56:30:56:43 | (...) | test.cpp:56:30:56:43 | (...) | AST only |
| test.cpp:56:31:56:34 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only |
| test.cpp:56:31:56:34 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only |
| test.cpp:56:31:56:34 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only |
| test.cpp:56:39:56:42 | (int)... | test.cpp:44:9:44:9 | 0 | AST only |
| test.cpp:56:39:56:42 | (int)... | test.cpp:51:25:51:25 | 0 | AST only |
| test.cpp:56:39:56:42 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only |
| test.cpp:56:39:56:42 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only |
| test.cpp:56:39:56:42 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only |
| test.cpp:56:39:56:42 | (int)... | test.cpp:88:12:88:12 | 0 | AST only |
| test.cpp:56:47:56:51 | ... ++ | test.cpp:56:47:56:51 | ... ++ | AST only |
| test.cpp:59:9:59:12 | (int)... | test.cpp:56:13:56:16 | (int)... | AST only |
| test.cpp:59:9:59:12 | (int)... | test.cpp:56:31:56:34 | (int)... | AST only |
| test.cpp:59:9:59:12 | (int)... | test.cpp:59:9:59:12 | (int)... | AST only |
| test.cpp:59:17:59:20 | (int)... | test.cpp:44:9:44:9 | 0 | AST only |
| test.cpp:59:17:59:20 | (int)... | test.cpp:51:25:51:25 | 0 | AST only |
| test.cpp:59:17:59:20 | (int)... | test.cpp:53:18:53:21 | (int)... | AST only |
| test.cpp:59:17:59:20 | (int)... | test.cpp:56:39:56:42 | (int)... | AST only |
| test.cpp:59:17:59:20 | (int)... | test.cpp:59:17:59:20 | (int)... | AST only |
| test.cpp:59:17:59:20 | (int)... | test.cpp:88:12:88:12 | 0 | AST only |
| test.cpp:62:5:62:12 | ... ++ | test.cpp:62:5:62:12 | ... ++ | AST only |
| test.cpp:77:20:77:28 | call to getAValue | test.cpp:79:7:79:7 | v | IR only |
| test.cpp:77:20:77:30 | (signed short)... | test.cpp:77:20:77:30 | (signed short)... | AST only |
| test.cpp:77:20:77:30 | (signed short)... | test.cpp:79:7:79:7 | v | AST only |
| test.cpp:79:7:79:7 | (int)... | test.cpp:79:7:79:7 | (int)... | AST only |
| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:28 | call to getAValue | IR only |
| test.cpp:79:7:79:7 | v | test.cpp:77:20:77:30 | (signed short)... | AST only |
| test.cpp:79:11:79:20 | (int)... | test.cpp:79:11:79:20 | (int)... | AST only |
| test.cpp:79:24:79:33 | (int)... | test.cpp:79:24:79:33 | (int)... | AST only |
| test.cpp:80:5:80:19 | ... = ... | test.cpp:80:5:80:19 | ... = ... | AST only |
| test.cpp:80:9:80:19 | (signed short)... | test.cpp:80:9:80:19 | (signed short)... | AST only |
| test.cpp:88:3:88:20 | ... = ... | test.cpp:88:3:88:20 | ... = ... | AST only |
| test.cpp:88:12:88:12 | 0 | test.cpp:44:9:44:9 | 0 | AST only |
| test.cpp:88:12:88:12 | 0 | test.cpp:51:25:51:25 | 0 | AST only |
| test.cpp:88:12:88:12 | 0 | test.cpp:53:18:53:21 | (int)... | AST only |
| test.cpp:88:12:88:12 | 0 | test.cpp:56:39:56:42 | (int)... | AST only |
| test.cpp:88:12:88:12 | 0 | test.cpp:59:17:59:20 | (int)... | AST only |
| test.cpp:88:12:88:12 | (void *)... | test.cpp:88:12:88:12 | (void *)... | AST only |
| test.cpp:92:11:92:16 | ... = ... | test.cpp:92:15:92:16 | 10 | IR only |
| test.cpp:92:11:92:16 | ... = ... | test.cpp:93:10:93:10 | x | IR only |
| test.cpp:92:15:92:16 | 10 | test.cpp:92:11:92:16 | ... = ... | IR only |
| test.cpp:92:15:92:16 | 10 | test.cpp:93:10:93:10 | x | IR only |
| test.cpp:93:10:93:10 | x | test.cpp:92:11:92:16 | ... = ... | IR only |
| test.cpp:93:10:93:10 | x | test.cpp:92:15:92:16 | 10 | IR only |
| test.cpp:105:11:105:12 | (Base *)... | test.cpp:105:11:105:12 | (Base *)... | AST only |
| test.cpp:105:11:105:12 | (Base *)... | test.cpp:106:14:106:35 | static_cast<Base *>... | AST only |
| test.cpp:105:11:105:12 | (Base *)... | test.cpp:107:11:107:12 | pb | AST only |
| test.cpp:105:11:105:12 | pd | test.cpp:107:11:107:12 | pb | IR only |
| test.cpp:106:14:106:35 | static_cast<Base *>... | test.cpp:105:11:105:12 | (Base *)... | AST only |
| test.cpp:106:14:106:35 | static_cast<Base *>... | test.cpp:106:14:106:35 | static_cast<Base *>... | AST only |
| test.cpp:106:14:106:35 | static_cast<Base *>... | test.cpp:107:11:107:12 | pb | AST only |
| test.cpp:106:33:106:34 | pd | test.cpp:107:11:107:12 | pb | IR only |
| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | (Base *)... | AST only |
| test.cpp:107:11:107:12 | pb | test.cpp:105:11:105:12 | pd | IR only |
| test.cpp:107:11:107:12 | pb | test.cpp:106:14:106:35 | static_cast<Base *>... | AST only |
| test.cpp:107:11:107:12 | pb | test.cpp:106:33:106:34 | pd | IR only |
| test.cpp:113:3:113:5 | a | test.cpp:115:3:115:5 | a | IR only |
| test.cpp:115:3:115:5 | a | test.cpp:113:3:113:5 | a | IR only |
| test.cpp:125:15:125:15 | x | test.cpp:128:7:128:7 | x | AST only |
| test.cpp:126:15:126:15 | x | test.cpp:128:7:128:7 | x | AST only |
| test.cpp:128:3:128:11 | ... = ... | test.cpp:128:3:128:11 | ... = ... | AST only |
| test.cpp:128:7:128:7 | x | test.cpp:125:15:125:15 | x | AST only |
| test.cpp:128:7:128:7 | x | test.cpp:126:15:126:15 | x | AST only |
| test.cpp:128:11:128:11 | n | test.cpp:129:15:129:15 | x | IR only |
| test.cpp:129:15:129:15 | x | test.cpp:128:11:128:11 | n | IR only |
| test.cpp:136:21:136:21 | x | test.cpp:139:13:139:13 | x | AST only |
| test.cpp:137:21:137:21 | x | test.cpp:139:13:139:13 | x | AST only |
| test.cpp:139:3:139:24 | ... = ... | test.cpp:139:3:139:24 | ... = ... | AST only |
| test.cpp:139:13:139:13 | x | test.cpp:136:21:136:21 | x | AST only |
| test.cpp:139:13:139:13 | x | test.cpp:137:21:137:21 | x | AST only |
| test.cpp:144:15:144:15 | x | test.cpp:149:15:149:15 | x | IR only |
| test.cpp:145:15:145:15 | y | test.cpp:147:7:147:7 | y | AST only |
| test.cpp:147:3:147:18 | ... = ... | test.cpp:147:3:147:18 | ... = ... | AST only |
| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only |
| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only |
| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only |

View File

@@ -1,15 +0,0 @@
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl as AST
import semmle.code.cpp.ir.internal.ASTValueNumbering as IR
import semmle.code.cpp.ir.IR
Expr ir(Expr e) { result = IR::globalValueNumber(e).getAnExpr() }
Expr ast(Expr e) { result = AST::globalValueNumber(e).getAnExpr() }
from Expr e, Expr evn, string note
where
evn = ast(e) and not evn = ir(e) and note = "AST only"
or
evn = ir(e) and not evn = ast(e) and note = "IR only"
select e, evn, note

View File

@@ -16,6 +16,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
private readonly ILogger logger;
/// <summary>
/// Contains the dependencies found in the parsed assets files.
/// </summary>
public DependencyContainer Dependencies { get; } = new();
internal Assets(ILogger logger)
{
this.logger = logger;
@@ -72,7 +77,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// "json.net"
/// }
/// </summary>
private void AddPackageDependencies(JObject json, DependencyContainer dependencies)
private void AddPackageDependencies(JObject json)
{
// If there is more than one framework we need to pick just one.
// To ensure stability we pick one based on the lexicographic order of
@@ -107,13 +112,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
// If this is a framework reference then include everything.
if (FrameworkPackageNames.AllFrameworks.Any(framework => name.StartsWith(framework)))
{
dependencies.AddFramework(name);
Dependencies.AddFramework(name);
}
return;
}
info.Compile
.ForEach(r => dependencies.Add(name, r.Key));
.ForEach(r => Dependencies.Add(name, r.Key));
});
return;
@@ -149,7 +154,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// "microsoft.netcore.app.ref"
/// }
/// </summary>
private void AddFrameworkDependencies(JObject json, DependencyContainer dependencies)
private void AddFrameworkDependencies(JObject json)
{
var frameworks = json
@@ -178,7 +183,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
references
.Properties()
.ForEach(f => dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant()));
.ForEach(f => Dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant()));
}
/// <summary>
@@ -186,13 +191,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// (together with used package information) required for compilation.
/// </summary>
/// <returns>True if parsing succeeds, otherwise false.</returns>
public bool TryParse(string json, DependencyContainer dependencies)
public bool TryParse(string json)
{
try
{
var obj = JObject.Parse(json);
AddPackageDependencies(obj, dependencies);
AddFrameworkDependencies(obj, dependencies);
AddPackageDependencies(obj);
AddFrameworkDependencies(obj);
return true;
}
catch (Exception e)
@@ -217,19 +222,24 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
public static DependencyContainer GetCompilationDependencies(ILogger logger, IEnumerable<string> assets)
/// <summary>
/// Add the dependencies from the assets file to the dependencies.
/// </summary>
/// <param name="asset">Path to an assets file.</param>
public void AddDependencies(string asset)
{
var parser = new Assets(logger);
var dependencies = new DependencyContainer();
assets.ForEach(asset =>
if (TryReadAllText(asset, logger, out var json))
{
if (TryReadAllText(asset, logger, out var json))
{
parser.TryParse(json, dependencies);
}
});
return dependencies;
TryParse(json);
}
}
/// <summary>
/// Add the dependencies from the assets files to the dependencies.
/// </summary>
/// <param name="assets">Collection of paths to assets files.</param>
public void AddDependenciesRange(IEnumerable<string> assets) =>
assets.ForEach(AddDependencies);
}
internal static class JsonExtensions

View File

@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// <summary>
/// Paths to dependencies required for compilation.
/// </summary>
public List<string> Paths { get; } = new();
public HashSet<string> Paths { get; } = new();
/// <summary>
/// Packages that are used as a part of the required dependencies.
@@ -45,7 +45,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var p = package.Replace('/', Path.DirectorySeparatorChar);
var d = dependency.Replace('/', Path.DirectorySeparatorChar);
// In most cases paths in asset files point to dll's or the empty _._ file.
// In most cases paths in assets files point to dll's or the empty _._ file.
// That is, for _._ we don't need to add anything.
if (Path.GetFileName(d) == "_._")
{
@@ -68,4 +68,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
Packages.Add(GetPackageName(p));
}
}
internal static class DependencyContainerExtensions
{
/// <summary>
/// Flatten a list of containers into a single container.
/// </summary>
public static DependencyContainer Flatten(this IEnumerable<DependencyContainer> containers, DependencyContainer init) =>
containers.Aggregate(init, (acc, container) =>
{
acc.Paths.UnionWith(container.Paths);
acc.Packages.UnionWith(container.Packages);
return acc;
});
}
}

View File

@@ -3,8 +3,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Semmle.Util;

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -144,11 +145,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
logger.LogError($"Failed to restore Nuget packages with nuget.exe: {exc.Message}");
}
var restoredProjects = RestoreSolutions(out var assets1);
var restoredProjects = RestoreSolutions(out var container);
var projects = fileProvider.Projects.Except(restoredProjects);
RestoreProjects(projects, out var assets2);
RestoreProjects(projects, out var containers);
var dependencies = Assets.GetCompilationDependencies(logger, assets1.Union(assets2));
var dependencies = containers.Flatten(container);
var paths = dependencies
.Paths
@@ -198,14 +199,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
/// as `dotnet restore` on a solution already uses multiple threads for restoring
/// the projects (this can be disabled with the `--disable-parallel` flag).
/// Populates assets with the relative paths to the assets files generated by the restore.
/// Populates dependencies with the relevant dependencies from the assets files generated by the restore.
/// Returns a list of projects that are up to date with respect to restore.
/// </summary>
private IEnumerable<string> RestoreSolutions(out IEnumerable<string> assets)
private IEnumerable<string> RestoreSolutions(out DependencyContainer dependencies)
{
var successCount = 0;
var nugetSourceFailures = 0;
var assetFiles = new List<string>();
var assets = new Assets(logger);
var projects = fileProvider.Solutions.SelectMany(solution =>
{
logger.LogInfo($"Restoring solution {solution}...");
@@ -218,10 +219,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
nugetSourceFailures++;
}
assetFiles.AddRange(res.AssetsFilePaths);
assets.AddDependenciesRange(res.AssetsFilePaths);
return res.RestoredProjects;
}).ToList();
assets = assetFiles;
dependencies = assets.Dependencies;
compilationInfoContainer.CompilationInfos.Add(("Successfully restored solution files", successCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Failed solution restore with package source error", nugetSourceFailures.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString()));
@@ -231,33 +232,39 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// <summary>
/// Executes `dotnet restore` on all projects in projects.
/// This is done in parallel for performance reasons.
/// Populates assets with the relative paths to the assets files generated by the restore.
/// Populates dependencies with the relative paths to the assets files generated by the restore.
/// </summary>
/// <param name="projects">A list of paths to project files.</param>
private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<string> assets)
private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<DependencyContainer> dependencies)
{
var successCount = 0;
var nugetSourceFailures = 0;
var assetFiles = new List<string>();
ConcurrentBag<DependencyContainer> collectedDependencies = [];
var sync = new object();
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, project =>
var projectGroups = projects.GroupBy(Path.GetDirectoryName);
Parallel.ForEach(projectGroups, new ParallelOptions { MaxDegreeOfParallelism = DependencyManager.Threads }, projectGroup =>
{
logger.LogInfo($"Restoring project {project}...");
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true));
lock (sync)
var assets = new Assets(logger);
foreach (var project in projectGroup)
{
if (res.Success)
logger.LogInfo($"Restoring project {project}...");
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true));
assets.AddDependenciesRange(res.AssetsFilePaths);
lock (sync)
{
successCount++;
if (res.Success)
{
successCount++;
}
if (res.HasNugetPackageSourceError)
{
nugetSourceFailures++;
}
}
if (res.HasNugetPackageSourceError)
{
nugetSourceFailures++;
}
assetFiles.AddRange(res.AssetsFilePaths);
}
collectedDependencies.Add(assets.Dependencies);
});
assets = assetFiles;
dependencies = collectedDependencies;
compilationInfoContainer.CompilationInfos.Add(("Successfully restored project files", successCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString()));
}

View File

@@ -40,7 +40,6 @@ namespace Semmle.Extraction.CSharp.Standalone
output.Name, syntaxTrees, references, new CSharpCompilationOptions(OutputKind.ConsoleApplication, allowUnsafe: true)
),
(compilation, options) => analyser.Initialize(output.FullName, extractionInput.CompilationInfos, compilation, options),
_ => { },
() =>
{
foreach (var type in analyser.MissingNamespaces)

View File

@@ -245,6 +245,8 @@ namespace Semmle.Extraction.CSharp
}
}
public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p);
#nullable restore warnings
/// <summary>

View File

@@ -309,7 +309,6 @@ namespace Semmle.Extraction.CSharp
Func<Analyser, List<SyntaxTree>, IEnumerable<Action>> getSyntaxTreeTasks,
Func<IEnumerable<SyntaxTree>, IEnumerable<MetadataReference>, CSharpCompilation> getCompilation,
Action<CSharpCompilation, CommonOptions> initializeAnalyser,
Action<Entities.PerformanceMetrics> logPerformance,
Action postProcess)
{
using var references = new BlockingCollection<MetadataReference>();
@@ -368,7 +367,7 @@ namespace Semmle.Extraction.CSharp
PeakWorkingSet = currentProcess.PeakWorkingSet64
};
logPerformance(performance);
analyser.LogPerformance(performance);
analyser.Logger.Log(Severity.Info, " Extraction took {0}", sw.Elapsed);
postProcess();
@@ -422,7 +421,6 @@ namespace Semmle.Extraction.CSharp
);
},
(compilation, options) => analyser.EndInitialize(compilerArguments, options, compilation),
performance => analyser.LogPerformance(performance),
() => { });
}

View File

@@ -175,9 +175,6 @@ namespace Semmle.Extraction.CSharp
Where(e => e.Severity >= DiagnosticSeverity.Error && !errorsToIgnore.Contains(e.Id));
}
}
public void LogPerformance(Entities.PerformanceMetrics p) => compilationEntity.PopulatePerformance(p);
#nullable restore warnings
}
}

View File

@@ -14,29 +14,28 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsJson1;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
Assert.Equal(6, dependencies.Paths.Count());
Assert.Equal(5, dependencies.Packages.Count());
Assert.Equal(6, assets.Dependencies.Paths.Count);
Assert.Equal(5, assets.Dependencies.Packages.Count);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used references
Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll", normalizedPaths);
Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core2.dll", normalizedPaths);
Assert.Contains("json.net/1.0.33/lib/netstandard2.0/Json.Net.dll", normalizedPaths);
Assert.Contains("microsoft.aspnetcore.cryptography.internal/6.0.8/lib/net6.0/Microsoft.AspNetCore.Cryptography.Internal.dll", normalizedPaths);
// Used packages
Assert.Contains("castle.core", dependencies.Packages);
Assert.Contains("json.net", dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.cryptography.internal", dependencies.Packages);
Assert.Contains("castle.core", assets.Dependencies.Packages);
Assert.Contains("json.net", assets.Dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.cryptography.internal", assets.Dependencies.Packages);
// Used frameworks
Assert.Contains("microsoft.netcore.app.ref", dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.app.ref", dependencies.Packages);
Assert.Contains("microsoft.netcore.app.ref", assets.Dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.app.ref", assets.Dependencies.Packages);
}
[Fact]
@@ -45,14 +44,13 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = "garbage data";
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.False(success);
Assert.Empty(dependencies.Paths);
Assert.Empty(assets.Dependencies.Paths);
}
[Fact]
@@ -61,28 +59,27 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsNet70;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
Assert.Equal(4, dependencies.Paths.Count);
Assert.Equal(4, dependencies.Packages.Count);
Assert.Equal(4, assets.Dependencies.Paths.Count);
Assert.Equal(4, assets.Dependencies.Packages.Count);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used paths
Assert.Contains("microsoft.netcore.app.ref", normalizedPaths);
Assert.Contains("microsoft.aspnetcore.app.ref", normalizedPaths);
Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths);
Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths);
// Used packages
Assert.Contains("microsoft.netcore.app.ref", dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.app.ref", dependencies.Packages);
Assert.Contains("newtonsoft.json", dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", dependencies.Packages);
Assert.Contains("microsoft.netcore.app.ref", assets.Dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.app.ref", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages);
}
@@ -92,25 +89,24 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsNet48;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
Assert.Equal(3, dependencies.Paths.Count);
Assert.Equal(3, dependencies.Packages.Count);
Assert.Equal(3, assets.Dependencies.Paths.Count);
Assert.Equal(3, assets.Dependencies.Packages.Count);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used references
Assert.Contains("microsoft.netframework.referenceassemblies.net48/1.0.2", normalizedPaths);
Assert.Contains("newtonsoft.json/12.0.1/lib/net45/Newtonsoft.Json.dll", normalizedPaths);
Assert.Contains("newtonsoft.json.bson/1.0.2/lib/net45/Newtonsoft.Json.Bson.dll", normalizedPaths);
// Used packages
Assert.Contains("microsoft.netframework.referenceassemblies.net48", dependencies.Packages);
Assert.Contains("newtonsoft.json", dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", dependencies.Packages);
Assert.Contains("microsoft.netframework.referenceassemblies.net48", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages);
}
[Fact]
@@ -119,26 +115,25 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsNetstandard21;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
Assert.Equal(3, dependencies.Paths.Count);
Assert.Equal(3, dependencies.Packages.Count);
Assert.Equal(3, assets.Dependencies.Paths.Count);
Assert.Equal(3, assets.Dependencies.Packages.Count);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used references
Assert.Contains("netstandard.library.ref", normalizedPaths);
Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths);
Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths);
// Used packages
Assert.Contains("netstandard.library.ref", dependencies.Packages);
Assert.Contains("newtonsoft.json", dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", dependencies.Packages);
Assert.Contains("netstandard.library.ref", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages);
}
[Fact]
@@ -147,17 +142,16 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsNetstandard16;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
Assert.Equal(5, dependencies.Paths.Count);
Assert.Equal(5, dependencies.Packages.Count);
Assert.Equal(5, assets.Dependencies.Paths.Count);
Assert.Equal(5, assets.Dependencies.Packages.Count);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used references
Assert.Contains("netstandard.library/1.6.1", normalizedPaths);
@@ -166,11 +160,11 @@ namespace Semmle.Extraction.Tests
Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard1.3/Newtonsoft.Json.dll", normalizedPaths);
Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard1.3/Newtonsoft.Json.Bson.dll", normalizedPaths);
// Used packages
Assert.Contains("netstandard.library", dependencies.Packages);
Assert.Contains("microsoft.csharp", dependencies.Packages);
Assert.Contains("microsoft.win32.primitives", dependencies.Packages);
Assert.Contains("newtonsoft.json", dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", dependencies.Packages);
Assert.Contains("netstandard.library", assets.Dependencies.Packages);
Assert.Contains("microsoft.csharp", assets.Dependencies.Packages);
Assert.Contains("microsoft.win32.primitives", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages);
}
[Fact]
@@ -179,26 +173,25 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsNetcoreapp20;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
Assert.Equal(144, dependencies.Paths.Count);
Assert.Equal(3, dependencies.Packages.Count);
Assert.Equal(144, assets.Dependencies.Paths.Count);
Assert.Equal(3, assets.Dependencies.Packages.Count);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used references (only some of them)
Assert.Contains("microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/Microsoft.CSharp.dll", normalizedPaths);
Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths);
Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths);
// Used packages
Assert.Contains("microsoft.netcore.app", dependencies.Packages);
Assert.Contains("newtonsoft.json", dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", dependencies.Packages);
Assert.Contains("microsoft.netcore.app", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages);
}
[Fact]
@@ -207,15 +200,14 @@ namespace Semmle.Extraction.Tests
// Setup
var assets = new Assets(new LoggerStub());
var json = assetsNetcoreapp31;
var dependencies = new DependencyContainer();
// Execute
var success = assets.TryParse(json, dependencies);
var success = assets.TryParse(json);
// Verify
Assert.True(success);
var normalizedPaths = dependencies.Paths.Select(FixExpectedPathOnWindows);
var normalizedPaths = assets.Dependencies.Paths.Select(FixExpectedPathOnWindows);
// Used paths
Assert.Contains("microsoft.netcore.app.ref", normalizedPaths);
@@ -223,10 +215,10 @@ namespace Semmle.Extraction.Tests
Assert.Contains("newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll", normalizedPaths);
Assert.Contains("newtonsoft.json.bson/1.0.2/lib/netstandard2.0/Newtonsoft.Json.Bson.dll", normalizedPaths);
// Used packages
Assert.Contains("microsoft.netcore.app.ref", dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.app.ref", dependencies.Packages);
Assert.Contains("newtonsoft.json", dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", dependencies.Packages);
Assert.Contains("microsoft.netcore.app.ref", assets.Dependencies.Packages);
Assert.Contains("microsoft.aspnetcore.app.ref", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json", assets.Dependencies.Packages);
Assert.Contains("newtonsoft.json.bson", assets.Dependencies.Packages);
}
/// <summary>

View File

@@ -0,0 +1,166 @@
| [...]/avalara.avatax/23.11.0/lib/netstandard2.0/Avalara.AvaTax.RestClient.dll |
| [...]/microsoft.bcl.asyncinterfaces/8.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.CSharp.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.Core.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.VisualBasic.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.Win32.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/Microsoft.Win32.Registry.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.AppContext.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Buffers.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Concurrent.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Immutable.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.NonGeneric.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.Specialized.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Collections.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.Annotations.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.DataAnnotations.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.EventBasedAsync.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.TypeConverter.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ComponentModel.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Configuration.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Console.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Core.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.Common.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.DataSetExtensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Data.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Contracts.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Debug.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.DiagnosticSource.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.FileVersionInfo.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Process.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.StackTrace.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.TextWriterTraceListener.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Tools.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.TraceSource.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Diagnostics.Tracing.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Drawing.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Drawing.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Dynamic.Runtime.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Formats.Asn1.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Formats.Tar.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.Calendars.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.Extensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Globalization.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.Brotli.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.FileSystem.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.ZipFile.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Compression.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.AccessControl.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.DriveInfo.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.Watcher.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.FileSystem.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.IsolatedStorage.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.MemoryMappedFiles.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Pipes.AccessControl.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.Pipes.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.UnmanagedMemoryStream.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.IO.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Expressions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Parallel.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.Queryable.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Linq.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Memory.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Http.Json.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Http.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.HttpListener.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Mail.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.NameResolution.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.NetworkInformation.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Ping.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Quic.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Requests.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Security.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.ServicePoint.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.Sockets.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebClient.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebHeaderCollection.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebProxy.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebSockets.Client.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.WebSockets.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Net.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Numerics.Vectors.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Numerics.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ObjectModel.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.DispatchProxy.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.ILGeneration.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.Lightweight.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Emit.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Extensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Metadata.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.TypeExtensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Reflection.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.Reader.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.ResourceManager.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Resources.Writer.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.CompilerServices.Unsafe.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.CompilerServices.VisualC.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Extensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Handles.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.JavaScript.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.RuntimeInformation.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.InteropServices.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Intrinsics.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Loader.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Numerics.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Formatters.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Json.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.Xml.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.Serialization.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Runtime.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.AccessControl.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Claims.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Algorithms.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Cng.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Csp.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Encoding.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.OpenSsl.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.Primitives.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.X509Certificates.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Cryptography.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Principal.Windows.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.Principal.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.SecureString.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Security.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ServiceModel.Web.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ServiceProcess.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.CodePages.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.Extensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encoding.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Encodings.Web.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.Json.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Text.RegularExpressions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Channels.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Overlapped.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Dataflow.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Extensions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.Parallel.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Tasks.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Thread.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.ThreadPool.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.Timer.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Threading.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Transactions.Local.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Transactions.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.ValueTuple.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Web.HttpUtility.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Web.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Windows.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.Linq.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.ReaderWriter.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.Serialization.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XDocument.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XPath.XDocument.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XPath.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XmlDocument.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.XmlSerializer.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.Xml.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/System.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/WindowsBase.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/mscorlib.dll |
| [...]/microsoft.netcore.app.ref/8.0.1/ref/net8.0/netstandard.dll |
| [...]/newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll |

View File

@@ -0,0 +1,17 @@
import csharp
private string getPath(Assembly a) {
not a.getCompilation().getOutputAssembly() = a and
exists(string s | s = a.getFile().getAbsolutePath() |
result =
"[...]" +
s.substring(s.indexOf("test-db/working/") + "test-db/working/".length() + 16 +
"/packages".length(), s.length())
or
result = s and
not exists(s.indexOf("test-db/working/"))
)
}
from Assembly a
select getPath(a)

View File

@@ -0,0 +1,6 @@
class Program
{
static void Main(string[] args)
{
}
}

View File

@@ -0,0 +1,5 @@
{
"sdk": {
"version": "8.0.101"
}
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
<RemoveDir Directories=".\bin" />
<RemoveDir Directories=".\obj" />
</Target>
<ItemGroup>
<PackageReference Include="Avalara.AvaTax" Version="23.11.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
<RemoveDir Directories=".\bin" />
<RemoveDir Directories=".\obj" />
</Target>
<ItemGroup>
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,3 @@
from create_database_utils import *
run_codeql_database_create([], lang="csharp", extra_args=["--build-mode=none"])

View File

@@ -0,0 +1,6 @@
---
category: breaking
---
* Deleted the deprecated `getAssemblyName` predicate from the `Operator` class. Use `getFunctionName` instead.
* Deleted the deprecated `LShiftOperator`, `RShiftOperator`, `AssignLShiftExpr`, `AssignRShiftExpr`, `LShiftExpr`, and `RShiftExpr` aliases.
* Deleted the deprecated `getCallableDescription` predicate from the `ExternalApiDataNode` class. Use `hasQualifiedName` instead.

View File

@@ -527,13 +527,6 @@ class Destructor extends Callable, Member, Attributable, @destructor {
* (`BinaryOperator`), or a conversion operator (`ConversionOperator`).
*/
class Operator extends Callable, Member, Attributable, Overridable, @operator {
/**
* DEPRECATED: use `getFunctionName()` instead.
*
* Gets the assembly name of this operator.
*/
deprecated string getAssemblyName() { result = this.getFunctionName() }
override string getName() { operators(this, _, result, _, _, _) }
override string getUndecoratedName() { operators(this, _, result, _, _, _) }
@@ -989,9 +982,6 @@ class LeftShiftOperator extends BinaryOperator {
override string getAPrimaryQlClass() { result = "LeftShiftOperator" }
}
/** DEPRECATED: Alias for LeftShiftOperator. */
deprecated class LShiftOperator = LeftShiftOperator;
/**
* A user-defined right shift operator (`>>`), for example
*
@@ -1007,9 +997,6 @@ class RightShiftOperator extends BinaryOperator {
override string getAPrimaryQlClass() { result = "RightShiftOperator" }
}
/** DEPRECATED: Alias for RightShiftOperator. */
deprecated class RShiftOperator = RightShiftOperator;
/**
* A user-defined unsigned right shift operator (`>>>`), for example
*

View File

@@ -192,9 +192,6 @@ class AssignLeftShiftExpr extends AssignBitwiseOperation, @assign_lshift_expr {
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
}
/** DEPRECATED: Alias for AssignLeftShipExpr. */
deprecated class AssignLShiftExpr = AssignLeftShiftExpr;
/**
* A right-shift assignment operation, for example `x >>= y`.
*/
@@ -204,9 +201,6 @@ class AssignRightShiftExpr extends AssignBitwiseOperation, @assign_rshift_expr {
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
}
/** DEPRECATED: Alias for AssignRightShiftExpr. */
deprecated class AssignRShiftExpr = AssignRightShiftExpr;
/**
* An unsigned right-shift assignment operation, for example `x >>>= y`.
*/

View File

@@ -47,9 +47,6 @@ class LeftShiftExpr extends BinaryBitwiseOperation, @lshift_expr {
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
}
/** DEPRECATED: Alias for LeftShiftExpr. */
deprecated class LShiftExpr = LeftShiftExpr;
/**
* A right-shift operation, for example `x >> y`.
*/
@@ -59,9 +56,6 @@ class RightShiftExpr extends BinaryBitwiseOperation, @rshift_expr {
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
}
/** DEPRECATED: Alias for RightShiftExpr. */
deprecated class RShiftExpr = RightShiftExpr;
/**
* An unsigned right-shift operation, for example `x >>> y`.
*/

View File

@@ -71,17 +71,6 @@ class ExternalApiDataNode extends DataFlow::Node {
predicate hasQualifiedName(string qualifier, string name) {
this.getCallable().hasFullyQualifiedName(qualifier, name)
}
/**
* DEPRECATED: Use hasQualifiedName/2 instead.
*
* Gets the description of the callable being called.
*/
deprecated string getCallableDescription() {
exists(string qualifier, string name |
this.hasQualifiedName(qualifier, name) and result = getQualifiedName(qualifier, name)
)
}
}
/**

View File

@@ -201,6 +201,14 @@ predicate analyzerAssemblies(string key, float value) {
value = 1.0
}
predicate timingValues(string key, float value) {
exists(Compilation c |
key = "Total elapsed seconds" and value = c.getElapsedSeconds()
or
key = "Extractor elapsed seconds" and value = c.getExtractorElapsedSeconds()
)
}
from string key, float value
where
(
@@ -230,7 +238,8 @@ where
ExprStatsReport::numberOfOk(key, value) or
ExprStatsReport::numberOfNotOk(key, value) or
ExprStatsReport::percentageOfOk(key, value) or
analyzerAssemblies(key, value)
analyzerAssemblies(key, value) or
timingValues(key, value)
) and
/* Infinity */
value != 1.0 / 0.0 and

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* Deleted the deprecated `CsvRemoteSource` alias. Use `MaDRemoteSource` instead.

View File

@@ -39,6 +39,4 @@ module RemoteFlowSource {
class MaDRemoteSource extends Range {
MaDRemoteSource() { ExternalFlow::sourceNode(this, "remote") }
}
deprecated class CsvRemoteSource = MaDRemoteSource;
}

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* Deleted the deprecated `AssignLShiftExpr`, `AssignRShiftExpr`, `AssignURShiftExpr`, `LShiftExpr`, `RShiftExpr`, and `URShiftExpr` aliases.

View File

@@ -511,9 +511,6 @@ class AssignLeftShiftExpr extends AssignOp, @assignlshiftexpr {
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
}
/** DEPRECATED: Alias for AssignLeftShiftExpr. */
deprecated class AssignLShiftExpr = AssignLeftShiftExpr;
/** A compound assignment expression using the `>>=` operator. */
class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr {
override string getOp() { result = ">>=" }
@@ -521,9 +518,6 @@ class AssignRightShiftExpr extends AssignOp, @assignrshiftexpr {
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
}
/** DEPRECATED: Alias for AssignRightShiftExpr. */
deprecated class AssignRShiftExpr = AssignRightShiftExpr;
/** A compound assignment expression using the `>>>=` operator. */
class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr {
override string getOp() { result = ">>>=" }
@@ -531,9 +525,6 @@ class AssignUnsignedRightShiftExpr extends AssignOp, @assignurshiftexpr {
override string getAPrimaryQlClass() { result = "AssignUnsignedRightShiftExpr" }
}
/** DEPRECATED: Alias for AssignUnsignedRightShiftExpr. */
deprecated class AssignURShiftExpr = AssignUnsignedRightShiftExpr;
/** A common super-class to represent constant literals. */
class Literal extends Expr, @literal {
/**
@@ -793,9 +784,6 @@ class LeftShiftExpr extends BinaryExpr, @lshiftexpr {
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
}
/** DEPRECATED: Alias for LeftShiftExpr. */
deprecated class LShiftExpr = LeftShiftExpr;
/** A binary expression using the `>>` operator. */
class RightShiftExpr extends BinaryExpr, @rshiftexpr {
override string getOp() { result = " >> " }
@@ -803,9 +791,6 @@ class RightShiftExpr extends BinaryExpr, @rshiftexpr {
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
}
/** DEPRECATED: Alias for RightShiftExpr. */
deprecated class RShiftExpr = RightShiftExpr;
/** A binary expression using the `>>>` operator. */
class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr {
override string getOp() { result = " >>> " }
@@ -813,9 +798,6 @@ class UnsignedRightShiftExpr extends BinaryExpr, @urshiftexpr {
override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" }
}
/** DEPRECATED: Alias for UnsignedRightShiftExpr. */
deprecated class URShiftExpr = UnsignedRightShiftExpr;
/** A binary expression using the `&` operator. */
class AndBitwiseExpr extends BinaryExpr, @andbitexpr {
override string getOp() { result = " & " }

View File

@@ -1162,14 +1162,6 @@ module Impl implements RegexTreeViewSig {
root.getLiteral().isIgnoreCase()
}
/**
* Gets the flags for `root`, or the empty string if `root` has no flags.
*/
additional deprecated string getFlags(RegExpTerm root) {
root.isRootTerm() and
result = root.getLiteral().getFlags()
}
/**
* Holds if `root` has the `s` flag for multi-line matching.
*/

View File

@@ -0,0 +1,6 @@
---
category: breaking
---
* Deleted the deprecated `getInput` predicate from the `CryptographicOperation` class. Use `getAnInput` instead.
* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`.
* Deleted the deprecated `semmle/javascript/security/BadTagFilterQuery.qll`, `semmle/javascript/security/OverlyLargeRangeQuery.qll`, `semmle/javascript/security/regexp/RegexpMatching.qll`, and `Security/CWE-020/HostnameRegexpShared.qll` files.

View File

@@ -125,16 +125,7 @@ module Cryptography {
* extend `CryptographicOperation::Range` instead.
*/
class CryptographicOperation extends SC::CryptographicOperation instanceof CryptographicOperation::Range
{
/**
* DEPRECATED. This predicate has been renamed to `getAnInput`.
*
* To implement `CryptographicOperation`, please extend
* `CryptographicOperation::Range` and implement `getAnInput` instead of
* extending this class directly.
*/
deprecated final DataFlow::Node getInput() { result = this.getAnInput() }
}
{ }
class EncryptionAlgorithm = SC::EncryptionAlgorithm;

View File

@@ -1022,20 +1022,6 @@ predicate isInterpretedAsRegExp(DataFlow::Node source) {
)
}
/**
* Provides utility predicates related to regular expressions.
*/
deprecated module RegExpPatterns {
/**
* Gets a pattern that matches common top-level domain names in lower case.
* DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead.
*/
deprecated string getACommonTld() {
// according to ranking by http://google.com/search?q=site:.<<TLD>>
result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])"
}
}
/**
* Gets a node whose value may flow (inter-procedurally) to `re`, where it is interpreted
* as a part of a regular expression.

View File

@@ -1,8 +0,0 @@
/**
* Provides predicates for reasoning about bad tag filter vulnerabilities.
*/
private import regexp.RegExpTreeView::RegExpTreeView as TreeView
// BadTagFilterQuery should be used directly from the shared pack, and not from this file.
deprecated private import codeql.regex.nfa.BadTagFilterQuery::Make<TreeView> as Dep
import Dep

View File

@@ -1,8 +0,0 @@
/**
* Classes and predicates for working with suspicious character ranges.
*/
private import regexp.RegExpTreeView::RegExpTreeView as TreeView
// OverlyLargeRangeQuery should be used directly from the shared pack, and not from this file.
deprecated private import codeql.regex.OverlyLargeRangeQuery::Make<TreeView> as Dep
import Dep

View File

@@ -1,9 +0,0 @@
/**
* Provides predicates for reasoning about which strings are matched by a regular expression,
* and for testing which capture groups are filled when a particular regexp matches a string.
*/
private import RegExpTreeView::RegExpTreeView as TreeView
// RegexpMatching should be used directly from the shared pack, and not from this file.
deprecated private import codeql.regex.nfa.RegexpMatching::Make<TreeView> as Dep
import Dep

View File

@@ -1,7 +0,0 @@
/**
* Provides predicates for reasoning about regular expressions
* that match URLs and hostname patterns.
*/
deprecated import semmle.javascript.security.regexp.HostnameRegexp as Dep
import Dep

View File

@@ -0,0 +1,5 @@
---
category: breaking
---
* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`.
* Deleted the deprecated `Security/CWE-020/HostnameRegexpShared.qll` file.

View File

@@ -7,20 +7,6 @@ private import semmle.python.regex
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.regexp.internal.RegExpTracking
/**
* Provides utility predicates related to regular expressions.
*/
deprecated module RegExpPatterns {
/**
* Gets a pattern that matches common top-level domain names in lower case.
* DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead.
*/
deprecated string getACommonTld() {
// according to ranking by http://google.com/search?q=site:.<<TLD>>
result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])"
}
}
/**
* A node whose value may flow to a position where it is interpreted
* as a part of a regular expression.

View File

@@ -1,8 +0,0 @@
/**
* Provides predicates for reasoning about regular expressions
* that match URLs and hostname patterns.
*/
// HostnameRegexp should be used directly from the shared regex pack, and not from this file.
deprecated private import semmle.python.security.regexp.HostnameRegex as Dep
import Dep

View File

@@ -18,4 +18,7 @@ extensions:
- ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"]
- ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"]
- ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"]
- ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[self]", "ReturnValue.TupleElement[0]", "value"]
- ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"]
- ["foo", "Member[MS_Class].Instance.Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"]
- ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"]

View File

@@ -18,4 +18,7 @@ extensions:
- ["foo", "Member[MS_spread]", "Argument[0]", "ReturnValue.TupleElement[0]", "value"]
- ["foo", "Member[MS_spread]", "Argument[1]", "ReturnValue.TupleElement[1]", "value"]
- ["foo", "Member[MS_spread_all]", "Argument[0]", "ReturnValue.TupleElement[0,1]", "value"]
- ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[self]", "ReturnValue.TupleElement[0]", "value"]
- ["foo", "Member[MS_Class].Instance.Member[instance_method]", "Argument[0]", "ReturnValue.TupleElement[1]", "value"]
- ["foo", "Member[MS_Class].Instance.Member[explicit_self]", "Argument[self:]", "ReturnValue", "value"]
- ["json", "Member[MS_loads]", "Argument[0]", "ReturnValue", "taint"]

View File

@@ -122,6 +122,24 @@ a, b = MS_spread_all(SOURCE)
SINK(a) # $ flow="SOURCE, l:-1 -> a"
SINK(b) # $ flow="SOURCE, l:-2 -> b"
from foo import MS_Class
c = MS_Class()
a, b = c.instance_method(SOURCE)
SINK_F(a)
SINK(b) # $ flow="SOURCE, l:-2 -> b"
# Call the instance method on the class to expose the self argument
x, y = MS_Class.instance_method(SOURCE, NONSOURCE)
SINK(x) # $ MISSING: flow="SOURCE, l:-1 -> x"
SINK_F(y)
# Call the instance method on the class to expose the self argument
# That self argument is not referenced by `Argument[self:]`
SINK_F(MS_Class.explicit_self(SOURCE))
# Instead, `Argument[self:]` refers to a keyword argument named `self` (which you are allowed to do in Python)
SINK(c.explicit_self(self = SOURCE)) # $ flow="SOURCE -> c.explicit_self(..)"
# Modeled flow-summary is not value preserving
from json import MS_loads as json_loads

View File

@@ -0,0 +1,5 @@
---
category: breaking
---
* Deleted the deprecated `RegExpPatterns` module from `Regexp.qll`.
* Deleted the deprecated `security/cwe-020/HostnameRegexpShared.qll` file.

View File

@@ -14,20 +14,6 @@ private import codeql.ruby.DataFlow
private import codeql.ruby.ApiGraphs
private import codeql.ruby.Concepts
/**
* Provides utility predicates related to regular expressions.
*/
deprecated module RegExpPatterns {
/**
* Gets a pattern that matches common top-level domain names in lower case.
* DEPRECATED: use the similarly named predicate from `HostnameRegex` from the `regex` pack instead.
*/
deprecated string getACommonTld() {
// according to ranking by http://google.com/search?q=site:.<<TLD>>
result = "(?:com|org|edu|gov|uk|net|io)(?![a-z0-9])"
}
}
/**
* A node whose value may flow to a position where it is interpreted
* as a part of a regular expression.
@@ -122,7 +108,9 @@ class StdLibRegExpInterpretation extends RegExpInterpretation::Range {
mce.getMethodName() = ["match", "match?"] and
this = mce.getArgument(0) and
// exclude https://ruby-doc.org/core-2.4.0/Regexp.html#method-i-match
not mce.getReceiver() = RegExpTracking::trackRegexpType()
not mce.getReceiver() = RegExpTracking::trackRegexpType() and
// exclude non-stdlib methods
not exists(mce.getATarget())
)
}
}

View File

@@ -1,8 +0,0 @@
/**
* Provides predicates for reasoning about regular expressions
* that match URLs and hostname patterns.
*/
// HostnameRegexp should be used directly from the shared regex pack, and not from this file.
deprecated import codeql.ruby.security.regexp.HostnameRegexp as Dep
import Dep

View File

@@ -1,6 +1,9 @@
class UsersController < ActionController::Base
def create
filename = params[:filename]
File.open(filename)
end
def create
filename = params[:filename]
File.open(filename)
web_page = params[:web_page]
Net::HTTP.get(URI.parse(web_page))
end
end

View File

@@ -1,6 +1,11 @@
require "open-uri"
class UsersController < ActionController::Base
def create
filename = params[:filename]
open(filename) # BAD
web_page = params[:web_page]
URI.open(web_page) # BAD - calls `Kernel.open` internally
end
end

View File

@@ -28,3 +28,4 @@
| tst-IncompleteHostnameRegExp.rb:48:42:48:67 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unescaped '.' before 'example\\.com/', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:48:13:48:69 | ... + ... | here |
| tst-IncompleteHostnameRegExp.rb:48:42:48:67 | ^https?://.+.example\\.com/ | This string, which is used as a regular expression $@, has an unrestricted wildcard '.+' which may cause 'example\\.com/' to be matched anywhere in the URL, outside the hostname. | tst-IncompleteHostnameRegExp.rb:48:13:48:69 | ... + ... | here |
| tst-IncompleteHostnameRegExp.rb:59:5:59:20 | foo.example\\.com | This regular expression has an unescaped '.' before 'example\\.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:59:2:59:32 | /^(foo.example\\.com\|whatever)$/ | here |
| tst-IncompleteHostnameRegExp.rb:81:11:81:34 | ^http://test.example.com | This string, which is used as a regular expression $@, has an unescaped '.' before 'example.com', so it might match more hosts than expected. | tst-IncompleteHostnameRegExp.rb:77:22:77:22 | x | here |

View File

@@ -65,3 +65,17 @@ end
def convert2(domain)
return Regexp.new(domain[:hostname]);
end
class A
def self.match?(x) = true
end
A.match?("^http://test.example.com") # OK
class B
def self.match?(x)
some_string.match?(x)
end
end
B.match?("^http://test.example.com") # NOT OK

View File

@@ -1119,9 +1119,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
pragma[nomagic]
private SndLevelScopeOption getScope(RetNodeEx ret) {
result = SndLevelScopeOption::some(getSecondLevelScope(ret.asNode()))
result = SndLevelScopeOption::some(getSecondLevelScopeCached(ret.asNode()))
or
result instanceof SndLevelScopeOption::None and not exists(getSecondLevelScope(ret.asNode()))
result instanceof SndLevelScopeOption::None and
not exists(getSecondLevelScopeCached(ret.asNode()))
}
pragma[nomagic]

View File

@@ -616,6 +616,9 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
cached
predicate forceCachingInSameStage() { any() }
cached
DataFlowSecondLevelScope getSecondLevelScopeCached(Node n) { result = getSecondLevelScope(n) }
cached
predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) }