Merge remote-tracking branch 'upstream/master' into csharp/unsafe-deserialization

This commit is contained in:
Tom Hvitved 2019-11-04 13:42:35 +01:00
Родитель 3f5ee5138b fa5388b5f3
Коммит fd63246f44
204 изменённых файлов: 4652 добавлений и 3600 удалений

Просмотреть файл

@ -1,4 +1,5 @@
{ "provide": [ "*/ql/src/qlpack.yml",
"*/upgrades/qlpack.yml",
"misc/legacy-support/*/qlpack.yml",
"misc/suite-helpers/qlpack.yml",
"codeql/.codeqlmanifest.json" ] }

Просмотреть файл

@ -39,6 +39,10 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
definition of `x` when `x` is a variable of pointer type. It no longer
considers deep paths such as `f(&x.myField)` to be definitions of `x`. These
changes are in line with the user expectations we've observed.
* The data-flow library now makes it easier to specify barriers/sanitizers
arising from guards by overriding the predicate
`isBarrierGuard`/`isSanitizerGuard` on data-flow and taint-tracking
configurations respectively.
* There is now a `DataFlow::localExprFlow` predicate and a
`TaintTracking::localExprTaint` predicate to make it easy to use the most
common case of local data flow and taint: from one `Expr` to another.

Просмотреть файл

@ -8,6 +8,7 @@ The following changes in version 1.23 affect C# analysis in all applications.
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Deserialized delegate (`cs/deserialized-delegate`) | security, external/cwe/cwe-502 | Finds unsafe deserialization of delegate types. |
| Deserialization of untrusted data (`cs/unsafe-deserialization-untrusted-input`) | security | Finds flow of untrusted input to calls to unsafe deserializers. |
| Unsafe year argument for 'DateTime' constructor (`cs/unsafe-year-construction`) | reliability, date-time | Finds incorrect manipulation of `DateTime` values, which could lead to invalid dates. |
| Unsafe deserializer (`cs/unsafe-deserialization`) | security | Finds calls to unsafe deserializers. |
@ -45,5 +46,6 @@ The following changes in version 1.23 affect C# analysis in all applications.
* There is now a `DataFlow::localExprFlow` predicate and a
`TaintTracking::localExprTaint` predicate to make it easy to use the most
common case of local data flow and taint: from one `Expr` to another.
* Data is now tracked through null-coalescing expressions (`??`).
## Changes to autobuilder

Просмотреть файл

@ -44,6 +44,7 @@
| Stored cross-site scripting (`js/stored-xss`) | Fewer false-positive results | The query now recognizes more sanitizers. |
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now treats responses from servers as untrusted. |
| Uncontrolled data used in path expression (`js/path-injection`) | Fewer false-positive results | This query now recognizes calls to Express `sendFile` as safe in some cases. |
| Unknown directive (`js/unknown-directive`) | Fewer false positive results | This query no longer flags uses of ":", which is sometimes used like a directive. |
## Changes to QL libraries

Просмотреть файл

@ -21,6 +21,7 @@ from Variable v
where
v.isStatic() and
v.hasDefinition() and
not v.isConstexpr() and
not exists(VariableAccess a | a.getTarget() = v) and
not v instanceof MemberVariable and
not declarationHasSideEffects(v) and

Просмотреть файл

@ -7,3 +7,15 @@
import cpp
import PrintAST
/**
* Temporarily tweak this class or make a copy to control which functions are
* printed.
*/
class Cfg extends PrintASTConfiguration {
/**
* TWEAK THIS PREDICATE AS NEEDED.
* Holds if the AST for `func` should be printed.
*/
override predicate shouldPrintFunction(Function func) { any() }
}

Просмотреть файл

@ -5,6 +5,8 @@
private import cpp
private import semmle.code.cpp.dataflow.internal.FlowVar
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.controlflow.Guards
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
cached
private newtype TNode =
@ -680,12 +682,16 @@ VariableAccess getAnAccessToAssignedVariable(Expr assign) {
*
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends Expr {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `branch`. */
abstract deprecated predicate checks(Expr e, boolean branch);
class BarrierGuard extends GuardCondition {
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
abstract predicate checks(Expr e, boolean b);
/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
final ExprNode getAGuardedNode() {
exists(GVN value, boolean branch |
result.getExpr() = value.getAnExpr() and
this.checks(value.getAnExpr(), branch) and
this.controls(result.getExpr().getBasicBlock(), branch)
)
}
}

Просмотреть файл

@ -37,7 +37,7 @@ private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
}
private predicate accessesVariable(CopyInstruction copy, Variable var) {
exists(VariableAddressInstruction va | va.getVariable().getAST() = var |
exists(VariableAddressInstruction va | va.getASTVariable() = var |
copy.(StoreInstruction).getDestinationAddress() = va
or
copy.(LoadInstruction).getSourceAddress() = va

Просмотреть файл

@ -5,6 +5,7 @@
private import cpp
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.controlflow.IRGuards
private import semmle.code.cpp.ir.ValueNumbering
/**
* A newtype wrapper to prevent accidental casts between `Node` and
@ -220,7 +221,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
/**
* A guard that validates some expression.
* A guard that validates some instruction.
*
* To use this in a configuration, extend the class and provide a
* characteristic predicate precisely specifying the guard, and override
@ -229,11 +230,15 @@ predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)
* It is important that all extending classes in scope are disjoint.
*/
class BarrierGuard extends IRGuardCondition {
/** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `b`. */
abstract deprecated predicate checks(Instruction e, boolean b);
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
abstract predicate checks(Instruction instr, boolean b);
/** Gets a node guarded by this guard. */
final Node getAGuardedNode() {
none() // stub
exists(ValueNumber value, boolean edge |
result.asInstruction() = value.getAnInstruction() and
this.checks(value.getAnInstruction(), edge) and
this.controls(result.asInstruction().getBlock(), edge)
)
}
}

Просмотреть файл

@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
TBufferMayMemoryAccess() or
TEscapedMemoryAccess() or
TEscapedMayMemoryAccess() or
TNonLocalMayMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
override string toString() { result = "escaped(may)" }
}
/**
* The operand or result may access all memory whose address has escaped, other than data on the
* stack frame of the current function.
*/
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
override string toString() { result = "nonlocal(may)" }
}
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.

Просмотреть файл

@ -57,6 +57,7 @@ private newtype TOpcode =
TUnmodeledDefinition() or
TUnmodeledUse() or
TAliasedDefinition() or
TAliasedUse() or
TPhi() or
TBuiltIn() or
TVarArgsStart() or
@ -393,6 +394,10 @@ module Opcode {
final override string toString() { result = "AliasedDefinition" }
}
class AliasedUse extends Opcode, TAliasedUse {
final override string toString() { result = "AliasedUse" }
}
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
}

Просмотреть файл

@ -50,7 +50,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -263,6 +264,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

Просмотреть файл

@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

Просмотреть файл

@ -45,6 +45,7 @@ private newtype TMemoryLocation =
languageType = type.getCanonicalLanguageType()
} or
TUnknownMemoryLocation(IRFunction irFunc) or
TUnknownNonLocalMemoryLocation(IRFunction irFunc) or
TUnknownVirtualVariable(IRFunction irFunc)
/**
@ -162,6 +163,26 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation {
final override string getUniqueId() { result = "{Unknown}" }
}
/**
* An access to memory that is not known to be confined to a specific `IRVariable`, but is known to
* not access memory on the current function's stack frame.
*/
class UnknownNonLocalMemoryLocation extends TUnknownNonLocalMemoryLocation, MemoryLocation {
IRFunction irFunc;
UnknownNonLocalMemoryLocation() { this = TUnknownNonLocalMemoryLocation(irFunc) }
final override string toString() { result = "{UnknownNonLocal}" }
final override VirtualVariable getVirtualVariable() { result = TUnknownVirtualVariable(irFunc) }
final override Language::LanguageType getType() {
result = any(IRUnknownType type).getCanonicalLanguageType()
}
final override string getUniqueId() { result = "{UnknownNonLocal}" }
}
/**
* An access to all aliased memory.
*/
@ -194,6 +215,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
def instanceof UnknownMemoryLocation and
result instanceof MayPartiallyOverlap
or
// An UnknownNonLocalMemoryLocation may partially overlap any location within the same virtual
// variable, except a local variable.
def.getVirtualVariable() = use.getVirtualVariable() and
def instanceof UnknownNonLocalMemoryLocation and
result instanceof MayPartiallyOverlap and
not use.(VariableMemoryLocation).getVariable() instanceof IRAutomaticVariable
or
exists(VariableMemoryLocation defVariableLocation |
defVariableLocation = def and
(
@ -202,6 +230,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
(use instanceof UnknownMemoryLocation or use instanceof UnknownVirtualVariable) and
result instanceof MayPartiallyOverlap
or
// A VariableMemoryLocation that is not a local variable may partially overlap an unknown
// non-local location within the same virtual variable.
def.getVirtualVariable() = use.getVirtualVariable() and
use instanceof UnknownNonLocalMemoryLocation and
result instanceof MayPartiallyOverlap and
not defVariableLocation.getVariable() instanceof IRAutomaticVariable
or
// A VariableMemoryLocation overlaps another location within the same variable based on the relationship
// of the two offset intervals.
exists(Overlap intervalOverlap |
@ -327,6 +362,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
or
kind instanceof EscapedMayMemoryAccess and
result = TUnknownMemoryLocation(instr.getEnclosingIRFunction())
or
kind instanceof NonLocalMayMemoryAccess and
result = TUnknownNonLocalMemoryLocation(instr.getEnclosingIRFunction())
)
)
}
@ -351,6 +389,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
or
kind instanceof EscapedMayMemoryAccess and
result = TUnknownMemoryLocation(operand.getEnclosingIRFunction())
or
kind instanceof NonLocalMayMemoryAccess and
result = TUnknownNonLocalMemoryLocation(operand.getEnclosingIRFunction())
)
)
}

Просмотреть файл

@ -50,7 +50,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -263,6 +264,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

Просмотреть файл

@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

Просмотреть файл

@ -26,6 +26,7 @@ newtype TInstructionTag =
UnmodeledDefinitionTag() or
UnmodeledUseTag() or
AliasedDefinitionTag() or
AliasedUseTag() or
SwitchBranchTag() or
CallTargetTag() or
CallTag() or
@ -118,6 +119,8 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = AliasedDefinitionTag() and result = "AliasedDef"
or
tag = AliasedUseTag() and result = "AliasedUse"
or
tag = SwitchBranchTag() and result = "SwitchBranch"
or
tag = CallTargetTag() and result = "CallTarget"

Просмотреть файл

@ -447,20 +447,26 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
}
override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) {
exists(Type operandType |
if hasSpecificReadSideEffect(any(Opcode::BufferReadSideEffect op))
then
result = getUnknownType() and
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
operandTag instanceof SideEffectOperandTag
or
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType() and
not operandType instanceof DerivedType and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
// not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
result = getTypeForPRValueOrUnknown(operandType)
)
else
exists(Type operandType |
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and
operandTag instanceof SideEffectOperandTag
or
tag instanceof OnlyInstructionTag and
operandType = arg.getType().getUnspecifiedType() and
not operandType instanceof DerivedType and
operandTag instanceof SideEffectOperandTag
|
// If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will
// not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`.
result = getTypeForPRValueOrUnknown(operandType)
)
}
predicate hasSpecificWriteSideEffect(Opcode op) {
@ -510,7 +516,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
)
or
not call.getTarget() instanceof SideEffectFunction and
op instanceof Opcode::IndirectReadSideEffect
op instanceof Opcode::BufferReadSideEffect
}
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {

Просмотреть файл

@ -96,6 +96,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
result = getInstruction(UnmodeledUseTag())
or
tag = UnmodeledUseTag() and
result = getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = getInstruction(ExitFunctionTag())
)
}
@ -167,6 +170,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
opcode instanceof Opcode::UnmodeledUse and
resultType = getVoidType()
or
tag = AliasedUseTag() and
opcode instanceof Opcode::AliasedUse and
resultType = getVoidType()
or
tag = ExitFunctionTag() and
opcode instanceof Opcode::ExitFunction and
resultType = getVoidType()
@ -187,6 +194,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
operandTag instanceof UnmodeledUseOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = ReturnTag() and
hasReturnValue() and
(
@ -203,6 +214,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
hasReturnValue() and
operandTag instanceof LoadOperandTag and
result = getTypeForPRValue(getReturnType())
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnknownType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {

Просмотреть файл

@ -50,7 +50,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -263,6 +264,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

Просмотреть файл

@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

Просмотреть файл

@ -80,7 +80,7 @@ private module RangeAnalysisCache {
cached
module RangeAnalysisPublic {
/**
* Holds if `b + delta` is a valid bound for `i`.
* Holds if `b + delta` is a valid bound for `i` and this is the best such delta.
* - `upper = true` : `i <= b + delta`
* - `upper = false` : `i >= b + delta`
*
@ -90,11 +90,12 @@ private module RangeAnalysisCache {
*/
cached
predicate boundedInstruction(Instruction i, Bound b, int delta, boolean upper, Reason reason) {
boundedInstruction(i, b, delta, upper, _, _, reason)
boundedInstruction(i, b, delta, upper, _, _, reason) and
bestInstructionBound(i, b, delta, upper)
}
/**
* Holds if `b + delta` is a valid bound for `op`.
* Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
* - `upper = true` : `op <= b + delta`
* - `upper = false` : `op >= b + delta`
*
@ -104,9 +105,8 @@ private module RangeAnalysisCache {
*/
cached
predicate boundedOperand(Operand op, Bound b, int delta, boolean upper, Reason reason) {
boundedNonPhiOperand(op, b, delta, upper, _, _, reason)
or
boundedPhiOperand(op, b, delta, upper, _, _, reason)
boundedOperandCand(op, b, delta, upper, reason) and
bestOperandBound(op, b, delta, upper)
}
}
@ -124,6 +124,43 @@ private module RangeAnalysisCache {
private import RangeAnalysisCache
import RangeAnalysisPublic
/**
* Holds if `b + delta` is a valid bound for `e` and this is the best such delta.
* - `upper = true` : `e <= b + delta`
* - `upper = false` : `e >= b + delta`
*/
private predicate bestInstructionBound(Instruction i, Bound b, int delta, boolean upper) {
delta = min(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = true
or
delta = max(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = false
}
/**
* Holds if `b + delta` is a valid bound for `op`.
* - `upper = true` : `op <= b + delta`
* - `upper = false` : `op >= b + delta`
*
* The reason for the bound is given by `reason` and may be either a condition
* or `NoReason` if the bound was proven directly without the use of a bounding
* condition.
*/
private predicate boundedOperandCand(Operand op, Bound b, int delta, boolean upper, Reason reason) {
boundedNonPhiOperand(op, b, delta, upper, _, _, reason)
or
boundedPhiOperand(op, b, delta, upper, _, _, reason)
}
/**
* Holds if `b + delta` is a valid bound for `op` and this is the best such delta.
* - `upper = true` : `op <= b + delta`
* - `upper = false` : `op >= b + delta`
*/
private predicate bestOperandBound(Operand op, Bound b, int delta, boolean upper) {
delta = min(int d | boundedOperandCand(op, b, d, upper, _)) and upper = true
or
delta = max(int d | boundedOperandCand(op, b, d, upper, _)) and upper = false
}
/**
* Gets a condition that tests whether `vn` equals `bound + delta`.
*

Просмотреть файл

@ -0,0 +1,68 @@
int source();
void sink(int);
bool guarded(int);
void bg_basic(int source) {
if (guarded(source)) {
sink(source); // no flow
} else {
sink(source); // flow
}
}
void bg_not(int source) {
if (!guarded(source)) {
sink(source); // flow
} else {
sink(source); // no flow
}
}
void bg_and(int source, bool arbitrary) {
if (guarded(source) && arbitrary) {
sink(source); // no flow
} else {
sink(source); // flow
}
}
void bg_or(int source, bool arbitrary) {
if (guarded(source) || arbitrary) {
sink(source); // flow
} else {
sink(source); // flow
}
}
void bg_return(int source) {
if (!guarded(source)) {
return;
}
sink(source); // no flow
}
struct XY {
int x, y;
};
void bg_stackstruct(XY s1, XY s2) {
s1.x = source();
if (guarded(s1.x)) {
sink(s1.x); // no flow
} else if (guarded(s1.y)) {
sink(s1.x); // flow
} else if (guarded(s2.y)) {
sink(s1.x); // flow
}
}
void bg_structptr(XY *p1, XY *p2) {
p1->x = source();
if (guarded(p1->x)) {
sink(p1->x); // no flow [FALSE POSITIVE in AST]
} else if (guarded(p1->y)) {
sink(p1->x); // flow [NOT DETECTED in IR]
} else if (guarded(p2->x)) {
sink(p1->x); // flow [NOT DETECTED in IR]
}
}

Просмотреть файл

@ -1,6 +1,20 @@
import cpp
import semmle.code.cpp.dataflow.DataFlow
/**
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
class TestBarrierGuard extends DataFlow::BarrierGuard {
TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" }
override predicate checks(Expr checked, boolean isTrue) {
checked = this.(FunctionCall).getArgument(0) and
isTrue = true
}
}
/** Common data flow configuration to be used by tests. */
class TestAllocationConfig extends DataFlow::Configuration {
TestAllocationConfig() { this = "TestAllocationConfig" }
@ -26,4 +40,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
}
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
}

Просмотреть файл

@ -1,5 +1,20 @@
import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
import semmle.code.cpp.ir.IR
/**
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
* S in `if (guarded(x)) S`.
*/
// This is tested in `BarrierGuard.cpp`.
class TestBarrierGuard extends DataFlow::BarrierGuard {
TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" }
override predicate checks(Instruction checked, boolean isTrue) {
checked = this.(CallInstruction).getPositionalArgument(0) and
isTrue = true
}
}
/** Common data flow configuration to be used by tests. */
class TestAllocationConfig extends DataFlow::Configuration {
@ -24,4 +39,6 @@ class TestAllocationConfig extends DataFlow::Configuration {
override predicate isBarrier(DataFlow::Node barrier) {
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
}
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
}

Просмотреть файл

@ -1,3 +1,13 @@
| BarrierGuard.cpp:9:10:9:15 | source | BarrierGuard.cpp:5:19:5:24 | source |
| BarrierGuard.cpp:15:10:15:15 | source | BarrierGuard.cpp:13:17:13:22 | source |
| BarrierGuard.cpp:25:10:25:15 | source | BarrierGuard.cpp:21:17:21:22 | source |
| BarrierGuard.cpp:31:10:31:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
| BarrierGuard.cpp:33:10:33:15 | source | BarrierGuard.cpp:29:16:29:21 | source |
| BarrierGuard.cpp:53:13:53:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
| BarrierGuard.cpp:55:13:55:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source |
| BarrierGuard.cpp:62:14:62:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| BarrierGuard.cpp:64:14:64:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| BarrierGuard.cpp:66:14:66:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source |
| acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source |
| clang.cpp:18:8:18:19 | sourceArray1 | clang.cpp:12:9:12:20 | sourceArray1 |
| clang.cpp:22:8:22:20 | & ... | clang.cpp:12:9:12:20 | sourceArray1 |

Просмотреть файл

@ -1,3 +1,6 @@
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:62:14:62:14 | AST only |
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:64:14:64:14 | AST only |
| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:66:14:66:14 | AST only |
| clang.cpp:12:9:12:20 | clang.cpp:22:8:22:20 | AST only |
| clang.cpp:28:27:28:32 | clang.cpp:29:27:29:28 | AST only |
| clang.cpp:28:27:28:32 | clang.cpp:30:27:30:34 | AST only |

Просмотреть файл

@ -1,3 +1,10 @@
| BarrierGuard.cpp:9:10:9:15 | Load: source | BarrierGuard.cpp:5:19:5:24 | InitializeParameter: source |
| BarrierGuard.cpp:15:10:15:15 | Load: source | BarrierGuard.cpp:13:17:13:22 | InitializeParameter: source |
| BarrierGuard.cpp:25:10:25:15 | Load: source | BarrierGuard.cpp:21:17:21:22 | InitializeParameter: source |
| BarrierGuard.cpp:31:10:31:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
| BarrierGuard.cpp:33:10:33:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source |
| BarrierGuard.cpp:53:13:53:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| BarrierGuard.cpp:55:13:55:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Convert: (int)... | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| acrossLinkTargets.cpp:12:8:12:8 | Load: x | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source |
| clang.cpp:18:8:18:19 | Convert: (const int *)... | clang.cpp:12:9:12:20 | InitializeParameter: sourceArray1 |

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -84,7 +84,8 @@ ssa.cpp:
# 13| r6_12(glval<int>) = VariableAddress[#return] :
# 13| v6_13(void) = ReturnValue : &:r6_12, m6_11
# 13| v6_14(void) = UnmodeledUse : mu*
# 13| v6_15(void) = ExitFunction :
# 13| v6_15(void) = AliasedUse : ~m6_0
# 13| v6_16(void) = ExitFunction :
# 31| int UnreachableViaGoto()
# 31| Block 0
@ -99,7 +100,8 @@ ssa.cpp:
# 31| r0_8(glval<int>) = VariableAddress[#return] :
# 31| v0_9(void) = ReturnValue : &:r0_8, m0_7
# 31| v0_10(void) = UnmodeledUse : mu*
# 31| v0_11(void) = ExitFunction :
# 31| v0_11(void) = AliasedUse : ~m0_1
# 31| v0_12(void) = ExitFunction :
# 38| int UnreachableIf(bool)
# 38| Block 0
@ -125,7 +127,8 @@ ssa.cpp:
# 38| r1_1(glval<int>) = VariableAddress[#return] :
# 38| v1_2(void) = ReturnValue : &:r1_1, m1_0
# 38| v1_3(void) = UnmodeledUse : mu*
# 38| v1_4(void) = ExitFunction :
# 38| v1_4(void) = AliasedUse : ~m0_1
# 38| v1_5(void) = ExitFunction :
# 42| Block 2
# 42| r2_0(glval<int>) = VariableAddress[x] :
@ -188,7 +191,8 @@ ssa.cpp:
# 59| r1_4(glval<int>) = VariableAddress[#return] :
# 59| v1_5(void) = ReturnValue : &:r1_4, m1_3
# 59| v1_6(void) = UnmodeledUse : mu*
# 59| v1_7(void) = ExitFunction :
# 59| v1_7(void) = AliasedUse : ~m0_1
# 59| v1_8(void) = ExitFunction :
# 59| Block 2
# 59| v2_0(void) = Unreached :
@ -219,7 +223,8 @@ ssa.cpp:
# 71| v2_0(void) = NoOp :
# 68| v2_1(void) = ReturnVoid :
# 68| v2_2(void) = UnmodeledUse : mu*
# 68| v2_3(void) = ExitFunction :
# 68| v2_3(void) = AliasedUse : ~m3_0
# 68| v2_4(void) = ExitFunction :
# 69| Block 3
# 69| m3_0(unknown) = Phi : from 0:~m0_1, from 1:~m1_7
@ -291,7 +296,8 @@ ssa.cpp:
# 89| v3_14(void) = NoOp :
# 75| v3_15(void) = ReturnVoid :
# 75| v3_16(void) = UnmodeledUse : mu*
# 75| v3_17(void) = ExitFunction :
# 75| v3_17(void) = AliasedUse : ~m0_1
# 75| v3_18(void) = ExitFunction :
# 91| void MustExactlyOverlap(Point)
# 91| Block 0
@ -307,7 +313,8 @@ ssa.cpp:
# 93| v0_9(void) = NoOp :
# 91| v0_10(void) = ReturnVoid :
# 91| v0_11(void) = UnmodeledUse : mu*
# 91| v0_12(void) = ExitFunction :
# 91| v0_12(void) = AliasedUse : ~m0_1
# 91| v0_13(void) = ExitFunction :
# 95| void MustExactlyOverlapEscaped(Point)
# 95| Block 0
@ -327,13 +334,14 @@ ssa.cpp:
# 97| v0_13(void) = Call : func:r0_10, 0:r0_12
# 97| m0_14(unknown) = ^CallSideEffect : ~m0_5
# 97| m0_15(unknown) = Chi : total:m0_5, partial:m0_14
# 97| v0_16(void) = ^IndirectReadSideEffect[0] : &:r0_12, ~m0_15
# 97| v0_16(void) = ^BufferReadSideEffect[0] : &:r0_12, ~m0_15
# 97| m0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_12
# 97| m0_18(unknown) = Chi : total:m0_15, partial:m0_17
# 98| v0_19(void) = NoOp :
# 95| v0_20(void) = ReturnVoid :
# 95| v0_21(void) = UnmodeledUse : mu*
# 95| v0_22(void) = ExitFunction :
# 95| v0_22(void) = AliasedUse : ~m0_15
# 95| v0_23(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point)
# 100| Block 0
@ -355,7 +363,8 @@ ssa.cpp:
# 103| v0_15(void) = NoOp :
# 100| v0_16(void) = ReturnVoid :
# 100| v0_17(void) = UnmodeledUse : mu*
# 100| v0_18(void) = ExitFunction :
# 100| v0_18(void) = AliasedUse : ~m0_1
# 100| v0_19(void) = ExitFunction :
# 105| void MustTotallyOverlapEscaped(Point)
# 105| Block 0
@ -381,13 +390,14 @@ ssa.cpp:
# 108| v0_19(void) = Call : func:r0_16, 0:r0_18
# 108| m0_20(unknown) = ^CallSideEffect : ~m0_5
# 108| m0_21(unknown) = Chi : total:m0_5, partial:m0_20
# 108| v0_22(void) = ^IndirectReadSideEffect[0] : &:r0_18, ~m0_21
# 108| v0_22(void) = ^BufferReadSideEffect[0] : &:r0_18, ~m0_21
# 108| m0_23(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_18
# 108| m0_24(unknown) = Chi : total:m0_21, partial:m0_23
# 109| v0_25(void) = NoOp :
# 105| v0_26(void) = ReturnVoid :
# 105| v0_27(void) = UnmodeledUse : mu*
# 105| v0_28(void) = ExitFunction :
# 105| v0_28(void) = AliasedUse : ~m0_21
# 105| v0_29(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int)
# 111| Block 0
@ -417,7 +427,8 @@ ssa.cpp:
# 114| v0_23(void) = NoOp :
# 111| v0_24(void) = ReturnVoid :
# 111| v0_25(void) = UnmodeledUse : mu*
# 111| v0_26(void) = ExitFunction :
# 111| v0_26(void) = AliasedUse : ~m0_1
# 111| v0_27(void) = ExitFunction :
# 116| void MayPartiallyOverlapEscaped(int, int)
# 116| Block 0
@ -451,13 +462,14 @@ ssa.cpp:
# 119| v0_27(void) = Call : func:r0_24, 0:r0_26
# 119| m0_28(unknown) = ^CallSideEffect : ~m0_19
# 119| m0_29(unknown) = Chi : total:m0_19, partial:m0_28
# 119| v0_30(void) = ^IndirectReadSideEffect[0] : &:r0_26, ~m0_29
# 119| v0_30(void) = ^BufferReadSideEffect[0] : &:r0_26, ~m0_29
# 119| m0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_26
# 119| m0_32(unknown) = Chi : total:m0_29, partial:m0_31
# 120| v0_33(void) = NoOp :
# 116| v0_34(void) = ReturnVoid :
# 116| v0_35(void) = UnmodeledUse : mu*
# 116| v0_36(void) = ExitFunction :
# 116| v0_36(void) = AliasedUse : ~m0_29
# 116| v0_37(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int)
# 122| Block 0
@ -519,7 +531,8 @@ ssa.cpp:
# 132| v3_11(void) = NoOp :
# 122| v3_12(void) = ReturnVoid :
# 122| v3_13(void) = UnmodeledUse : mu*
# 122| v3_14(void) = ExitFunction :
# 122| v3_14(void) = AliasedUse : ~m0_1
# 122| v3_15(void) = ExitFunction :
# 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int)
# 134| Block 0
@ -575,7 +588,8 @@ ssa.cpp:
# 143| v3_7(void) = NoOp :
# 134| v3_8(void) = ReturnVoid :
# 134| v3_9(void) = UnmodeledUse : mu*
# 134| v3_10(void) = ExitFunction :
# 134| v3_10(void) = AliasedUse : ~m0_1
# 134| v3_11(void) = ExitFunction :
# 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int)
# 145| Block 0
@ -629,7 +643,8 @@ ssa.cpp:
# 154| v3_5(void) = NoOp :
# 145| v3_6(void) = ReturnVoid :
# 145| v3_7(void) = UnmodeledUse : mu*
# 145| v3_8(void) = ExitFunction :
# 145| v3_8(void) = AliasedUse : ~m0_1
# 145| v3_9(void) = ExitFunction :
# 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int)
# 156| Block 0
@ -685,7 +700,8 @@ ssa.cpp:
# 165| v3_6(void) = NoOp :
# 156| v3_7(void) = ReturnVoid :
# 156| v3_8(void) = UnmodeledUse : mu*
# 156| v3_9(void) = ExitFunction :
# 156| v3_9(void) = AliasedUse : ~m0_1
# 156| v3_10(void) = ExitFunction :
# 171| void WrapperStruct(Wrapper)
# 171| Block 0
@ -719,7 +735,8 @@ ssa.cpp:
# 177| v0_27(void) = NoOp :
# 171| v0_28(void) = ReturnVoid :
# 171| v0_29(void) = UnmodeledUse : mu*
# 171| v0_30(void) = ExitFunction :
# 171| v0_30(void) = AliasedUse : ~m0_1
# 171| v0_31(void) = ExitFunction :
# 179| int AsmStmt(int*)
# 179| Block 0
@ -738,7 +755,8 @@ ssa.cpp:
# 179| r0_12(glval<int>) = VariableAddress[#return] :
# 179| v0_13(void) = ReturnValue : &:r0_12, m0_11
# 179| v0_14(void) = UnmodeledUse : mu*
# 179| v0_15(void) = ExitFunction :
# 179| v0_15(void) = AliasedUse : ~m0_6
# 179| v0_16(void) = ExitFunction :
# 184| void AsmStmtWithOutputs(unsigned int&, unsigned int&, unsigned int&, unsigned int&)
# 184| Block 0
@ -768,7 +786,8 @@ ssa.cpp:
# 192| v0_23(void) = NoOp :
# 184| v0_24(void) = ReturnVoid :
# 184| v0_25(void) = UnmodeledUse : mu*
# 184| v0_26(void) = ExitFunction :
# 184| v0_26(void) = AliasedUse : ~m0_22
# 184| v0_27(void) = ExitFunction :
# 198| int PureFunctions(char*, char*, int)
# 198| Block 0
@ -817,7 +836,8 @@ ssa.cpp:
# 198| r0_42(glval<int>) = VariableAddress[#return] :
# 198| v0_43(void) = ReturnValue : &:r0_42, m0_41
# 198| v0_44(void) = UnmodeledUse : mu*
# 198| v0_45(void) = ExitFunction :
# 198| v0_45(void) = AliasedUse : ~m0_1
# 198| v0_46(void) = ExitFunction :
# 207| int ModeledCallTarget(int)
# 207| Block 0
@ -847,4 +867,5 @@ ssa.cpp:
# 207| r0_23(glval<int>) = VariableAddress[#return] :
# 207| v0_24(void) = ReturnValue : &:r0_23, m0_22
# 207| v0_25(void) = UnmodeledUse : mu*
# 207| v0_26(void) = ExitFunction :
# 207| v0_26(void) = AliasedUse : ~m0_1
# 207| v0_27(void) = ExitFunction :

Просмотреть файл

@ -78,7 +78,8 @@ ssa.cpp:
# 13| r6_11(glval<int>) = VariableAddress[#return] :
# 13| v6_12(void) = ReturnValue : &:r6_11, m6_10
# 13| v6_13(void) = UnmodeledUse : mu*
# 13| v6_14(void) = ExitFunction :
# 13| v6_14(void) = AliasedUse : ~mu0_2
# 13| v6_15(void) = ExitFunction :
# 31| int UnreachableViaGoto()
# 31| Block 0
@ -93,7 +94,8 @@ ssa.cpp:
# 31| r0_8(glval<int>) = VariableAddress[#return] :
# 31| v0_9(void) = ReturnValue : &:r0_8, m0_7
# 31| v0_10(void) = UnmodeledUse : mu*
# 31| v0_11(void) = ExitFunction :
# 31| v0_11(void) = AliasedUse : ~mu0_2
# 31| v0_12(void) = ExitFunction :
# 38| int UnreachableIf(bool)
# 38| Block 0
@ -119,7 +121,8 @@ ssa.cpp:
# 38| r1_1(glval<int>) = VariableAddress[#return] :
# 38| v1_2(void) = ReturnValue : &:r1_1, m1_0
# 38| v1_3(void) = UnmodeledUse : mu*
# 38| v1_4(void) = ExitFunction :
# 38| v1_4(void) = AliasedUse : ~mu0_2
# 38| v1_5(void) = ExitFunction :
# 42| Block 2
# 42| r2_0(glval<int>) = VariableAddress[x] :
@ -191,7 +194,8 @@ ssa.cpp:
# 59| r1_4(glval<int>) = VariableAddress[#return] :
# 59| v1_5(void) = ReturnValue : &:r1_4, m1_3
# 59| v1_6(void) = UnmodeledUse : mu*
# 59| v1_7(void) = ExitFunction :
# 59| v1_7(void) = AliasedUse : ~mu0_2
# 59| v1_8(void) = ExitFunction :
# 59| Block 2
# 59| v2_0(void) = Unreached :
@ -221,7 +225,8 @@ ssa.cpp:
# 71| v2_0(void) = NoOp :
# 68| v2_1(void) = ReturnVoid :
# 68| v2_2(void) = UnmodeledUse : mu*
# 68| v2_3(void) = ExitFunction :
# 68| v2_3(void) = AliasedUse : ~mu0_2
# 68| v2_4(void) = ExitFunction :
# 69| Block 3
# 69| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6
@ -292,7 +297,8 @@ ssa.cpp:
# 89| v3_14(void) = NoOp :
# 75| v3_15(void) = ReturnVoid :
# 75| v3_16(void) = UnmodeledUse : mu*
# 75| v3_17(void) = ExitFunction :
# 75| v3_17(void) = AliasedUse : ~mu0_2
# 75| v3_18(void) = ExitFunction :
# 91| void MustExactlyOverlap(Point)
# 91| Block 0
@ -308,7 +314,8 @@ ssa.cpp:
# 93| v0_9(void) = NoOp :
# 91| v0_10(void) = ReturnVoid :
# 91| v0_11(void) = UnmodeledUse : mu*
# 91| v0_12(void) = ExitFunction :
# 91| v0_12(void) = AliasedUse : ~mu0_2
# 91| v0_13(void) = ExitFunction :
# 95| void MustExactlyOverlapEscaped(Point)
# 95| Block 0
@ -326,12 +333,13 @@ ssa.cpp:
# 97| r0_11(void *) = Convert : r0_10
# 97| v0_12(void) = Call : func:r0_9, 0:r0_11
# 97| mu0_13(unknown) = ^CallSideEffect : ~mu0_2
# 97| v0_14(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2
# 97| v0_14(void) = ^BufferReadSideEffect[0] : &:r0_11, ~mu0_2
# 97| mu0_15(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11
# 98| v0_16(void) = NoOp :
# 95| v0_17(void) = ReturnVoid :
# 95| v0_18(void) = UnmodeledUse : mu*
# 95| v0_19(void) = ExitFunction :
# 95| v0_19(void) = AliasedUse : ~mu0_2
# 95| v0_20(void) = ExitFunction :
# 100| void MustTotallyOverlap(Point)
# 100| Block 0
@ -353,7 +361,8 @@ ssa.cpp:
# 103| v0_15(void) = NoOp :
# 100| v0_16(void) = ReturnVoid :
# 100| v0_17(void) = UnmodeledUse : mu*
# 100| v0_18(void) = ExitFunction :
# 100| v0_18(void) = AliasedUse : ~mu0_2
# 100| v0_19(void) = ExitFunction :
# 105| void MustTotallyOverlapEscaped(Point)
# 105| Block 0
@ -377,12 +386,13 @@ ssa.cpp:
# 108| r0_17(void *) = Convert : r0_16
# 108| v0_18(void) = Call : func:r0_15, 0:r0_17
# 108| mu0_19(unknown) = ^CallSideEffect : ~mu0_2
# 108| v0_20(void) = ^IndirectReadSideEffect[0] : &:r0_17, ~mu0_2
# 108| v0_20(void) = ^BufferReadSideEffect[0] : &:r0_17, ~mu0_2
# 108| mu0_21(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_17
# 109| v0_22(void) = NoOp :
# 105| v0_23(void) = ReturnVoid :
# 105| v0_24(void) = UnmodeledUse : mu*
# 105| v0_25(void) = ExitFunction :
# 105| v0_25(void) = AliasedUse : ~mu0_2
# 105| v0_26(void) = ExitFunction :
# 111| void MayPartiallyOverlap(int, int)
# 111| Block 0
@ -410,7 +420,8 @@ ssa.cpp:
# 114| v0_21(void) = NoOp :
# 111| v0_22(void) = ReturnVoid :
# 111| v0_23(void) = UnmodeledUse : mu*
# 111| v0_24(void) = ExitFunction :
# 111| v0_24(void) = AliasedUse : ~mu0_2
# 111| v0_25(void) = ExitFunction :
# 116| void MayPartiallyOverlapEscaped(int, int)
# 116| Block 0
@ -440,12 +451,13 @@ ssa.cpp:
# 119| r0_23(void *) = Convert : r0_22
# 119| v0_24(void) = Call : func:r0_21, 0:r0_23
# 119| mu0_25(unknown) = ^CallSideEffect : ~mu0_2
# 119| v0_26(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2
# 119| v0_26(void) = ^BufferReadSideEffect[0] : &:r0_23, ~mu0_2
# 119| mu0_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23
# 120| v0_28(void) = NoOp :
# 116| v0_29(void) = ReturnVoid :
# 116| v0_30(void) = UnmodeledUse : mu*
# 116| v0_31(void) = ExitFunction :
# 116| v0_31(void) = AliasedUse : ~mu0_2
# 116| v0_32(void) = ExitFunction :
# 122| void MergeMustExactlyOverlap(bool, int, int)
# 122| Block 0
@ -501,7 +513,8 @@ ssa.cpp:
# 132| v3_9(void) = NoOp :
# 122| v3_10(void) = ReturnVoid :
# 122| v3_11(void) = UnmodeledUse : mu*
# 122| v3_12(void) = ExitFunction :
# 122| v3_12(void) = AliasedUse : ~mu0_2
# 122| v3_13(void) = ExitFunction :
# 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int)
# 134| Block 0
@ -552,7 +565,8 @@ ssa.cpp:
# 143| v3_5(void) = NoOp :
# 134| v3_6(void) = ReturnVoid :
# 134| v3_7(void) = UnmodeledUse : mu*
# 134| v3_8(void) = ExitFunction :
# 134| v3_8(void) = AliasedUse : ~mu0_2
# 134| v3_9(void) = ExitFunction :
# 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int)
# 145| Block 0
@ -602,7 +616,8 @@ ssa.cpp:
# 154| v3_4(void) = NoOp :
# 145| v3_5(void) = ReturnVoid :
# 145| v3_6(void) = UnmodeledUse : mu*
# 145| v3_7(void) = ExitFunction :
# 145| v3_7(void) = AliasedUse : ~mu0_2
# 145| v3_8(void) = ExitFunction :
# 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int)
# 156| Block 0
@ -654,7 +669,8 @@ ssa.cpp:
# 165| v3_5(void) = NoOp :
# 156| v3_6(void) = ReturnVoid :
# 156| v3_7(void) = UnmodeledUse : mu*
# 156| v3_8(void) = ExitFunction :
# 156| v3_8(void) = AliasedUse : ~mu0_2
# 156| v3_9(void) = ExitFunction :
# 171| void WrapperStruct(Wrapper)
# 171| Block 0
@ -688,7 +704,8 @@ ssa.cpp:
# 177| v0_27(void) = NoOp :
# 171| v0_28(void) = ReturnVoid :
# 171| v0_29(void) = UnmodeledUse : mu*
# 171| v0_30(void) = ExitFunction :
# 171| v0_30(void) = AliasedUse : ~mu0_2
# 171| v0_31(void) = ExitFunction :
# 179| int AsmStmt(int*)
# 179| Block 0
@ -706,7 +723,8 @@ ssa.cpp:
# 179| r0_11(glval<int>) = VariableAddress[#return] :
# 179| v0_12(void) = ReturnValue : &:r0_11, m0_10
# 179| v0_13(void) = UnmodeledUse : mu*
# 179| v0_14(void) = ExitFunction :
# 179| v0_14(void) = AliasedUse : ~mu0_2
# 179| v0_15(void) = ExitFunction :
# 184| void AsmStmtWithOutputs(unsigned int&, unsigned int&, unsigned int&, unsigned int&)
# 184| Block 0
@ -735,7 +753,8 @@ ssa.cpp:
# 192| v0_22(void) = NoOp :
# 184| v0_23(void) = ReturnVoid :
# 184| v0_24(void) = UnmodeledUse : mu*
# 184| v0_25(void) = ExitFunction :
# 184| v0_25(void) = AliasedUse : ~mu0_2
# 184| v0_26(void) = ExitFunction :
# 198| int PureFunctions(char*, char*, int)
# 198| Block 0
@ -784,7 +803,8 @@ ssa.cpp:
# 198| r0_42(glval<int>) = VariableAddress[#return] :
# 198| v0_43(void) = ReturnValue : &:r0_42, m0_41
# 198| v0_44(void) = UnmodeledUse : mu*
# 198| v0_45(void) = ExitFunction :
# 198| v0_45(void) = AliasedUse : ~mu0_2
# 198| v0_46(void) = ExitFunction :
# 207| int ModeledCallTarget(int)
# 207| Block 0
@ -811,4 +831,5 @@ ssa.cpp:
# 207| r0_20(glval<int>) = VariableAddress[#return] :
# 207| v0_21(void) = ReturnValue : &:r0_20, m0_19
# 207| v0_22(void) = UnmodeledUse : mu*
# 207| v0_23(void) = ExitFunction :
# 207| v0_23(void) = AliasedUse : ~mu0_2
# 207| v0_24(void) = ExitFunction :

Просмотреть файл

@ -51,7 +51,6 @@
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | false | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 |
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | false | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 |
| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | true | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 |
| test.cpp:169:12:169:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 |

Просмотреть файл

@ -11,13 +11,7 @@ query predicate instructionBounds(
or
exists(ReturnValueInstruction retInstr | retInstr.getReturnValueOperand() = i.getAUse())
) and
(
upper = true and
delta = min(int d | boundedInstruction(i, b, d, upper, reason))
or
upper = false and
delta = max(int d | boundedInstruction(i, b, d, upper, reason))
) and
boundedInstruction(i, b, delta, upper, reason) and
not valueNumber(b.getInstruction()) = valueNumber(i) and
if reason instanceof CondReason
then reasonLoc = reason.(CondReason).getCond().getLocation()

Просмотреть файл

@ -1,9 +1,9 @@
missingOperand
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | IR: misc3 | void misc3() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | allocators.cpp:14:5:14:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | no_dynamic_init.cpp:9:5:9:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | parameterinitializer.cpp:18:5:18:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | stream_it.cpp:16:5:16:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | BufferReadSideEffect: my_c | Instruction 'BufferReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | allocators.cpp:14:5:14:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | BufferReadSideEffect: my_c | Instruction 'BufferReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | no_dynamic_init.cpp:9:5:9:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | BufferReadSideEffect: my_c | Instruction 'BufferReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | parameterinitializer.cpp:18:5:18:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | BufferReadSideEffect: my_c | Instruction 'BufferReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | stream_it.cpp:16:5:16:8 | IR: main | int main() |
| try_catch.cpp:13:5:13:16 | ThrowValue: throw ... | Instruction 'ThrowValue' is missing an expected operand with tag 'Load' in function '$@'. | try_catch.cpp:11:6:11:17 | IR: bypass_catch | void bypass_catch() |
unexpectedOperand
duplicateOperand

Просмотреть файл

@ -610,89 +610,10 @@ lostReachability
| range_analysis.c:371:37:371:39 | Constant: 500 |
backEdgeCountMismatch
useNotDominatedByDefinition
| VacuousDestructorCall.cpp:4:3:4:3 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | IR: CallDestructor | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:15:16:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:16:15:16:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:16:15:16:16 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:17:5:17:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:17:11:17:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:20:5:20:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:20:11:20:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) |
| condition_decls.cpp:26:19:26:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:26:19:26:20 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:26:19:26:20 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:28:5:28:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:28:11:28:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:31:5:31:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:31:11:31:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:34:5:34:18 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:34:9:34:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) |
| condition_decls.cpp:41:18:41:18 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:41:18:41:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:41:18:41:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:42:5:42:7 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:44:3:44:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) |
| condition_decls.cpp:48:48:48:48 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:48:48:48:49 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:48:48:48:49 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:48:56:48:61 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:49:5:49:7 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| condition_decls.cpp:51:3:51:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) |
| cpp11.cpp:28:21:28:21 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | cpp11.cpp:27:7:27:14 | IR: getFirst | int range_based_for_11::getFirst() |
| file://:0:0:0:0 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | cpp11.cpp:27:7:27:14 | IR: getFirst | int range_based_for_11::getFirst() |
| misc.c:68:16:68:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:70:13:70:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:72:11:72:11 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:82:5:82:12 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:83:5:83:12 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:83:14:83:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:83:17:83:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:6:84:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:6:84:13 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:16:84:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:84:19:84:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:85:9:85:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:86:9:86:9 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:87:10:87:10 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:88:9:88:9 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:88:9:88:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) |
| misc.c:171:15:171:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:173:19:173:24 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:174:17:174:22 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:174:30:174:35 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() |
| misc.c:219:5:219:26 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) |
| misc.c:220:4:220:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) |
| ms_try_except.cpp:9:19:9:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | IR: ms_try_except | void ms_try_except(int) |
| ms_try_except.cpp:19:17:19:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | IR: ms_try_except | void ms_try_except(int) |
| ms_try_mix.cpp:14:16:14:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:15:13:15:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:16:13:16:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:18:16:18:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:21:16:21:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:24:12:24:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) |
| ms_try_mix.cpp:31:16:31:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:32:13:32:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:33:13:33:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:35:16:35:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:38:16:38:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:41:12:41:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) |
| ms_try_mix.cpp:51:5:51:11 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:47:6:47:28 | IR: ms_empty_finally_at_end | void ms_empty_finally_at_end() |
| pointer_to_member.cpp:36:11:36:30 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() |
| pointer_to_member.cpp:36:13:36:19 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() |
| pointer_to_member.cpp:36:22:36:28 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() |
| stmt_expr.cpp:30:20:30:21 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | stmt_expr.cpp:21:6:21:6 | IR: g | void stmtexpr::g(int) |
| stmt_expr.cpp:31:16:31:18 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | stmt_expr.cpp:21:6:21:6 | IR: g | void stmtexpr::g(int) |
| try_catch.cpp:21:13:21:24 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | IR: throw_from_nonstmt | void throw_from_nonstmt(int) |
| vla.c:3:5:3:8 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:16:5:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:22:5:25 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:27:5:30 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:5:27:5:33 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) |
| vla.c:12:37:12:42 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:12:55:12:60 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:14:40:14:45 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:14:58:14:63 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
| vla.c:14:74:14:79 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() |
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType

Просмотреть файл

@ -1,9 +1,5 @@
missingOperand
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | IR: misc3 | void misc3() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | allocators.cpp:14:5:14:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | no_dynamic_init.cpp:9:5:9:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | parameterinitializer.cpp:18:5:18:8 | IR: main | int main() |
| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | stream_it.cpp:16:5:16:8 | IR: main | int main() |
| try_catch.cpp:13:5:13:16 | ThrowValue: throw ... | Instruction 'ThrowValue' is missing an expected operand with tag 'Load' in function '$@'. | try_catch.cpp:11:6:11:17 | IR: bypass_catch | void bypass_catch() |
unexpectedOperand
duplicateOperand

Просмотреть файл

@ -67,7 +67,8 @@ test.cpp:
# 1| valnum = unique
# 1| v0_33(void) = ReturnValue : &:r0_32
# 1| v0_34(void) = UnmodeledUse : mu*
# 1| v0_35(void) = ExitFunction :
# 1| v0_35(void) = AliasedUse : ~m0_1
# 1| v0_36(void) = ExitFunction :
# 12| int test01(int, int)
# 12| Block 0
@ -149,7 +150,8 @@ test.cpp:
# 12| valnum = unique
# 12| v0_39(void) = ReturnValue : &:r0_38
# 12| v0_40(void) = UnmodeledUse : mu*
# 12| v0_41(void) = ExitFunction :
# 12| v0_41(void) = AliasedUse : ~m0_1
# 12| v0_42(void) = ExitFunction :
# 25| int test02(int, int)
# 25| Block 0
@ -238,7 +240,8 @@ test.cpp:
# 25| valnum = unique
# 25| v0_43(void) = ReturnValue : &:r0_42
# 25| v0_44(void) = UnmodeledUse : mu*
# 25| v0_45(void) = ExitFunction :
# 25| v0_45(void) = AliasedUse : ~m0_26
# 25| v0_46(void) = ExitFunction :
# 39| int test03(int, int, int*)
# 39| Block 0
@ -334,7 +337,8 @@ test.cpp:
# 39| valnum = unique
# 39| v0_46(void) = ReturnValue : &:r0_45
# 39| v0_47(void) = UnmodeledUse : mu*
# 39| v0_48(void) = ExitFunction :
# 39| v0_48(void) = AliasedUse : ~m0_29
# 39| v0_49(void) = ExitFunction :
# 49| unsigned int my_strspn(char const*, char const*)
# 49| Block 0
@ -496,7 +500,8 @@ test.cpp:
# 49| valnum = r9_1
# 49| v9_6(void) = ReturnValue : &:r9_5, m9_4
# 49| v9_7(void) = UnmodeledUse : mu*
# 49| v9_8(void) = ExitFunction :
# 49| v9_8(void) = AliasedUse : ~m0_1
# 49| v9_9(void) = ExitFunction :
# 75| void test04(two_values*)
# 75| Block 0
@ -575,10 +580,13 @@ test.cpp:
#-----| Goto -> Block 2
# 82| Block 2
# 82| v2_0(void) = NoOp :
# 75| v2_1(void) = ReturnVoid :
# 75| v2_2(void) = UnmodeledUse : mu*
# 75| v2_3(void) = ExitFunction :
# 82| m2_0(unknown) = Phi : from 0:~m0_9, from 1:~m1_3
# 82| valnum = unique
# 82| v2_1(void) = NoOp :
# 75| v2_2(void) = ReturnVoid :
# 75| v2_3(void) = UnmodeledUse : mu*
# 75| v2_4(void) = AliasedUse : ~m2_0
# 75| v2_5(void) = ExitFunction :
# 84| void test05(int, int, void*)
# 84| Block 0
@ -651,7 +659,8 @@ test.cpp:
# 89| v3_5(void) = NoOp :
# 84| v3_6(void) = ReturnVoid :
# 84| v3_7(void) = UnmodeledUse : mu*
# 84| v3_8(void) = ExitFunction :
# 84| v3_8(void) = AliasedUse : ~m0_1
# 84| v3_9(void) = ExitFunction :
# 91| int regression_test00()
# 91| Block 0
@ -682,7 +691,8 @@ test.cpp:
# 91| valnum = r0_8
# 91| v0_13(void) = ReturnValue : &:r0_12, m0_11
# 91| v0_14(void) = UnmodeledUse : mu*
# 91| v0_15(void) = ExitFunction :
# 91| v0_15(void) = AliasedUse : ~m0_1
# 91| v0_16(void) = ExitFunction :
# 104| int inheritanceConversions(Derived*)
# 104| Block 0
@ -743,7 +753,8 @@ test.cpp:
# 104| valnum = r0_23
# 104| v0_28(void) = ReturnValue : &:r0_27, m0_26
# 104| v0_29(void) = UnmodeledUse : mu*
# 104| v0_30(void) = ExitFunction :
# 104| v0_30(void) = AliasedUse : ~m0_1
# 104| v0_31(void) = ExitFunction :
# 112| void test06()
# 112| Block 0
@ -763,4 +774,5 @@ test.cpp:
# 117| v0_7(void) = NoOp :
# 112| v0_8(void) = ReturnVoid :
# 112| v0_9(void) = UnmodeledUse : mu*
# 112| v0_10(void) = ExitFunction :
# 112| v0_10(void) = AliasedUse : ~m0_1
# 112| v0_11(void) = ExitFunction :

2
cpp/upgrades/qlpack.yml Normal file
Просмотреть файл

@ -0,0 +1,2 @@
name: codeql-cpp-upgrades
upgrades: .

Просмотреть файл

@ -457,7 +457,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestCppAutobuilderSuccess()
{
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test.sln"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test.sln"] = 1;
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
@ -720,9 +720,9 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestWindowCSharpMsBuild()
{
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test1.sln"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test1.sln"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test2.sln"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test2.sln"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
@ -751,9 +751,9 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestWindowCSharpMsBuildMultipleSolutions()
{
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore test1.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test1.csproj"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore test2.csproj"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test2.csproj"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
@ -798,7 +798,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestWindowCSharpMsBuildFailed()
{
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test1.sln"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test1.sln"] = 0;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1;
Actions.FileExists["csharp.log"] = true;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
@ -902,7 +902,7 @@ namespace Semmle.Extraction.Tests
{
Actions.RunProcess["dotnet --list-sdks"] = 0;
Actions.RunProcessOut["dotnet --list-sdks"] = "2.1.2 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]";
Actions.RunProcess[@"curl -sO https://dot.net/v1/dotnet-install.sh"] = 0;
Actions.RunProcess[@"curl -L -sO https://dot.net/v1/dotnet-install.sh"] = 0;
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
Actions.RunProcess[@"rm dotnet-install.sh"] = 0;
@ -938,7 +938,7 @@ namespace Semmle.Extraction.Tests
{
Actions.RunProcess["dotnet --list-sdks"] = 0;
Actions.RunProcessOut["dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]";
Actions.RunProcess[@"curl -sO https://dot.net/v1/dotnet-install.sh"] = 0;
Actions.RunProcess[@"curl -L -sO https://dot.net/v1/dotnet-install.sh"] = 0;
Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0;
Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0;
Actions.RunProcess[@"rm dotnet-install.sh"] = 0;
@ -1006,7 +1006,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestDirsProjWindows()
{
Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore dirs.proj"] = 1;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore dirs.proj"] = 1;
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
@ -1049,7 +1049,7 @@ namespace Semmle.Extraction.Tests
[Fact]
public void TestDirsProjLinux()
{
Actions.RunProcess[@"mono C:\codeql\csharp/tools/nuget.exe restore dirs.proj"] = 1;
Actions.RunProcess[@"mono C:\odasa\tools/csharp/nuget/nuget.exe restore dirs.proj"] = 1;
Actions.RunProcess[@"C:\odasa/tools/odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0;
Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0;
Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0;

Просмотреть файл

@ -196,6 +196,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
{
var curl = new CommandBuilder(builder.Actions).
RunCommand("curl").
Argument("-L").
Argument("-sO").
Argument("https://dot.net/v1/dotnet-install.sh");

Просмотреть файл

@ -37,9 +37,9 @@ namespace Semmle.Autobuild
}
var nuget =
builder.CodeQLExtractorCSharpRoot != null ?
builder.Actions.PathCombine(builder.CodeQLExtractorCSharpRoot, "tools", "nuget.exe") :
builder.Actions.PathCombine(builder.SemmlePlatformTools, "csharp", "nuget", "nuget.exe");
builder.SemmlePlatformTools != null ?
builder.Actions.PathCombine(builder.SemmlePlatformTools, "csharp", "nuget", "nuget.exe") :
"nuget";
var ret = BuildScript.Success;

Просмотреть файл

@ -5,14 +5,11 @@
* @kind problem
* @id cs/deserialized-delegate
* @problem.severity warning
* @precision high
* @tags security
* external/cwe/cwe-502
*/
/*
* consider: @precision high
*/
import csharp
import semmle.code.csharp.frameworks.system.linq.Expressions
import semmle.code.csharp.serialization.Deserializers

Просмотреть файл

@ -86,6 +86,10 @@ module LocalFlow {
scope = e2 and
isSuccessor = true
or
e1 = e2.(NullCoalescingExpr).getAnOperand() and
scope = e2 and
isSuccessor = false
or
e1 = e2.(SuppressNullableWarningExpr).getExpr() and
scope = e2 and
isSuccessor = true

Просмотреть файл

@ -5,6 +5,7 @@ private newtype TMemoryAccessKind =
TBufferMayMemoryAccess() or
TEscapedMemoryAccess() or
TEscapedMayMemoryAccess() or
TNonLocalMayMemoryAccess() or
TPhiMemoryAccess() or
TUnmodeledMemoryAccess() or
TChiTotalMemoryAccess() or
@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess {
override string toString() { result = "escaped(may)" }
}
/**
* The operand or result may access all memory whose address has escaped, other than data on the
* stack frame of the current function.
*/
class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess {
override string toString() { result = "nonlocal(may)" }
}
/**
* The operand is a Phi operand, which accesses the same memory as its
* definition.

Просмотреть файл

@ -57,6 +57,7 @@ private newtype TOpcode =
TUnmodeledDefinition() or
TUnmodeledUse() or
TAliasedDefinition() or
TAliasedUse() or
TPhi() or
TBuiltIn() or
TVarArgsStart() or
@ -393,6 +394,10 @@ module Opcode {
final override string toString() { result = "AliasedDefinition" }
}
class AliasedUse extends Opcode, TAliasedUse {
final override string toString() { result = "AliasedUse" }
}
class Phi extends Opcode, TPhi {
final override string toString() { result = "Phi" }
}

Просмотреть файл

@ -50,7 +50,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -263,6 +264,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

Просмотреть файл

@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

Просмотреть файл

@ -32,6 +32,7 @@ newtype TInstructionTag =
UnmodeledDefinitionTag() or
UnmodeledUseTag() or
AliasedDefinitionTag() or
AliasedUseTag() or
SwitchBranchTag() or
CallTargetTag() or
CallTag() or
@ -131,6 +132,8 @@ string getInstructionTagId(TInstructionTag tag) {
or
tag = AliasedDefinitionTag() and result = "AliasedDef"
or
tag = AliasedUseTag() and result = "AliasedUse"
or
tag = SwitchBranchTag() and result = "SwitchBranch"
or
tag = CallTargetTag() and result = "CallTarget"

Просмотреть файл

@ -99,6 +99,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
result = this.getInstruction(UnmodeledUseTag())
or
tag = UnmodeledUseTag() and
result = getInstruction(AliasedUseTag())
or
tag = AliasedUseTag() and
result = this.getInstruction(ExitFunctionTag())
)
}
@ -172,6 +175,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
opcode instanceof Opcode::UnmodeledUse and
resultType = getVoidType()
or
tag = AliasedUseTag() and
opcode instanceof Opcode::AliasedUse and
resultType = getVoidType()
or
tag = ExitFunctionTag() and
opcode instanceof Opcode::ExitFunction and
resultType = getVoidType()
@ -192,6 +199,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
operandTag instanceof UnmodeledUseOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnmodeledDefinitionInstruction()
or
tag = ReturnTag() and
not this.getReturnType() instanceof VoidType and
(
@ -208,6 +219,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
not this.getReturnType() instanceof VoidType and
operandTag instanceof LoadOperandTag and
result = getTypeForPRValue(this.getReturnType())
or
tag = AliasedUseTag() and
operandTag instanceof SideEffectOperandTag and
result = getUnknownType()
}
final override IRVariable getInstructionVariable(InstructionTag tag) {

Просмотреть файл

@ -50,7 +50,8 @@ module InstructionSanity {
(
opcode instanceof ReadSideEffectOpcode or
opcode instanceof Opcode::InlineAsm or
opcode instanceof Opcode::CallSideEffect
opcode instanceof Opcode::CallSideEffect or
opcode instanceof Opcode::AliasedUse
) and
tag instanceof SideEffectOperandTag
)
@ -263,6 +264,7 @@ module InstructionSanity {
) {
exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex |
not useOperand.getUse() instanceof UnmodeledUseInstruction and
not defInstr instanceof UnmodeledDefinitionInstruction and
pointOfEvaluation(useOperand, useBlock, useIndex) and
defInstr = useOperand.getAnyDef() and
(
@ -1421,6 +1423,13 @@ class AliasedDefinitionInstruction extends Instruction {
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
}
/**
* An instruction that consumes all escaped memory on exit from the function.
*/
class AliasedUseInstruction extends Instruction {
AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse }
}
class UnmodeledUseInstruction extends Instruction {
UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse }

Просмотреть файл

@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand {
override SideEffectOperandTag tag;
override MemoryAccessKind getMemoryAccess() {
useInstr instanceof AliasedUseInstruction and
result instanceof NonLocalMayMemoryAccess
or
useInstr instanceof CallSideEffectInstruction and
result instanceof EscapedMayMemoryAccess
or

Просмотреть файл

@ -12,6 +12,8 @@
| dataflow.cs:46:35:46:39 | "t1b" | dataflow.cs:46:18:46:40 | call to method Taint1 |
| dataflow.cs:49:35:49:38 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
| dataflow.cs:49:41:49:44 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:108:20:108:33 | call to method IndirectNull |
| dataflow.cs:109:23:109:26 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
| dataflow.cs:109:23:109:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |

Просмотреть файл

@ -8,7 +8,9 @@
| LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 |
| LocalDataFlow.cs:420:19:420:24 | access to local variable sink71 |
| LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 |
| LocalDataFlow.cs:466:15:466:21 | access to parameter tainted |
| LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 |
| LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 |
| LocalDataFlow.cs:472:15:472:21 | access to parameter tainted |
| SSA.cs:9:15:9:22 | access to local variable ssaSink0 |
| SSA.cs:25:15:25:22 | access to local variable ssaSink1 |
| SSA.cs:43:15:43:22 | access to local variable ssaSink2 |

Просмотреть файл

@ -545,7 +545,10 @@
| LocalDataFlow.cs:408:15:408:22 | access to local variable nonSink0 | LocalDataFlow.cs:415:31:415:38 | access to local variable nonSink0 |
| LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 |
| LocalDataFlow.cs:411:22:411:34 | ... = ... | LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) |
| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 |
| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 |
| LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | ... = ... |
| LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) |
| LocalDataFlow.cs:412:15:412:20 | [post] access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 |
| LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 |
| LocalDataFlow.cs:415:9:415:38 | SSA def(nonSink0) | LocalDataFlow.cs:416:15:416:22 | access to local variable nonSink0 |
@ -562,12 +565,23 @@
| LocalDataFlow.cs:427:17:427:22 | access to local variable sink70 | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) |
| LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 |
| LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) |
| LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 |
| LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 |
| LocalDataFlow.cs:458:28:458:30 | this | LocalDataFlow.cs:458:41:458:45 | this access |
| LocalDataFlow.cs:458:50:458:52 | this | LocalDataFlow.cs:458:56:458:60 | this access |
| LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value |
| LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted |
| LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted |
| LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) | LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 |
| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... |
| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 |
| LocalDataFlow.cs:443:22:443:38 | ... ?? ... | LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) |
| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... |
| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 |
| LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) | LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 |
| LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... |
| LocalDataFlow.cs:444:22:444:38 | ... ?? ... | LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) |
| LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... |
| LocalDataFlow.cs:464:28:464:30 | this | LocalDataFlow.cs:464:41:464:45 | this access |
| LocalDataFlow.cs:464:50:464:52 | this | LocalDataFlow.cs:464:56:464:60 | this access |
| LocalDataFlow.cs:464:50:464:52 | value | LocalDataFlow.cs:464:64:464:68 | access to parameter value |
| LocalDataFlow.cs:470:41:470:47 | tainted | LocalDataFlow.cs:472:15:472:21 | access to parameter tainted |
| LocalDataFlow.cs:475:44:475:53 | nonTainted | LocalDataFlow.cs:477:15:477:24 | access to parameter nonTainted |
| SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S |
| SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access |
| SSA.cs:5:26:5:32 | tainted | SSA.cs:8:24:8:30 | access to parameter tainted |

Просмотреть файл

@ -438,6 +438,12 @@ public class LocalDataFlow
Check(nonSink17);
break;
}
// Null-coalescing expressions
var sink73 = nonSink0 ?? sink0;
var sink74 = sink0 ?? nonSink0;
Check(sink73);
Check(sink74);
}
static void Check<T>(T x) { }

Просмотреть файл

@ -62,7 +62,9 @@
| LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 |
| LocalDataFlow.cs:420:19:420:24 | access to local variable sink71 |
| LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 |
| LocalDataFlow.cs:466:15:466:21 | access to parameter tainted |
| LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 |
| LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 |
| LocalDataFlow.cs:472:15:472:21 | access to parameter tainted |
| SSA.cs:9:15:9:22 | access to local variable ssaSink0 |
| SSA.cs:25:15:25:22 | access to local variable ssaSink1 |
| SSA.cs:43:15:43:22 | access to local variable ssaSink2 |

Просмотреть файл

@ -690,7 +690,10 @@
| LocalDataFlow.cs:408:15:408:22 | access to local variable nonSink0 | LocalDataFlow.cs:415:31:415:38 | access to local variable nonSink0 |
| LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 |
| LocalDataFlow.cs:411:22:411:34 | ... = ... | LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) |
| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 |
| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 |
| LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | ... = ... |
| LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) |
| LocalDataFlow.cs:412:15:412:20 | [post] access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 |
| LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 |
| LocalDataFlow.cs:415:9:415:38 | SSA def(nonSink0) | LocalDataFlow.cs:416:15:416:22 | access to local variable nonSink0 |
@ -707,15 +710,26 @@
| LocalDataFlow.cs:427:17:427:22 | access to local variable sink70 | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) |
| LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 |
| LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) |
| LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 |
| LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 |
| LocalDataFlow.cs:458:28:458:30 | this | LocalDataFlow.cs:458:41:458:45 | this access |
| LocalDataFlow.cs:458:50:458:52 | this | LocalDataFlow.cs:458:56:458:60 | this access |
| LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:50:458:52 | value |
| LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value |
| LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:464:41:464:47 | tainted |
| LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted |
| LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:469:44:469:53 | nonTainted |
| LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted |
| LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) | LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 |
| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... |
| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 |
| LocalDataFlow.cs:443:22:443:38 | ... ?? ... | LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) |
| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... |
| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 |
| LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) | LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 |
| LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... |
| LocalDataFlow.cs:444:22:444:38 | ... ?? ... | LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) |
| LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... |
| LocalDataFlow.cs:464:28:464:30 | this | LocalDataFlow.cs:464:41:464:45 | this access |
| LocalDataFlow.cs:464:50:464:52 | this | LocalDataFlow.cs:464:56:464:60 | this access |
| LocalDataFlow.cs:464:50:464:52 | value | LocalDataFlow.cs:464:50:464:52 | value |
| LocalDataFlow.cs:464:50:464:52 | value | LocalDataFlow.cs:464:64:464:68 | access to parameter value |
| LocalDataFlow.cs:470:41:470:47 | tainted | LocalDataFlow.cs:470:41:470:47 | tainted |
| LocalDataFlow.cs:470:41:470:47 | tainted | LocalDataFlow.cs:472:15:472:21 | access to parameter tainted |
| LocalDataFlow.cs:475:44:475:53 | nonTainted | LocalDataFlow.cs:475:44:475:53 | nonTainted |
| LocalDataFlow.cs:475:44:475:53 | nonTainted | LocalDataFlow.cs:477:15:477:24 | access to parameter nonTainted |
| SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S |
| SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access |
| SSA.cs:5:26:5:32 | tainted | SSA.cs:5:26:5:32 | tainted |

Просмотреть файл

@ -53,7 +53,8 @@ array.cs:
# 10| mu0_49(Int32) = Store : &:r0_48, r0_43
# 2| v0_50(Void) = ReturnVoid :
# 2| v0_51(Void) = UnmodeledUse : mu*
# 2| v0_52(Void) = ExitFunction :
# 2| v0_52(Void) = AliasedUse : ~mu0_2
# 2| v0_53(Void) = ExitFunction :
# 13| System.Void ArrayTest.twod_and_init_acc()
# 13| Block 0
@ -144,7 +145,8 @@ array.cs:
# 20| mu0_84(Int32) = Store : &:r0_83, r0_76
# 13| v0_85(Void) = ReturnVoid :
# 13| v0_86(Void) = UnmodeledUse : mu*
# 13| v0_87(Void) = ExitFunction :
# 13| v0_87(Void) = AliasedUse : ~mu0_2
# 13| v0_88(Void) = ExitFunction :
assignop.cs:
# 4| System.Void AssignOp.Main()
@ -215,7 +217,8 @@ assignop.cs:
# 17| mu0_63(Int32) = Store : &:r0_60, r0_62
# 4| v0_64(Void) = ReturnVoid :
# 4| v0_65(Void) = UnmodeledUse : mu*
# 4| v0_66(Void) = ExitFunction :
# 4| v0_66(Void) = AliasedUse : ~mu0_2
# 4| v0_67(Void) = ExitFunction :
casts.cs:
# 11| System.Void Casts.Main()
@ -241,7 +244,8 @@ casts.cs:
# 15| mu0_18(Casts_B) = Store : &:r0_14, r0_17
# 11| v0_19(Void) = ReturnVoid :
# 11| v0_20(Void) = UnmodeledUse : mu*
# 11| v0_21(Void) = ExitFunction :
# 11| v0_21(Void) = AliasedUse : ~mu0_2
# 11| v0_22(Void) = ExitFunction :
collections.cs:
# 11| System.Void Collections.Main()
@ -285,7 +289,8 @@ collections.cs:
# 13| mu0_36(Dictionary<Int32,MyClass>) = Store : &:r0_3, r0_4
# 11| v0_37(Void) = ReturnVoid :
# 11| v0_38(Void) = UnmodeledUse : mu*
# 11| v0_39(Void) = ExitFunction :
# 11| v0_39(Void) = AliasedUse : ~mu0_2
# 11| v0_40(Void) = ExitFunction :
constructor_init.cs:
# 5| System.Void BaseClass..ctor()
@ -297,7 +302,8 @@ constructor_init.cs:
# 6| v0_4(Void) = NoOp :
# 5| v0_5(Void) = ReturnVoid :
# 5| v0_6(Void) = UnmodeledUse : mu*
# 5| v0_7(Void) = ExitFunction :
# 5| v0_7(Void) = AliasedUse : ~mu0_2
# 5| v0_8(Void) = ExitFunction :
# 9| System.Void BaseClass..ctor(System.Int32)
# 9| Block 0
@ -314,7 +320,8 @@ constructor_init.cs:
# 11| mu0_10(Int32) = Store : &:r0_9, r0_7
# 9| v0_11(Void) = ReturnVoid :
# 9| v0_12(Void) = UnmodeledUse : mu*
# 9| v0_13(Void) = ExitFunction :
# 9| v0_13(Void) = AliasedUse : ~mu0_2
# 9| v0_14(Void) = ExitFunction :
# 17| System.Void DerivedClass..ctor()
# 17| Block 0
@ -329,7 +336,8 @@ constructor_init.cs:
# 18| v0_8(Void) = NoOp :
# 17| v0_9(Void) = ReturnVoid :
# 17| v0_10(Void) = UnmodeledUse : mu*
# 17| v0_11(Void) = ExitFunction :
# 17| v0_11(Void) = AliasedUse : ~mu0_2
# 17| v0_12(Void) = ExitFunction :
# 21| System.Void DerivedClass..ctor(System.Int32)
# 21| Block 0
@ -348,7 +356,8 @@ constructor_init.cs:
# 22| v0_12(Void) = NoOp :
# 21| v0_13(Void) = ReturnVoid :
# 21| v0_14(Void) = UnmodeledUse : mu*
# 21| v0_15(Void) = ExitFunction :
# 21| v0_15(Void) = AliasedUse : ~mu0_2
# 21| v0_16(Void) = ExitFunction :
# 25| System.Void DerivedClass..ctor(System.Int32,System.Int32)
# 25| Block 0
@ -368,7 +377,8 @@ constructor_init.cs:
# 26| v0_13(Void) = NoOp :
# 25| v0_14(Void) = ReturnVoid :
# 25| v0_15(Void) = UnmodeledUse : mu*
# 25| v0_16(Void) = ExitFunction :
# 25| v0_16(Void) = AliasedUse : ~mu0_2
# 25| v0_17(Void) = ExitFunction :
# 29| System.Void DerivedClass.Main()
# 29| Block 0
@ -398,7 +408,8 @@ constructor_init.cs:
# 33| mu0_23(DerivedClass) = Store : &:r0_16, r0_17
# 29| v0_24(Void) = ReturnVoid :
# 29| v0_25(Void) = UnmodeledUse : mu*
# 29| v0_26(Void) = ExitFunction :
# 29| v0_26(Void) = AliasedUse : ~mu0_2
# 29| v0_27(Void) = ExitFunction :
crement.cs:
# 3| System.Void CrementOpsTest.Main()
@ -439,7 +450,8 @@ crement.cs:
# 9| mu0_33(Int32) = Store : &:r0_32, r0_28
# 3| v0_34(Void) = ReturnVoid :
# 3| v0_35(Void) = UnmodeledUse : mu*
# 3| v0_36(Void) = ExitFunction :
# 3| v0_36(Void) = AliasedUse : ~mu0_2
# 3| v0_37(Void) = ExitFunction :
delegates.cs:
# 6| System.Int32 Delegates.returns(System.Int32)
@ -456,7 +468,8 @@ delegates.cs:
# 6| r0_9(glval<Int32>) = VariableAddress[#return] :
# 6| v0_10(Void) = ReturnValue : &:r0_9, ~mu0_2
# 6| v0_11(Void) = UnmodeledUse : mu*
# 6| v0_12(Void) = ExitFunction :
# 6| v0_12(Void) = AliasedUse : ~mu0_2
# 6| v0_13(Void) = ExitFunction :
# 11| System.Void Delegates.Main()
# 11| Block 0
@ -478,7 +491,8 @@ delegates.cs:
# 13| mu0_15(<unknown>) = ^CallSideEffect : ~mu0_2
# 11| v0_16(Void) = ReturnVoid :
# 11| v0_17(Void) = UnmodeledUse : mu*
# 11| v0_18(Void) = ExitFunction :
# 11| v0_18(Void) = AliasedUse : ~mu0_2
# 11| v0_19(Void) = ExitFunction :
events.cs:
# 8| System.Void Events..ctor()
@ -497,7 +511,8 @@ events.cs:
# 10| mu0_11(MyDel) = Store : &:r0_10, r0_4
# 8| v0_12(Void) = ReturnVoid :
# 8| v0_13(Void) = UnmodeledUse : mu*
# 8| v0_14(Void) = ExitFunction :
# 8| v0_14(Void) = AliasedUse : ~mu0_2
# 8| v0_15(Void) = ExitFunction :
# 13| System.Void Events.AddEvent()
# 13| Block 0
@ -514,7 +529,8 @@ events.cs:
# 15| mu0_10(<unknown>) = ^CallSideEffect : ~mu0_2
# 13| v0_11(Void) = ReturnVoid :
# 13| v0_12(Void) = UnmodeledUse : mu*
# 13| v0_13(Void) = ExitFunction :
# 13| v0_13(Void) = AliasedUse : ~mu0_2
# 13| v0_14(Void) = ExitFunction :
# 18| System.Void Events.RemoveEvent()
# 18| Block 0
@ -531,7 +547,8 @@ events.cs:
# 20| mu0_10(<unknown>) = ^CallSideEffect : ~mu0_2
# 18| v0_11(Void) = ReturnVoid :
# 18| v0_12(Void) = UnmodeledUse : mu*
# 18| v0_13(Void) = ExitFunction :
# 18| v0_13(Void) = AliasedUse : ~mu0_2
# 18| v0_14(Void) = ExitFunction :
# 23| System.String Events.Fun(System.String)
# 23| Block 0
@ -548,7 +565,8 @@ events.cs:
# 23| r0_10(glval<String>) = VariableAddress[#return] :
# 23| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2
# 23| v0_12(Void) = UnmodeledUse : mu*
# 23| v0_13(Void) = ExitFunction :
# 23| v0_13(Void) = AliasedUse : ~mu0_2
# 23| v0_14(Void) = ExitFunction :
# 28| System.Void Events.Main(System.String[])
# 28| Block 0
@ -583,7 +601,8 @@ events.cs:
# 33| mu0_28(<unknown>) = ^CallSideEffect : ~mu0_2
# 28| v0_29(Void) = ReturnVoid :
# 28| v0_30(Void) = UnmodeledUse : mu*
# 28| v0_31(Void) = ExitFunction :
# 28| v0_31(Void) = AliasedUse : ~mu0_2
# 28| v0_32(Void) = ExitFunction :
foreach.cs:
# 4| System.Void ForEach.Main()
@ -662,7 +681,8 @@ foreach.cs:
# 7| mu3_4(<unknown>) = ^CallSideEffect : ~mu0_2
# 4| v3_5(Void) = ReturnVoid :
# 4| v3_6(Void) = UnmodeledUse : mu*
# 4| v3_7(Void) = ExitFunction :
# 4| v3_7(Void) = AliasedUse : ~mu0_2
# 4| v3_8(Void) = ExitFunction :
func_with_param_call.cs:
# 5| System.Int32 test_call_with_param.f(System.Int32,System.Int32)
@ -684,7 +704,8 @@ func_with_param_call.cs:
# 5| r0_14(glval<Int32>) = VariableAddress[#return] :
# 5| v0_15(Void) = ReturnValue : &:r0_14, ~mu0_2
# 5| v0_16(Void) = UnmodeledUse : mu*
# 5| v0_17(Void) = ExitFunction :
# 5| v0_17(Void) = AliasedUse : ~mu0_2
# 5| v0_18(Void) = ExitFunction :
# 10| System.Int32 test_call_with_param.g()
# 10| Block 0
@ -701,7 +722,8 @@ func_with_param_call.cs:
# 10| r0_10(glval<Int32>) = VariableAddress[#return] :
# 10| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2
# 10| v0_12(Void) = UnmodeledUse : mu*
# 10| v0_13(Void) = ExitFunction :
# 10| v0_13(Void) = AliasedUse : ~mu0_2
# 10| v0_14(Void) = ExitFunction :
indexers.cs:
# 8| System.String Indexers.MyClass.get_Item(System.Int32)
@ -724,7 +746,8 @@ indexers.cs:
# 8| r0_15(glval<String>) = VariableAddress[#return] :
# 8| v0_16(Void) = ReturnValue : &:r0_15, ~mu0_2
# 8| v0_17(Void) = UnmodeledUse : mu*
# 8| v0_18(Void) = ExitFunction :
# 8| v0_18(Void) = AliasedUse : ~mu0_2
# 8| v0_19(Void) = ExitFunction :
# 12| System.Void Indexers.MyClass.set_Item(System.Int32,System.String)
# 12| Block 0
@ -747,7 +770,8 @@ indexers.cs:
# 14| mu0_16(String) = Store : &:r0_15, r0_9
# 12| v0_17(Void) = ReturnVoid :
# 12| v0_18(Void) = UnmodeledUse : mu*
# 12| v0_19(Void) = ExitFunction :
# 12| v0_19(Void) = AliasedUse : ~mu0_2
# 12| v0_20(Void) = ExitFunction :
# 19| System.Void Indexers.Main()
# 19| Block 0
@ -788,7 +812,8 @@ indexers.cs:
# 24| mu0_34(<unknown>) = ^CallSideEffect : ~mu0_2
# 19| v0_35(Void) = ReturnVoid :
# 19| v0_36(Void) = UnmodeledUse : mu*
# 19| v0_37(Void) = ExitFunction :
# 19| v0_37(Void) = AliasedUse : ~mu0_2
# 19| v0_38(Void) = ExitFunction :
inheritance_polymorphism.cs:
# 3| System.Int32 A.function()
@ -803,7 +828,8 @@ inheritance_polymorphism.cs:
# 3| r0_7(glval<Int32>) = VariableAddress[#return] :
# 3| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2
# 3| v0_9(Void) = UnmodeledUse : mu*
# 3| v0_10(Void) = ExitFunction :
# 3| v0_10(Void) = AliasedUse : ~mu0_2
# 3| v0_11(Void) = ExitFunction :
# 15| System.Int32 C.function()
# 15| Block 0
@ -817,7 +843,8 @@ inheritance_polymorphism.cs:
# 15| r0_7(glval<Int32>) = VariableAddress[#return] :
# 15| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2
# 15| v0_9(Void) = UnmodeledUse : mu*
# 15| v0_10(Void) = ExitFunction :
# 15| v0_10(Void) = AliasedUse : ~mu0_2
# 15| v0_11(Void) = ExitFunction :
# 23| System.Void Program.Main()
# 23| Block 0
@ -861,7 +888,8 @@ inheritance_polymorphism.cs:
# 34| mu0_37(<unknown>) = ^CallSideEffect : ~mu0_2
# 23| v0_38(Void) = ReturnVoid :
# 23| v0_39(Void) = UnmodeledUse : mu*
# 23| v0_40(Void) = ExitFunction :
# 23| v0_40(Void) = AliasedUse : ~mu0_2
# 23| v0_41(Void) = ExitFunction :
inoutref.cs:
# 11| System.Void InOutRef.set(MyClass,MyClass)
@ -880,7 +908,8 @@ inoutref.cs:
# 13| mu0_11(MyClass) = Store : &:r0_10, r0_8
# 11| v0_12(Void) = ReturnVoid :
# 11| v0_13(Void) = UnmodeledUse : mu*
# 11| v0_14(Void) = ExitFunction :
# 11| v0_14(Void) = AliasedUse : ~mu0_2
# 11| v0_15(Void) = ExitFunction :
# 16| System.Void InOutRef.F(System.Int32,MyStruct,MyStruct,MyClass,MyClass)
# 16| Block 0
@ -939,7 +968,8 @@ inoutref.cs:
# 26| mu0_52(<unknown>) = ^CallSideEffect : ~mu0_2
# 16| v0_53(Void) = ReturnVoid :
# 16| v0_54(Void) = UnmodeledUse : mu*
# 16| v0_55(Void) = ExitFunction :
# 16| v0_55(Void) = AliasedUse : ~mu0_2
# 16| v0_56(Void) = ExitFunction :
# 29| System.Void InOutRef.Main()
# 29| Block 0
@ -977,7 +1007,8 @@ inoutref.cs:
# 36| mu0_31(Int32) = Store : &:r0_27, r0_30
# 29| v0_32(Void) = ReturnVoid :
# 29| v0_33(Void) = UnmodeledUse : mu*
# 29| v0_34(Void) = ExitFunction :
# 29| v0_34(Void) = AliasedUse : ~mu0_2
# 29| v0_35(Void) = ExitFunction :
isexpr.cs:
# 8| System.Void IsExpr.Main()
@ -1008,7 +1039,8 @@ isexpr.cs:
# 8| Block 1
# 8| v1_0(Void) = ReturnVoid :
# 8| v1_1(Void) = UnmodeledUse : mu*
# 8| v1_2(Void) = ExitFunction :
# 8| v1_2(Void) = AliasedUse : ~mu0_2
# 8| v1_3(Void) = ExitFunction :
# 13| Block 2
# 13| v2_0(Void) = ConditionalBranch : r0_18
@ -1214,7 +1246,8 @@ jumps.cs:
# 38| mu22_4(<unknown>) = ^CallSideEffect : ~mu0_2
# 5| v22_5(Void) = ReturnVoid :
# 5| v22_6(Void) = UnmodeledUse : mu*
# 5| v22_7(Void) = ExitFunction :
# 5| v22_7(Void) = AliasedUse : ~mu0_2
# 5| v22_8(Void) = ExitFunction :
lock.cs:
# 5| System.Void LockTest.A()
@ -1258,7 +1291,8 @@ lock.cs:
# 5| Block 1
# 5| v1_0(Void) = ReturnVoid :
# 5| v1_1(Void) = UnmodeledUse : mu*
# 5| v1_2(Void) = ExitFunction :
# 5| v1_2(Void) = AliasedUse : ~mu0_2
# 5| v1_3(Void) = ExitFunction :
# 8| Block 2
# 8| r2_0(<funcaddr>) = FunctionAddress[Exit] :
@ -1278,7 +1312,8 @@ obj_creation.cs:
# 8| v0_4(Void) = NoOp :
# 7| v0_5(Void) = ReturnVoid :
# 7| v0_6(Void) = UnmodeledUse : mu*
# 7| v0_7(Void) = ExitFunction :
# 7| v0_7(Void) = AliasedUse : ~mu0_2
# 7| v0_8(Void) = ExitFunction :
# 11| System.Void ObjCreation.MyClass..ctor(System.Int32)
# 11| Block 0
@ -1295,7 +1330,8 @@ obj_creation.cs:
# 13| mu0_10(Int32) = Store : &:r0_9, r0_7
# 11| v0_11(Void) = ReturnVoid :
# 11| v0_12(Void) = UnmodeledUse : mu*
# 11| v0_13(Void) = ExitFunction :
# 11| v0_13(Void) = AliasedUse : ~mu0_2
# 11| v0_14(Void) = ExitFunction :
# 17| System.Void ObjCreation.SomeFun(ObjCreation.MyClass)
# 17| Block 0
@ -1307,7 +1343,8 @@ obj_creation.cs:
# 18| v0_5(Void) = NoOp :
# 17| v0_6(Void) = ReturnVoid :
# 17| v0_7(Void) = UnmodeledUse : mu*
# 17| v0_8(Void) = ExitFunction :
# 17| v0_8(Void) = AliasedUse : ~mu0_2
# 17| v0_9(Void) = ExitFunction :
# 21| System.Void ObjCreation.Main()
# 21| Block 0
@ -1346,7 +1383,8 @@ obj_creation.cs:
# 27| mu0_32(<unknown>) = ^CallSideEffect : ~mu0_2
# 21| v0_33(Void) = ReturnVoid :
# 21| v0_34(Void) = UnmodeledUse : mu*
# 21| v0_35(Void) = ExitFunction :
# 21| v0_35(Void) = AliasedUse : ~mu0_2
# 21| v0_36(Void) = ExitFunction :
pointers.cs:
# 3| System.Void Pointers.addone(System.Int32[])
@ -1380,7 +1418,8 @@ pointers.cs:
# 3| Block 1
# 3| v1_0(Void) = ReturnVoid :
# 3| v1_1(Void) = UnmodeledUse : mu*
# 3| v1_2(Void) = ExitFunction :
# 3| v1_2(Void) = AliasedUse : ~mu0_2
# 3| v1_3(Void) = ExitFunction :
# 9| Block 2
# 9| r2_0(glval<Int32>) = VariableAddress[i] :
@ -1475,7 +1514,8 @@ pointers.cs:
# 40| mu0_61(<unknown>) = ^CallSideEffect : ~mu0_2
# 25| v0_62(Void) = ReturnVoid :
# 25| v0_63(Void) = UnmodeledUse : mu*
# 25| v0_64(Void) = ExitFunction :
# 25| v0_64(Void) = AliasedUse : ~mu0_2
# 25| v0_65(Void) = ExitFunction :
prop.cs:
# 7| System.Int32 PropClass.get_Prop()
@ -1493,7 +1533,8 @@ prop.cs:
# 7| r0_10(glval<Int32>) = VariableAddress[#return] :
# 7| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2
# 7| v0_12(Void) = UnmodeledUse : mu*
# 7| v0_13(Void) = ExitFunction :
# 7| v0_13(Void) = AliasedUse : ~mu0_2
# 7| v0_14(Void) = ExitFunction :
# 12| System.Void PropClass.set_Prop(System.Int32)
# 12| Block 0
@ -1509,7 +1550,8 @@ prop.cs:
# 14| mu0_9(Int32) = Store : &:r0_8, r0_7
# 12| v0_10(Void) = ReturnVoid :
# 12| v0_11(Void) = UnmodeledUse : mu*
# 12| v0_12(Void) = ExitFunction :
# 12| v0_12(Void) = AliasedUse : ~mu0_2
# 12| v0_13(Void) = ExitFunction :
# 18| System.Int32 PropClass.func()
# 18| Block 0
@ -1523,7 +1565,8 @@ prop.cs:
# 18| r0_7(glval<Int32>) = VariableAddress[#return] :
# 18| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2
# 18| v0_9(Void) = UnmodeledUse : mu*
# 18| v0_10(Void) = ExitFunction :
# 18| v0_10(Void) = AliasedUse : ~mu0_2
# 18| v0_11(Void) = ExitFunction :
# 26| System.Void Prog.Main()
# 26| Block 0
@ -1551,7 +1594,8 @@ prop.cs:
# 30| mu0_21(Int32) = Store : &:r0_15, r0_19
# 26| v0_22(Void) = ReturnVoid :
# 26| v0_23(Void) = UnmodeledUse : mu*
# 26| v0_24(Void) = ExitFunction :
# 26| v0_24(Void) = AliasedUse : ~mu0_2
# 26| v0_25(Void) = ExitFunction :
simple_call.cs:
# 5| System.Int32 test_simple_call.f()
@ -1565,7 +1609,8 @@ simple_call.cs:
# 5| r0_6(glval<Int32>) = VariableAddress[#return] :
# 5| v0_7(Void) = ReturnValue : &:r0_6, ~mu0_2
# 5| v0_8(Void) = UnmodeledUse : mu*
# 5| v0_9(Void) = ExitFunction :
# 5| v0_9(Void) = AliasedUse : ~mu0_2
# 5| v0_10(Void) = ExitFunction :
# 10| System.Int32 test_simple_call.g()
# 10| Block 0
@ -1581,7 +1626,8 @@ simple_call.cs:
# 10| r0_9(glval<Int32>) = VariableAddress[#return] :
# 10| v0_10(Void) = ReturnValue : &:r0_9, ~mu0_2
# 10| v0_11(Void) = UnmodeledUse : mu*
# 10| v0_12(Void) = ExitFunction :
# 10| v0_12(Void) = AliasedUse : ~mu0_2
# 10| v0_13(Void) = ExitFunction :
simple_function.cs:
# 5| System.Int32 test_simple_function.f()
@ -1595,7 +1641,8 @@ simple_function.cs:
# 5| r0_6(glval<Int32>) = VariableAddress[#return] :
# 5| v0_7(Void) = ReturnValue : &:r0_6, ~mu0_2
# 5| v0_8(Void) = UnmodeledUse : mu*
# 5| v0_9(Void) = ExitFunction :
# 5| v0_9(Void) = AliasedUse : ~mu0_2
# 5| v0_10(Void) = ExitFunction :
stmts.cs:
# 5| System.Int32 test_stmts.ifStmt(System.Int32)
@ -1617,7 +1664,8 @@ stmts.cs:
# 5| r1_0(glval<Int32>) = VariableAddress[#return] :
# 5| v1_1(Void) = ReturnValue : &:r1_0, ~mu0_2
# 5| v1_2(Void) = UnmodeledUse : mu*
# 5| v1_3(Void) = ExitFunction :
# 5| v1_3(Void) = AliasedUse : ~mu0_2
# 5| v1_4(Void) = ExitFunction :
# 10| Block 2
# 10| r2_0(glval<Int32>) = VariableAddress[#return] :
@ -1646,7 +1694,8 @@ stmts.cs:
# 13| Block 1
# 13| v1_0(Void) = ReturnVoid :
# 13| v1_1(Void) = UnmodeledUse : mu*
# 13| v1_2(Void) = ExitFunction :
# 13| v1_2(Void) = AliasedUse : ~mu0_2
# 13| v1_3(Void) = ExitFunction :
# 16| Block 2
# 16| r2_0(glval<Int32>) = VariableAddress[i] :
@ -1693,7 +1742,8 @@ stmts.cs:
# 22| r1_0(glval<Int32>) = VariableAddress[#return] :
# 22| v1_1(Void) = ReturnValue : &:r1_0, ~mu0_2
# 22| v1_2(Void) = UnmodeledUse : mu*
# 22| v1_3(Void) = ExitFunction :
# 22| v1_3(Void) = AliasedUse : ~mu0_2
# 22| v1_4(Void) = ExitFunction :
# 29| Block 2
# 29| v2_0(Void) = NoOp :
@ -1750,7 +1800,8 @@ stmts.cs:
# 46| Block 1
# 46| v1_0(Void) = UnmodeledUse : mu*
# 46| v1_1(Void) = ExitFunction :
# 46| v1_1(Void) = AliasedUse : ~mu0_2
# 46| v1_2(Void) = ExitFunction :
# 46| Block 2
# 46| v2_0(Void) = Unwind :
@ -1816,7 +1867,8 @@ stmts.cs:
# 69| Block 1
# 69| v1_0(Void) = ReturnVoid :
# 69| v1_1(Void) = UnmodeledUse : mu*
# 69| v1_2(Void) = ExitFunction :
# 69| v1_2(Void) = AliasedUse : ~mu0_2
# 69| v1_3(Void) = ExitFunction :
# 72| Block 2
# 72| r2_0(glval<Int32>) = VariableAddress[i] :
@ -1893,7 +1945,8 @@ stmts.cs:
# 89| Block 1
# 89| v1_0(Void) = ReturnVoid :
# 89| v1_1(Void) = UnmodeledUse : mu*
# 89| v1_2(Void) = ExitFunction :
# 89| v1_2(Void) = AliasedUse : ~mu0_2
# 89| v1_3(Void) = ExitFunction :
# 94| Block 2
# 94| r2_0(glval<Int32>) = VariableAddress[x] :
@ -1933,7 +1986,8 @@ stmts.cs:
# 108| mu0_18(Int32) = Store : &:r0_17, r0_16
# 99| v0_19(Void) = ReturnVoid :
# 99| v0_20(Void) = UnmodeledUse : mu*
# 99| v0_21(Void) = ExitFunction :
# 99| v0_21(Void) = AliasedUse : ~mu0_2
# 99| v0_22(Void) = ExitFunction :
using.cs:
# 7| System.Void UsingStmt.MyDisposable..ctor()
@ -1945,7 +1999,8 @@ using.cs:
# 7| v0_4(Void) = NoOp :
# 7| v0_5(Void) = ReturnVoid :
# 7| v0_6(Void) = UnmodeledUse : mu*
# 7| v0_7(Void) = ExitFunction :
# 7| v0_7(Void) = AliasedUse : ~mu0_2
# 7| v0_8(Void) = ExitFunction :
# 8| System.Void UsingStmt.MyDisposable.DoSomething()
# 8| Block 0
@ -1956,7 +2011,8 @@ using.cs:
# 8| v0_4(Void) = NoOp :
# 8| v0_5(Void) = ReturnVoid :
# 8| v0_6(Void) = UnmodeledUse : mu*
# 8| v0_7(Void) = ExitFunction :
# 8| v0_7(Void) = AliasedUse : ~mu0_2
# 8| v0_8(Void) = ExitFunction :
# 9| System.Void UsingStmt.MyDisposable.Dispose()
# 9| Block 0
@ -1967,7 +2023,8 @@ using.cs:
# 9| v0_4(Void) = NoOp :
# 9| v0_5(Void) = ReturnVoid :
# 9| v0_6(Void) = UnmodeledUse : mu*
# 9| v0_7(Void) = ExitFunction :
# 9| v0_7(Void) = AliasedUse : ~mu0_2
# 9| v0_8(Void) = ExitFunction :
# 12| System.Void UsingStmt.Main()
# 12| Block 0
@ -2009,7 +2066,8 @@ using.cs:
# 26| mu0_35(<unknown>) = ^CallSideEffect : ~mu0_2
# 12| v0_36(Void) = ReturnVoid :
# 12| v0_37(Void) = UnmodeledUse : mu*
# 12| v0_38(Void) = ExitFunction :
# 12| v0_38(Void) = AliasedUse : ~mu0_2
# 12| v0_39(Void) = ExitFunction :
variables.cs:
# 5| System.Void test_variables.f()
@ -2035,4 +2093,5 @@ variables.cs:
# 10| mu0_18(Int32) = Store : &:r0_15, r0_17
# 5| v0_19(Void) = ReturnVoid :
# 5| v0_20(Void) = UnmodeledUse : mu*
# 5| v0_21(Void) = ExitFunction :
# 5| v0_21(Void) = AliasedUse : ~mu0_2
# 5| v0_22(Void) = ExitFunction :

Просмотреть файл

@ -83,6 +83,11 @@ class Test
// GOOD: Disposed automatically.
using var c2 = new Timer(TimerProc);
// GOOD: ownership taken via ??
StringReader source = null;
using(XmlReader.Create(source ?? new StringReader("xml"), null))
;
return null;
}

Просмотреть файл

@ -0,0 +1,2 @@
name: codeql-csharp-upgrades
upgrades: .

Просмотреть файл

@ -61,7 +61,7 @@
</div>
<div class="linkcontainer">
<div class="linkbar">
<a href="https://help.semmle.com/QL/learn-ql/" target="_blank">Learn QL</a>
<a href="https://help.semmle.com/QL/learn-ql/" target="_blank">Learn CodeQL</a>
<a href="https://help.semmle.com/QL/learn-ql/ql-training.html" target="_blank">QL for variant analysis</a>
<a href="https://help.semmle.com/QL/ql-tools.html" target="_blank">QL tools</a>
<a href="https://help.semmle.com/QL/ql-explore-queries.html" target="_blank">Queries</a>

Просмотреть файл

@ -1,11 +1,11 @@
About QL
========
This section is aimed at users with a background in general purpose programming as well as in databases. For a basic introduction and information on how to get started, see :doc:`Introduction to the QL language <introduction-to-ql>` and :doc:`Learning QL <../index>`.
This section is aimed at users with a background in general purpose programming as well as in databases. For a basic introduction and information on how to get started, see :doc:`Introduction to QL <introduction-to-ql>` and :doc:`Learning CodeQL <../index>`.
QL is a declarative, object-oriented query language that is optimized to enable efficient analysis of hierarchical data structures, in particular, databases representing software artifacts.
The queries and metrics used in LGTM are implemented using QL. This ensures that they can be extended or revised easily to keep up with changes in definitions of best coding practice. We continually improve existing queries as we work towards the ultimate goal of 100% precision.
The queries and metrics used in LGTM are implemented using CodeQL, which uses QL to analyze code. This ensures that they can be extended or revised easily to keep up with changes in definitions of best coding practice. We continually improve existing queries as we work towards the ultimate goal of 100% precision.
You can write queries to identify security vulnerabilities, find coding errors and bugs, or find code that breaks your team's guidelines for best practice. You can also create customized versions of the default queries to accommodate a new framework.

Просмотреть файл

@ -4,7 +4,7 @@ Semantics of abstract classes
Concrete classes
----------------
Concrete QL classes, as described in the QL language handbook topic on `Classes <https://help.semmle.com/QL/ql-handbook/types.html#classes>`__, lend themselves well to top-down modeling. We start from general superclasses representing large sets of values, and carve out individual subclasses representing more restricted sets of values.
Concrete classes, as described in the QL language handbook topic on `Classes <https://help.semmle.com/QL/ql-handbook/types.html#classes>`__, lend themselves well to top-down modeling. We start from general superclasses representing large sets of values, and carve out individual subclasses representing more restricted sets of values.
A classic example where this approach is useful is when modeling ASTs (Abstract Syntax Trees): the node types of an AST form a natural inheritance hierarchy, where, for example, there is a class ``Expr`` representing all expression nodes, with many different subclasses for different categories of expressions. There might be a class ``ArithmeticExpr`` representing arithmetic expressions, which in turn could have subclasses ``AddExpr`` and ``SubExpr``.
@ -57,7 +57,7 @@ Like a concrete class, an abstract class has one or more superclasses and a char
Example
~~~~~~~
The following example is taken from the standard QL library for Java:
The following example is taken from the CodeQL library for Java:
.. code-block:: ql

Просмотреть файл

@ -8,7 +8,7 @@ Advanced QL
./*
Topics on advanced uses of QL. These topics assume that you are familiar with the QL language and the basics of query writing.
Topics on advanced uses of QL. These topics assume that you are familiar with QL and the basics of query writing.
- :doc:`Semantics of abstract classes <abstract-classes>`
- :doc:`Choosing appropriate ways to constrain types <constraining-types>`

Просмотреть файл

@ -8,7 +8,7 @@ Type constraint methods
Note
The examples below use the Java QL library. All QL libraries support using these methods to constrain variables, the only difference is in the names of the classes used.
The examples below use the CodeQL library for Java. All libraries support using these methods to constrain variables, the only difference is in the names of the classes used.
There are several ways of imposing type constraints on variables:

Просмотреть файл

@ -1,14 +1,14 @@
Determining the most specific types of a variable
=================================================
It is sometimes useful to be able to determine what QL types an entity has -- especially when you are unfamiliar with the QL library used by a query. To help with this, QL provides a predicate called ``getAQlClass()``, which returns the most specific QL types of the entity that it is called on.
It is sometimes useful to be able to determine what types an entity has -- especially when you are unfamiliar with the library used by a query. To help with this, there is a predicate called ``getAQlClass()``, which returns the most specific QL types of the entity that it is called on.
This can be useful when you are not sure of the most precise class of a value. Discovering a more precise class can allow you to cast to it and use predicates that are not available on the more general class.
Example
-------
If you were working with a Java snapshot database, you might use ``getAQlClass()`` on every ``Expr`` in a callable called ``c``:
If you were working with a Java database, you might use ``getAQlClass()`` on every ``Expr`` in a callable called ``c``:
**Java example**
@ -23,6 +23,6 @@ If you were working with a Java snapshot database, you might use ``getAQlClass()
and e.getEnclosingCallable() = c
select e, e.getAQlClass()
The result of this query is a list of the most specific types of every ``Expr`` in that function. You will see multiple results for some expressions because that expression is represented by more than one QL type.
The result of this query is a list of the most specific types of every ``Expr`` in that function. You will see multiple results for some expressions because that expression is represented by more than one type.
For example, ``StringLiteral``\ s like ``"Hello"`` in Java belong to both the ``StringLiteral`` QL class (a specialization of the ``Literal`` QL class) and the ``CompileTimeConstantExpr`` QL class. So any instances of ``StringLiteral``\ s in the results will produce more than one result, one for each of the QL classes to which they belong.
For example, ``StringLiteral``\ s like ``"Hello"`` in Java belong to both the ``StringLiteral`` class (a specialization of the ``Literal`` class) and the ``CompileTimeConstantExpr`` class. So any instances of ``StringLiteral``\ s in the results will produce more than one result, one for each of the classes to which they belong.

Просмотреть файл

@ -6,7 +6,7 @@ The two expressions:
#. ``a() != b()``
#. ``not(a() = b())``
look equivalent - so much so that inexperienced (and even experienced) QL programmers have been known to rewrite one as the other. However, they are not equivalent due to the quantifiers involved.
look equivalent - so much so that inexperienced (and even experienced) programmers have been known to rewrite one as the other. However, they are not equivalent due to the quantifiers involved.
Thinking of ``a()`` and ``b()`` as sets of values, the first expression says that there is a pair of values (one from each side of the inequality) which are different.

Просмотреть файл

@ -1,7 +1,7 @@
Monotonic aggregates in QL
==========================
In addition to standard QL aggregates, QL also supports *monotonic* aggregates. These are a slightly different way of computing aggregates which have some advantages, notably the ability to be used recursively, which normal aggregates do not have. You can enable them in a scope by adding the \ ``language[monotonicAggregates]`` pragma on a predicate, class, or module.
In addition to standard aggregates, QL also supports *monotonic* aggregates. These are a slightly different way of computing aggregates which have some advantages, notably the ability to be used recursively, which normal aggregates do not have. You can enable them in a scope by adding the \ ``language[monotonicAggregates]`` pragma on a predicate, class, or module.
Syntax
------

Просмотреть файл

@ -77,4 +77,4 @@ What next?
- Help the villagers track down another criminal in the :doc:`next tutorial <fire-1>`.
- Find out more about the concepts you discovered in this tutorial in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__.
- Explore the libraries that help you get data about code in :doc:`Learning QL <../../index>`.
- Explore the libraries that help you get data about code in :doc:`Learning CodeQL <../../index>`.

Просмотреть файл

@ -40,4 +40,4 @@ What next?
- Find out who will be the new ruler of the village in the :doc:`next tutorial <heir>`.
- Learn more about predicates and classes in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__.
- Explore the libraries that help you get data about code in :doc:`Learning QL <../../index>`.
- Explore the libraries that help you get data about code in :doc:`Learning CodeQL <../../index>`.

Просмотреть файл

@ -161,4 +161,4 @@ What next?
- Learn more about recursion in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__.
- Put your QL skills to the test and solve the :doc:`River crossing puzzle <../ql-etudes/river-crossing>`.
- Start using QL to analyze projects. See :doc:`Learning QL <../../index>` for a summary of the available languages and resources.
- Start using QL to analyze projects. See :doc:`Learning CodeQL <../../index>` for a summary of the available languages and resources.

Просмотреть файл

@ -7,18 +7,21 @@ QL detective tutorials
./*
Welcome to QL! These tutorials are aimed at complete beginners. They teach you how to write QL queries and introduce you to key logic concepts along the way.
Welcome to the detective tutorials! These are aimed at complete beginners who would like to learn the basics of QL,
before analyzing code with CodeQL.
The tutorials teach you how to write queries and introduce you to key logic concepts along the way.
We recommend you first read the :doc:`Introduction to the QL language <../introduction-to-ql>` page for a basic description of QL.
We recommend you first read the :doc:`Introduction to QL <../introduction-to-ql>` page for a description of the language and
some simple examples.
Currently the following tutorials are available:
Currently the following detective tutorials are available:
- :doc:`Find the thief <find-thief-1>` - a three part mystery that introduces logical connectives, quantifiers and aggregates
- :doc:`Find the thief <find-thief-1>` - a three part mystery that introduces logical connectives, quantifiers, and aggregates
- :doc:`Catch the fire starter <fire-1>` - an intriguing search that introduces predicates and classes
- :doc:`Crown the rightful heir <heir>` - a detective puzzle that introduces recursion
Further resources
-----------------
- For a summary of available learning resources, see :doc:`Learning QL <../../index>`.
- For a summary of available learning resources, see :doc:`Learning CodeQL <../../index>`.
- For an overview of the important concepts in QL, see the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__.

Просмотреть файл

@ -1,10 +1,10 @@
Introducing the QL libraries for COBOL
======================================
Introducing the CodeQL libraries for COBOL
==========================================
Overview
--------
There is an extensive QL library for analyzing COBOL code. The classes in this library present the data from a snapshot database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks.
There is an extensive library for analyzing COBOL code. The classes in this library present the data from a CodeQL database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks.
The library is implemented as a set of QL modules–that is, files with the extension ``.qll``. The module ``cobol.qll`` imports most other standard library modules, so you can include the complete library by beginning your query with:
@ -12,12 +12,12 @@ The library is implemented as a set of QL modules–that is, files with the exte
import cobol
The rest of this tutorial briefly summarizes the most important QL classes and predicates provided by this library, including references to the `detailed API documentation <https://help.semmle.com/qldoc/cobol/>`__ where applicable.
The rest of this tutorial briefly summarizes the most important classes and predicates provided by this library, including references to the `detailed API documentation <https://help.semmle.com/qldoc/cobol/>`__ where applicable.
Introducing the library
-----------------------
The QL COBOL library presents information about COBOL source code at different levels:
The CodeQL library for COBOL presents information about COBOL source code at different levels:
- **Textual** — classes that represent source code as unstructured text files
- **Lexical** — classes that represent comments and other tokens of interest
@ -36,7 +36,7 @@ At its most basic level, a COBOL code base can simply be viewed as a collection
Files and folders
^^^^^^^^^^^^^^^^^
In QL, files are represented as entities of class `File <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$File.html>`__, and folders as entities of class `Folder <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$Folder.html>`__, both of which are subclasses of class `Container <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$Container.html>`__.
Files are represented as entities of class `File <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$File.html>`__, and folders as entities of class `Folder <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$Folder.html>`__, both of which are subclasses of class `Container <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$Container.html>`__.
Class `Container <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$Container.html>`__ provides the following member predicates:
@ -48,7 +48,7 @@ Note that while ``getAFile`` and ``getAFolder`` are declared on class `Container
Both files and folders have paths, which can be accessed by the predicate ``Container.getAbsolutePath()``. For example, if ``f`` represents a file with the path ``/home/user/project/src/main.cbl``, then ``f.getAbsolutePath()`` evaluates to the string ``"/home/user/project/src/main.cbl"``, while ``f.getParentContainer().getAbsolutePath()`` returns ``"/home/user/project/src"``.
These paths are absolute file system paths. If you want to obtain the path of a file relative to the snapshot source location, use ``Container.getRelativePath()`` instead. Note, however, that a snapshot may contain files that are not located underneath the snapshot source location; for such files, ``getRelativePath()`` will not return anything.
These paths are absolute file system paths. If you want to obtain the path of a file relative to the source location in the CodeQL database, use ``Container.getRelativePath()`` instead. Note, however, that a database may contain files that are not located underneath the source location; for such files, ``getRelativePath()`` will not return anything.
The following member predicates of class `Container <https://help.semmle.com/qldoc/cobol/semmle/cobol/Files.qll/type.Files$Container.html>`__ provide more information about the name of a file or folder:
@ -68,9 +68,9 @@ For example, the following query computes, for each folder, the number of COBOL
Locations
^^^^^^^^^
Most entities in a snapshot database have an associated source location. Locations are identified by four pieces of information: a file, a start line, a start column, an end line, and an end column. Line and column counts are 1-based (so the first character of a file is at line 1, column 1), and the end position is inclusive.
Most entities in a CodeQL database have an associated source location. Locations are identified by four pieces of information: a file, a start line, a start column, an end line, and an end column. Line and column counts are 1-based (so the first character of a file is at line 1, column 1), and the end position is inclusive.
All entities associated with a source location belong to the QL class `Locatable <https://help.semmle.com/qldoc/cobol/semmle/cobol/Location.qll/type.Location$Locatable.html>`__. The location itself is modeled by the QL class `Location <https://help.semmle.com/qldoc/cobol/semmle/cobol/Location.qll/type.Location$Location.html>`__ and can be accessed through the member predicate ``Locatable.getLocation()``. The `Location <https://help.semmle.com/qldoc/cobol/semmle/cobol/Location.qll/type.Location$Location.html>`__ class provides the following member predicates:
All entities associated with a source location belong to the class `Locatable <https://help.semmle.com/qldoc/cobol/semmle/cobol/Location.qll/type.Location$Locatable.html>`__. The location itself is modeled by the class `Location <https://help.semmle.com/qldoc/cobol/semmle/cobol/Location.qll/type.Location$Location.html>`__ and can be accessed through the member predicate ``Locatable.getLocation()``. The `Location <https://help.semmle.com/qldoc/cobol/semmle/cobol/Location.qll/type.Location$Location.html>`__ class provides the following member predicates:
- ``Location.getFile()``, ``Location.getStartLine()``, ``Location.getStartColumn()``, ``Location.getEndLine()``, ``Location.getEndColumn()`` return detailed information about the location.
- ``Location.getNumLines()`` returns the number of (whole or partial) lines covered by the location.
@ -104,13 +104,13 @@ The most important member predicates are as follows:
Syntactic level
~~~~~~~~~~~~~~~
The majority of classes in the QL COBOL library is concerned with representing a COBOL program as a collection of `abstract syntax trees <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (ASTs).
The majority of classes in the CodeQL library for COBOL are concerned with representing a COBOL program as a collection of `abstract syntax trees <http://en.wikipedia.org/wiki/Abstract_syntax_tree>`__ (ASTs).
The QL class `ASTNode <https://help.semmle.com/qldoc/cobol/semmle/cobol/AstNode.qll/type.AstNode$AstNode.html>`__ contains all entities representing nodes in the abstract syntax trees and defines generic tree traversal predicates:
The class `ASTNode <https://help.semmle.com/qldoc/cobol/semmle/cobol/AstNode.qll/type.AstNode$AstNode.html>`__ contains all entities representing nodes in the abstract syntax trees and defines generic tree traversal predicates:
- ``ASTNode.getParent()``: returns the parent node of this AST node, if any.
Please note that the QL libraries for COBOL do not currently represent all possible parts of a COBOL program. Due to the complexity of the language, and its many dialects, this is an ongoing task. We prioritize elements that are of interest to queries, and expand this selection over time. Please check the `detailed API documentation <https://help.semmle.com/qldoc/cobol/>`__ to see what is currently available.
Please note that the libraries for COBOL do not currently represent all possible parts of a COBOL program. Due to the complexity of the language, and its many dialects, this is an ongoing task. We prioritize elements that are of interest to queries, and expand this selection over time. Please check the `detailed API documentation <https://help.semmle.com/qldoc/cobol/>`__ to see what is currently available.
The main structure of any COBOL program is represented by the `Unit <https://help.semmle.com/qldoc/cobol/semmle/cobol/Units.qll/type.Units$Unit.html>`__ class and its subclasses. For example, each program definition has a `ProgramDefinition <https://help.semmle.com/qldoc/cobol/semmle/cobol/Units.qll/type.Units$ProgramDefinition.html>`__ counterpart. For each ``PROCEDURE DIVISION`` in the program, there will be a `ProcedureDivision <https://help.semmle.com/qldoc/cobol/semmle/cobol/AST_extended.qll/type.AST_extended$ProcedureDivision.html>`__ class.

Просмотреть файл

@ -1,5 +1,5 @@
QL for COBOL
============
CodeQL for COBOL
================
.. toctree::
:glob:
@ -7,14 +7,14 @@ QL for COBOL
introduce-libraries-cobol
This page provides an overview of the QL for COBOL documentation that is currently available.
This page provides an overview of the CodeQL for COBOL documentation that is currently available.
- `Basic COBOL query <https://lgtm.com/help/lgtm/console/ql-cobol-basic-example>`__ describes how to write and run queries using LGTM.
- :doc:`Introducing the QL libraries for COBOL <introduce-libraries-cobol>` introduces the standard libraries used to write queries for COBOL code.
- :doc:`Introducing the CodeQL libraries for COBOL <introduce-libraries-cobol>` introduces the standard libraries used to write queries for COBOL code.
Other resources
---------------
- For the queries used in LGTM, display a `COBOL query <https://lgtm.com/search?q=language%3Acobol&t=rules>`__ and click **Open in query console** to see the QL code used to find alerts.
- For more information about the COBOL QL library see the `QL library for COBOL <https://help.semmle.com/qldoc/cobol/>`__.
- For the queries used in LGTM, display a `COBOL query <https://lgtm.com/search?q=language%3Acobol&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for COBOL see the `CodeQL library for COBOL <https://help.semmle.com/qldoc/cobol/>`__.

Просмотреть файл

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# Learn QL documentation build configuration file, created by
# Learn CodeQL documentation build configuration file, created by
# on Tuesday Nov 13 2018.
#
# This file is execfile()d with the current directory set to its
@ -41,16 +41,16 @@ highlight_language = 'ql'
master_doc = 'index'
# General information about the project.
project = u'Learning QL'
project = u'Learning CodeQL'
# -- Project-specifc options for HTML output ----------------------------------------------
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
html_title = 'Learn QL'
html_title = 'Learn CodeQL'
# Output file base name for HTML help builder.
htmlhelp_basename = 'Learn QL'
htmlhelp_basename = 'Learn CodeQL'
# The version info for this project, if different from version and release in main conf.py file.
# The short X.Y version.

Просмотреть файл

@ -4,12 +4,12 @@ Tutorial: Conversions and classes
Overview
--------
This topic contains worked examples of how to write queries using the standard QL library classes for C/C++ conversions and classes.
This topic contains worked examples of how to write queries using the CodeQL library classes for C/C++ conversions and classes.
Conversions
-----------
Let us take a look at the QL ``Conversion`` class in the standard library:
Let us take a look at the ``Conversion`` class in the standard library:
- ``Expr``
@ -128,26 +128,26 @@ Unlike the earlier versions of the query, this query would return each side of t
Note
In general, QL predicates named ``getAXxx`` exploit the ability to return multiple results (multiple instances of ``Xxx``) whereas plain ``getXxx`` predicates usually return at most one specific instance of ``Xxx``.
In general, predicates named ``getAXxx`` exploit the ability to return multiple results (multiple instances of ``Xxx``) whereas plain ``getXxx`` predicates usually return at most one specific instance of ``Xxx``.
Classes
-------
Next we're going to look at C++ classes, using the following QL classes:
Next we're going to look at C++ classes, using the following CodeQL classes:
- ``Type``
- ``UserType``—includes classes, typedefs and enums
- ``UserType``—includes classes, typedefs, and enums
- ``Class``—a class or struct
- ``Struct``—a struct, which is treated as a subtype of Class in QL.
- ``Struct``—a struct, which is treated as a subtype of ``Class``
- ``TemplateClass``—a C++ class template
Finding derived classes
~~~~~~~~~~~~~~~~~~~~~~~
We want to create a query that checks for destructors that should be ``virtual``. Specifically, when a class and a class derived from it both have destructors, the base class destructor should generally be virtual. This ensures that the derived class destructor is always invoked. A ``Destructor`` in QL is a subtype of ``MemberFunction``:
We want to create a query that checks for destructors that should be ``virtual``. Specifically, when a class and a class derived from it both have destructors, the base class destructor should generally be virtual. This ensures that the derived class destructor is always invoked. In the CodeQL library, ``Destructor`` is a subtype of ``MemberFunction``:
- ``Function``
@ -221,13 +221,13 @@ Our last change is to use ``Function.isVirtual()`` to find cases where the base
That completes the query.
There is a similar built-in LGTM `query <https://lgtm.com/rules/2158670642/>`__ that finds classes in a C/C++ project with virtual functions but no virtual destructor. You can take a look at the QL code for this query by clicking **Open in query console** at the top of that page.
There is a similar built-in LGTM `query <https://lgtm.com/rules/2158670642/>`__ that finds classes in a C/C++ project with virtual functions but no virtual destructor. You can take a look at the code for this query by clicking **Open in query console** at the top of that page.
What next?
----------
- Explore other ways of querying classes using examples from the `C/C++ cookbook <https://help.semmle.com/wiki/label/CBCPP/class>`__.
- Take a look at the :doc:`Analyzing data flow in C/C++ <dataflow>` tutorial.
- Try the worked examples in the following topics: :doc:`Example: Checking that constructors initialize all private fields <private-field-initialization>` and :doc:`Example: Checking for allocations equal to 'strlen(string)' without space for a null terminator <zero-space-terminator>`.
- Try the worked examples in the following topics: :doc:`Example: Checking that constructors initialize all private fields <private-field-initialization>`, and :doc:`Example: Checking for allocations equal to 'strlen(string)' without space for a null terminator <zero-space-terminator>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.

Просмотреть файл

@ -4,10 +4,10 @@ Analyzing data flow in C/C++
Overview
--------
This topic describes how data flow analysis is implemented in the QL for C/C++ library and includes examples to help you write your own data flow queries.
The following sections describe how to utilize the QL libraries for local data flow, global data flow and taint tracking.
This topic describes how data flow analysis is implemented in the CodeQL libraries for C/C++ and includes examples to help you write your own data flow queries.
The following sections describe how to utilize the libraries for local data flow, global data flow, and taint tracking.
For a more general introduction to modeling data flow in QL, see :doc:`Introduction to data flow analysis in QL <../intro-to-data-flow>`.
For a more general introduction to modeling data flow, see :doc:`Introduction to data flow analysis with CodeQL <../intro-to-data-flow>`.
Local data flow
---------------
@ -166,6 +166,7 @@ The following predicates are defined in the configuration:
- ``isSource``—defines where data may flow from
- ``isSink``—defines where data may flow to
- ``isBarrier``—optional, restricts the data flow
- ``isBarrierGuard``—optional, restricts the data flow
- ``isAdditionalFlowStep``—optional, adds additional flow steps
The characteristic predicate ``MyDataFlowConfiguration()`` defines the name of the configuration, so ``"MyDataFlowConfiguration"`` should be replaced by the name of your class.
@ -204,6 +205,7 @@ The following predicates are defined in the configuration:
- ``isSource``—defines where taint may flow from
- ``isSink``—defines where taint may flow to
- ``isSanitizer``—optional, restricts the taint flow
- ``isSanitizerGuard``—optional, restricts the taint flow
- ``isAdditionalTaintStep``—optional, adds additional taint steps
Similar to global data flow, the characteristic predicate ``MyTaintTrackingConfiguration()`` defines the unique name of the configuration, so ``"MyTaintTrackingConfiguration"`` should be replaced by the name of your class.

Просмотреть файл

@ -4,12 +4,12 @@ Tutorial: Expressions, types and statements
Overview
--------
This topic contains worked examples of how to write queries using the standard QL library classes for C/C++ expressions, types, and statements.
This topic contains worked examples of how to write queries using the standard CodeQL library classes for C/C++ expressions, types, and statements.
Expressions and types
---------------------
Each part of an expression in C becomes an instance of the QL ``Expr`` class. For example, the C code ``x = x + 1`` becomes an ``AssignExpr``, an ``AddExpr``, two instances of ``VariableAccess`` and a ``Literal``. All of these QL classes extend ``Expr``.
Each part of an expression in C becomes an instance of the ``Expr`` class. For example, the C code ``x = x + 1`` becomes an ``AssignExpr``, an ``AddExpr``, two instances of ``VariableAccess`` and a ``Literal``. All of these CodeQL classes extend ``Expr``.
Finding assignments to zero
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -26,7 +26,7 @@ In the following example we find instances of ``AssignExpr`` which assign the co
`See this in the query console <https://lgtm.com/query/1505908086530/>`__
The ``where`` clause in this example gets the expression on the right side of the assignment, ``getRValue()``, and compares it with zero. Notice that there are no checks to make sure that the right side of the assignment is an integer or that it has a value (that is, it is compile-time constant, rather than a variable). For expressions where either of these assumptions is wrong, the associated QL predicate simply does not return anything and the ``where`` clause will not produce a result. You could think of it as if there is an implicit ``exists(e.getRValue().getValue().toInt())`` at the beginning of this line.
The ``where`` clause in this example gets the expression on the right side of the assignment, ``getRValue()``, and compares it with zero. Notice that there are no checks to make sure that the right side of the assignment is an integer or that it has a value (that is, it is compile-time constant, rather than a variable). For expressions where either of these assumptions is wrong, the associated predicate simply does not return anything and the ``where`` clause will not produce a result. You could think of it as if there is an implicit ``exists(e.getRValue().getValue().toInt())`` at the beginning of this line.
It is also worth noting that the query above would find this C code:
@ -34,7 +34,7 @@ It is also worth noting that the query above would find this C code:
yPtr = NULL;
This is because the snapshot contains a representation of the code base after the preprocessor transforms have run (for more information, see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__). This means that any macro invocations, such as the ``NULL`` define used here, are expanded during the creation of the snapshot. If you want to write queries about macros then there are some special library classes that have been designed specifically for this purpose (for example, the ``Macro``, ``MacroInvocation`` classes and predicates like ``Element.isInMacroExpansion()``). In this case, it is good that macros are expanded, but we do not want to find assignments to pointers.
This is because the database contains a representation of the code base after the preprocessor transforms have run (for more information, see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__). This means that any macro invocations, such as the ``NULL`` define used here, are expanded during the creation of the database. If you want to write queries about macros then there are some special library classes that have been designed specifically for this purpose (for example, the ``Macro``, ``MacroInvocation`` classes and predicates like ``Element.isInMacroExpansion()``). In this case, it is good that macros are expanded, but we do not want to find assignments to pointers.
Finding assignments of 0 to an integer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Просмотреть файл

@ -4,14 +4,14 @@ Tutorial: Function classes
Overview
--------
The standard QL library for C and C++ represents functions using the ``Function`` class (see :doc:`Introducing the C/C++ libraries <introduce-libraries-cpp>`).
The standard CodeQL library for C and C++ represents functions using the ``Function`` class (see :doc:`Introducing the C/C++ libraries <introduce-libraries-cpp>`).
The example queries in this topic explore some of the most useful library predicates for querying functions.
Finding all static functions
----------------------------
Using the member predicate ``Function.isStatic()`` we can list all of the static functions in a snapshot:
Using the member predicate ``Function.isStatic()`` we can list all the static functions in a database:
.. code-block:: ql
@ -26,7 +26,7 @@ This query is very general, so there are probably too many results to be interes
Finding functions that are not called
-------------------------------------
It might be more interesting to find functions that are not called, using the standard QL ``FunctionCall`` class from the **abstract syntax tree** category (see :doc:`Introducing the C/C++ libraries <introduce-libraries-cpp>`). The ``FunctionCall`` class can be used to identify places where a function is actually used, and it is related to ``Function`` through the ``FunctionCall.getTarget()`` predicate.
It might be more interesting to find functions that are not called, using the standard CodeQL ``FunctionCall`` class from the **abstract syntax tree** category (see :doc:`Introducing the C/C++ libraries <introduce-libraries-cpp>`). The ``FunctionCall`` class can be used to identify places where a function is actually used, and it is related to ``Function`` through the ``FunctionCall.getTarget()`` predicate.
.. code-block:: ql
@ -58,9 +58,9 @@ You can modify the query to remove functions where a function pointer is used to
This query returns fewer results. However, if you examine the results then you can probably still find potential refinements.
For example, there is a more complicated LGTM `query <https://lgtm.com/rules/2152580467/>`__ that finds unused static functions. To see the QL code for this query, click **Open in query console** at the top of the page.
For example, there is a more complicated LGTM `query <https://lgtm.com/rules/2152580467/>`__ that finds unused static functions. To see the code for this query, click **Open in query console** at the top of the page.
You can explore the definition of an element in the standard QL libraries and see what predicates are available. Use the keyboard **F3** button to open the definition of any element. Alternatively, hover over the element and click **Jump to definition** in the tooltip displayed. The library file is opened in a new tab with the definition highlighted.
You can explore the definition of an element in the standard libraries and see what predicates are available. Use the keyboard **F3** button to open the definition of any element. Alternatively, hover over the element and click **Jump to definition** in the tooltip displayed. The library file is opened in a new tab with the definition highlighted.
Finding a specific function
---------------------------

Просмотреть файл

@ -1,23 +1,23 @@
Introducing the C/C++ libraries
===============================
Introducing the CodeQL libraries for C/C++
==========================================
Overview
--------
There is an extensive QL library for analyzing snapshots extracted from C/C++ projects. The QL classes in this library present the data from a snapshot database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``cpp.qll`` imports all of the core C/C++ library modules, so you can include the complete library by beginning your query with:
There is an extensive library for analyzing CodeQL databases extracted from C/C++ projects. The classes in this library present the data from a database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``cpp.qll`` imports all the core C/C++ library modules, so you can include the complete library by beginning your query with:
.. code-block:: ql
import cpp
The rest of this topic summarizes available QL classes and corresponding C/C++ constructs.
The rest of this topic summarizes the available CodeQL classes and corresponding C/C++ constructs.
NOTE: You can find related classes and features using the query console's auto-complete feature. You can also press *F3* to jump to the definition of any element; QL library files are opened in new tabs in the console.
NOTE: You can find related classes and features using the query console's auto-complete feature. You can also press *F3* to jump to the definition of any element; library files are opened in new tabs in the console.
Summary of the library classes
------------------------------
The most commonly used standard QL library classes are listed below. The listing is broken down by functionality. Each QL library class is annotated with a C/C++ construct it corresponds to.
The most commonly used standard library classes are listed below. The listing is broken down by functionality. Each library class is annotated with a C/C++ construct it corresponds to.
Declaration classes
~~~~~~~~~~~~~~~~~~~
@ -25,7 +25,7 @@ Declaration classes
This table lists `Declaration <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Declaration.qll/type.Declaration$Declaration.html>`__ classes representing C/C++ declarations.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Example syntax | QL class | Remarks |
| Example syntax | CodeQL class | Remarks |
+=================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+=======================================================================================================================================================================+====================================================================================================================================================================================================+
| ``int`` *var* ``;`` | `GlobalVariable <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Variable.qll/type.Variable$GlobalVariable.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@ -154,7 +154,7 @@ Statement classes
This table lists subclasses of `Stmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$Stmt.html>`__ representing C/C++ statements.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Example syntax | QL class | Remarks |
| Example syntax | CodeQL class | Remarks |
+===============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+===================================================================================================================================================================================================================================================================================================+
| ``__asm__ ("`` *movb %bh, (%eax)* ``");`` | `AsmStmt <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/stmts/Stmt.qll/type.Stmt$AsmStmt.html>`__ | Specific to a given CPU instruction set |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@ -215,7 +215,7 @@ Expression classes
This table lists subclasses of `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__ representing C/C++ expressions.
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Example syntax | QL class(es) | Remarks |
| Example syntax | CodeQL class(es) | Remarks |
+========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================+==========================================================================================================================================================================================================+=============================================================================================================================================================================================================================================================================================================+
| ``{`` `Expr <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Expr.qll/type.Expr$Expr.html>`__... ``}`` | | `ArrayAggregateLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$ArrayAggregateLiteral.html>`__ | |
| | | `ClassAggregateLiteral <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/exprs/Literal.qll/type.Literal$ClassAggregateLiteral.html>`__ | |
@ -417,7 +417,7 @@ Type classes
This table lists subclasses of `Type <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$Type.html>`__ representing C/C++ types.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Example syntax | QL class | Remarks |
| Example syntax | CodeQL class | Remarks |
+=============================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+==================================================================================================================================================================================================================================================================================+
| ``void`` | `VoidType <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Type.qll/type.Type$VoidType.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@ -485,7 +485,7 @@ Preprocessor classes
This table lists `Preprocessor <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/module.Preprocessor.html>`__ classes representing C/C++ preprocessing directives.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Example syntax | QL class | Remarks |
| Example syntax | CodeQL class | Remarks |
+=============================================================================================================================================================================================================================================================================================================================================================================================================================================+==================================================================================================================================================================+===================================================================================================================================================================================================================================================================================+
| ``#elif`` *condition* | `PreprocessorElif <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/Preprocessor.qll/type.Preprocessor$PreprocessorElif.html>`__ | |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
@ -522,6 +522,6 @@ This table lists `Preprocessor <https://help.semmle.com/qldoc/cpp/semmle/code/cp
What next?
----------
- Experiment with the worked examples in the QL for C/C++ topics: :doc:`Function classes <function-classes>`, :doc:`Expressions, types and statements <expressions-types>`, :doc:`Conversions and classes <conversions-classes>`, and :doc:`Analyzing data flow in C/C++ <dataflow>`.
- Experiment with the worked examples in the CodeQL for C/C++ topics: :doc:`Function classes <function-classes>`, :doc:`Expressions, types and statements <expressions-types>`, :doc:`Conversions and classes <conversions-classes>`, and :doc:`Analyzing data flow in C/C++ <dataflow>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.

Просмотреть файл

@ -4,7 +4,7 @@ Example: Checking that constructors initialize all private fields
Overview
--------
This topic describes how a C++ query was developed. The example introduces recursive predicates and demonstrates the typical workflow used to refine a query. For a full overview of the topics available for learning to write QL queries for C/C++ code, see :doc:`QL for C/C++ <ql-for-cpp>`.
This topic describes how a C++ query was developed. The example introduces recursive predicates and demonstrates the typical workflow used to refine a query. For a full overview of the topics available for learning to write queries for C/C++ code, see :doc:`CodeQL for C/C++ <ql-for-cpp>`.
Problem—finding every private field and checking for initialization
-------------------------------------------------------------------
@ -29,7 +29,7 @@ We can start by looking at every private field in a class and checking that ever
#. ``f.isPrivate()`` checks if the field is private.
#. ``not exists(Assignment a | a = f.getAnAssignment() and a.getEnclosingFunction() = c)`` checks that there is no assignment to the field in the constructor.
This QL code looks fairly complete, but when you test it on a project, there are several results that contain examples that we have overlooked.
This code looks fairly complete, but when you test it on a project, there are several results that contain examples that we have overlooked.
Refinement 1—excluding fields initialized by lists
--------------------------------------------------
@ -62,7 +62,7 @@ These can be excluded by adding an extra condition to check for this special con
Refinement 2—excluding fields initialized by external libraries
---------------------------------------------------------------
When you test the revised query, you may discover that fields from classes in external libraries are over-reported. This is often because a header file declares a constructor that is defined in a source file that is not analyzed (external libraries are often excluded from analysis). When the source code is analyzed, the snapshot is populated with a ``Constructor`` entry with no body. This ``constructor`` therefore contains no assignments and consequently the query reports that any fields initialized by the constructor are "uninitialized." There is no particular reason to be suspicious of these cases, and we can exclude them from the results by defining a condition to exclude constructors that have no body:
When you test the revised query, you may discover that fields from classes in external libraries are over-reported. This is often because a header file declares a constructor that is defined in a source file that is not analyzed (external libraries are often excluded from analysis). When the source code is analyzed, the CodeQL database is populated with a ``Constructor`` entry with no body. This ``constructor`` therefore contains no assignments and consequently the query reports that any fields initialized by the constructor are "uninitialized." There is no particular reason to be suspicious of these cases, and we can exclude them from the results by defining a condition to exclude constructors that have no body:
.. code-block:: ql

Просмотреть файл

@ -1,5 +1,5 @@
QL for C/C++
============
CodeQL for C/C++
================
.. toctree::
:glob:
@ -13,19 +13,19 @@ QL for C/C++
private-field-initialization
zero-space-terminator
These topics provide an overview of the QL C/C++ standard libraries and show examples of how to write queries that use them.
These topics provide an overview of the CodeQL libraries for C/C++ and show examples of how to write queries that use them.
- `Basic C/C++ QL query <https://lgtm.com/help/lgtm/console/ql-cpp-basic-example>`__ describes how to write and run queries using LGTM.
- `Basic C/C++ query <https://lgtm.com/help/lgtm/console/ql-cpp-basic-example>`__ describes how to write and run queries using LGTM.
- :doc:`Introducing the QL libraries for C/C++ <introduce-libraries-cpp>` introduces the standard libraries used to write queries for C and C++ code.
- :doc:`Introducing the CodeQL libraries for C/C++ <introduce-libraries-cpp>` introduces the standard libraries used to write queries for C and C++ code.
- :doc:`Tutorial: Function classes <function-classes>` demonstrates how to write queries using the standard QL library classes for C/C++ functions.
- :doc:`Tutorial: Function classes <function-classes>` demonstrates how to write queries using the standard CodeQL library classes for C/C++ functions.
- :doc:`Tutorial: Expressions, types and statements <expressions-types>` demonstrates how to write queries using the standard QL library classes for C/C++ expressions, types and statements.
- :doc:`Tutorial: Expressions, types and statements <expressions-types>` demonstrates how to write queries using the standard CodeQL library classes for C/C++ expressions, types and statements.
- :doc:`Tutorial: Conversions and classes <conversions-classes>` demonstrates how to write queries using the standard QL library classes for C/C++ conversions and classes.
- :doc:`Tutorial: Conversions and classes <conversions-classes>` demonstrates how to write queries using the standard CodeQL library classes for C/C++ conversions and classes.
- :doc:`Tutorial: Analyzing data flow in C/C++ <dataflow>` demonstrates how to write queries using the standard QL for C/C++ data flow and taint tracking libraries.
- :doc:`Tutorial: Analyzing data flow in C/C++ <dataflow>` demonstrates how to write queries using the standard data flow and taint tracking libraries for C/C++.
- :doc:`Example: Checking that constructors initialize all private fields <private-field-initialization>` works through the development of a query. It introduces recursive predicates and shows the typical workflow used to refine a query.
@ -51,6 +51,8 @@ Advanced libraries
Other resources
---------------
- For examples of how to query common C/C++ elements, see the `C/C++ QL cookbook <https://help.semmle.com/wiki/display/CBCPP>`__.
- For the queries used in LGTM, display a `C/C++ query <https://lgtm.com/search?q=language%3Acpp&t=rules>`__ and click **Open in query console** to see the QL code used to find alerts.
- For more information about the C/C++ QL library see the `QL library for C/C++ <https://help.semmle.com/qldoc/cpp>`__.
.. TODO: Rename the cookbooks: C/C++ cookbook, or C/C++ CodeQL cookbook, or CodeQL cookbook for C/C++, or...?
- For examples of how to query common C/C++ elements, see the `C/C++ cookbook <https://help.semmle.com/wiki/display/CBCPP>`__.
- For the queries used in LGTM, display a `C/C++ query <https://lgtm.com/search?q=language%3Acpp&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for C/C++ see the `CodeQL library for C/C++ <https://help.semmle.com/qldoc/cpp>`__.

Просмотреть файл

@ -4,7 +4,7 @@ Hash consing and value numbering
Overview
--------
In C and C++ QL databases, each node in the abstract syntax tree is represented by a separate object. This allows both analysis and results display to refer to specific appearances of a piece of syntax. However, it is frequently useful to determine whether two expressions are equivalent, either syntactically or semantically.
In C and C++ databases, each node in the abstract syntax tree is represented by a separate object. This allows both analysis and results display to refer to specific appearances of a piece of syntax. However, it is frequently useful to determine whether two expressions are equivalent, either syntactically or semantically.
The `hash consing <https://en.wikipedia.org/wiki/Hash_consing>`__ library (defined in ``semmle.code.cpp.valuenumbering.HashCons``) provides a mechanism for identifying expressions that have the same syntactic structure. The `global value numbering <https://en.wikipedia.org/wiki/Value_numbering>`__ library (defined in ``semmle.code.cpp.valuenumbering.GlobalValueNumbering``) provides a mechanism for identifying expressions that compute the same value at runtime.

Просмотреть файл

@ -4,7 +4,7 @@ Example: Checking for allocations equal to ``strlen(string)`` without space for
Overview
--------
This topic describes how a C/C++ query for detecting a potential buffer overflow was developed. For a full overview of the topics available for learning to write QL queries for C/C++ code, see :doc:`QL for C/C++ <ql-for-cpp>`.
This topic describes how a C/C++ query for detecting a potential buffer overflow was developed. For a full overview of the topics available for learning to write queries for C/C++ code, see :doc:`CodeQL for C/C++ <ql-for-cpp>`.
Problem—detecting memory allocation that omits space for a null termination character
-------------------------------------------------------------------------------------
@ -32,7 +32,7 @@ Defining the entities of interest
You could approach this problem either by searching for code similar to the call to ``malloc`` in line 3 or the call to ``strcpy`` in line 5 (see example above). For our basic query, we start with a simple assumption: any call to ``malloc`` with only a ``strlen`` to define the memory size is likely to cause an error when the memory is populated.
Calls to ``strlen`` can be identified using the library `StrlenCall <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/commons/StringAnalysis.qll/type.StringAnalysis$StrlenCall.html>`__ class, but we need to define a new class to identify calls to ``malloc``. Both the library class and the new class need to extend the standard QL class ``FunctionCall``, with the added restriction of the function name that they apply to:
Calls to ``strlen`` can be identified using the library `StrlenCall <https://help.semmle.com/qldoc/cpp/semmle/code/cpp/commons/StringAnalysis.qll/type.StringAnalysis$StrlenCall.html>`__ class, but we need to define a new class to identify calls to ``malloc``. Both the library class and the new class need to extend the standard class ``FunctionCall``, with the added restriction of the function name that they apply to:
.. code-block:: ql
@ -52,7 +52,7 @@ Calls to ``strlen`` can be identified using the library `StrlenCall <https://hel
Finding the ``strlen(string)`` pattern
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before we start to write our query, there's one remaining task. We need to modify our new ``MallocCall`` class, so it returns an expression for the size of the allocation. Currently this will be the first argument to the ``malloc`` call, ``FunctionCall.getArgument(0)``, but converting this into a QL predicate makes it more flexible for future refinements.
Before we start to write our query, there's one remaining task. We need to modify our new ``MallocCall`` class, so it returns an expression for the size of the allocation. Currently this will be the first argument to the ``malloc`` call, ``FunctionCall.getArgument(0)``, but converting this into a predicate makes it more flexible for future refinements.
.. code-block:: ql
@ -106,7 +106,7 @@ The query above works for simple cases, but does not identify a common coding pa
int len = strlen(input);
buffer = malloc(len);
To identify this case we can use the standard QL library ``SSA.qll`` (imported as ``semmle.code.cpp.controlflow.SSA``).
To identify this case we can use the standard library ``SSA.qll`` (imported as ``semmle.code.cpp.controlflow.SSA``).
This library helps us identify where values assigned to local variables may subsequently be used.

Просмотреть файл

@ -4,10 +4,10 @@ Analyzing data flow in C#
Overview
--------
This topic describes how data flow analysis is implemented in the QL for C# library and includes examples to help you write your own data flow queries.
The following sections describe how to utilize the QL libraries for local data flow, global data flow and taint tracking.
This topic describes how data flow analysis is implemented in the CodeQL libraries for C# and includes examples to help you write your own data flow queries.
The following sections describe how to utilize the libraries for local data flow, global data flow, and taint tracking.
For a more general introduction to modeling data flow in QL, see :doc:`Introduction to data flow analysis in QL <../intro-to-data-flow>`.
For a more general introduction to modeling data flow, see :doc:`Introduction to data flow analysis with CodeQL <../intro-to-data-flow>`.
Local data flow
---------------
@ -548,6 +548,6 @@ This can be adapted from the ``SystemUriFlow`` class:
What next?
----------
- Learn about the QL standard libraries used to write queries for C# in :doc:`Introducing the C# libraries <introduce-libraries-csharp>`.
- Learn about the standard libraries used to write queries for C# in :doc:`Introducing the C# libraries <introduce-libraries-csharp>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.

Просмотреть файл

@ -1,25 +1,23 @@
Introducing the C# libraries
============================
Introducing the CodeQL libraries for C#
=======================================
Overview
--------
The C# QL libraries are a data model for analysis of C# code. QL is an object-oriented language, so the data model is represented as *QL classes*, which are organized into *QL libraries*. The QL classes are a layer of logic built on top of an underlying database.
The core library is imported at the top of each query using:
There is an extensive library for analyzing CodeQL databases extracted from C# projects. The classes in this library present the data from a database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks. The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``csharp.qll`` imports all the core C# library modules, so you can include the complete library by beginning your query with:
.. code-block:: ql
import csharp
Since this is required for all C# queries, it is omitted from QL snippets below.
Since this is required for all C# queries, it is omitted from code snippets below.
The core library contains all the program elements, including `files <#files>`__, `types <#types>`__, methods, `variables <#variables>`__, `statements <#statements>`__, and `expressions <#expressions>`__. This is sufficient for most queries, however additional libraries can be imported for bespoke functionality such as control flow and data flow. See :doc:`QL for C# <ql-for-csharp>` for information about these additional libraries.
The core library contains all the program elements, including `files <#files>`__, `types <#types>`__, methods, `variables <#variables>`__, `statements <#statements>`__, and `expressions <#expressions>`__. This is sufficient for most queries, however additional libraries can be imported for bespoke functionality such as control flow and data flow. See :doc:`CodeQL for C# <ql-for-csharp>` for information about these additional libraries.
Class hierarchies
~~~~~~~~~~~~~~~~~
Each section contains a QL class hierarchy, showing the inheritance structure between QL classes. For example:
Each section contains a class hierarchy, showing the inheritance structure between CodeQL classes. For example:
- ``Expr``
@ -46,13 +44,13 @@ Each section contains a QL class hierarchy, showing the inheritance structure be
This means that the class ``AddExpr`` extends class ``BinaryArithmeticOperation``, which in turn extends class ``ArithmeticOperation`` and so on. If you want to query any arithmetic operation, then use the class ``ArithmeticOperation``, but if you specifically want to limit the query to addition operations, then use the class ``AddExpr``.
QL classes can also be considered to be *sets*, and the ``extends`` relation between classes defines a subset. Every member of class ``AddExpr`` is also in the class ``BinaryArithmeticOperation``. In general, QL classes overlap and an entity can be a member of several classes.
Classes can also be considered to be *sets*, and the ``extends`` relation between classes defines a subset. Every member of class ``AddExpr`` is also in the class ``BinaryArithmeticOperation``. In general, classes overlap and an entity can be a member of several classes.
This overview omits some of the less important or intermediate classes from the class hierarchy.
Each class has predicates, which are logical propositions about that class. They also define navigable relationships between classes. Predicates are inherited, so for example the ``AddExpr`` class inherits the predicates ``getLeftOperand()`` and ``getRightOperand()`` from ``BinaryArithmeticOperation``, and ``getType()`` from class ``Expr``. This is similar to how methods are inherited in object-oriented programming languages.
In this overview, we present the most common and useful predicates. Consult the reference, QL source code, and autocomplete in the editor for the complete list of predicates available on each class.
In this overview, we present the most common and useful predicates. Consult the `reference <https://help.semmle.com/qldoc/csharp>`__, the CodeQL source code, and autocomplete in the editor for the complete list of predicates available on each class.
Exercises
~~~~~~~~~
@ -72,7 +70,7 @@ Exercise 1: Simplify the following query:
Files
-----
Files are represented by the QL class `File <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/File.qll/type.File$File.html>`__, and directories by the QL class `Folder <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/File.qll/type.File$Folder.html>`__. The database contains all of the source files and assemblies used during the compilation.
Files are represented by the class `File <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/File.qll/type.File$File.html>`__, and directories by the class `Folder <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/File.qll/type.File$Folder.html>`__. The database contains all of the source files and assemblies used during the compilation.
Class hierarchy
~~~~~~~~~~~~~~~
@ -143,7 +141,7 @@ To list all elements in ``Main.cs``, their QL class and location:
where e.getFile().getShortName() = "Main"
select e, e.getAQlClass(), e.getLocation()
Note that ``getAQlClass()`` is available on all QL classes and is a useful way to figure out the QL class of something. Often the same element will have several QL classes which are all returned by ``getAQlClass()``.
Note that ``getAQlClass()`` is available on all entities and is a useful way to figure out the QL class of something. Often the same element will have several classes which are all returned by ``getAQlClass()``.
Locations
---------
@ -234,7 +232,7 @@ Find declarations containing a username:
Variables
---------
The QL class `Variable <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Variable.qll/type.Variable$Variable.html>`__ represents C# variables, such as fields, parameters and local variables. The database contains all variables from the source code, as well as all fields and parameters from assemblies referenced by the program.
The class `Variable <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Variable.qll/type.Variable$Variable.html>`__ represents C# variables, such as fields, parameters and local variables. The database contains all variables from the source code, as well as all fields and parameters from assemblies referenced by the program.
Class hierarchy
~~~~~~~~~~~~~~~
@ -283,7 +281,7 @@ Find all unused local variables:
Types
-----
Types are represented by the QL class `Type <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Type.qll/type.Type$Type.html>`__ and consist of builtin types, interfaces, classes, structs, enums, and type parameters. The database contains types from the program and all referenced assemblies including mscorlib and the .NET framework.
Types are represented by the CodeQL class `Type <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Type.qll/type.Type$Type.html>`__ and consist of builtin types, interfaces, classes, structs, enums, and type parameters. The database contains types from the program and all referenced assemblies including mscorlib and the .NET framework.
The builtin types (``object``, ``int``, ``double`` etc.) have corresponding types (``System.Object``, ``System.Int32`` etc.) in mscorlib.
@ -438,7 +436,7 @@ Exercise 5: Write a query to find all classes starting with the letter ``A``. (`
Callables
---------
Callables are represented by the QL class `Callable <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Callable.qll/type.Callable$Callable.html>`__ and are anything that can be called independently, such as methods, constructors, destructors, operators, anonymous functions, indexers, and property accessors.
Callables are represented by the class `Callable <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Callable.qll/type.Callable$Callable.html>`__ and are anything that can be called independently, such as methods, constructors, destructors, operators, anonymous functions, indexers, and property accessors.
The database contains all of the callables in your program and in all referenced assemblies.
@ -564,7 +562,7 @@ Find ``Main`` methods which are not ``private``:
Statements
----------
Statements are represented by the QL class `Stmt <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Stmt.qll/type.Stmt$Stmt.html>`__ and make up the body of methods (and other callables). The database contains all statements in the source code, but does not contain any statements from referenced assemblies where the source code is not available.
Statements are represented by the class `Stmt <https://help.semmle.com/qldoc/csharp/semmle/code/csharp/Stmt.qll/type.Stmt$Stmt.html>`__ and make up the body of methods (and other callables). The database contains all statements in the source code, but does not contain any statements from referenced assemblies where the source code is not available.
Class hierarchy
~~~~~~~~~~~~~~~
@ -922,7 +920,7 @@ Exercise 9: Limit the previous query to string types. Exclude empty passwords or
Attributes
----------
C# attributes are represented by the QL class `Attribute <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Attribute.qll/type.Attribute$Attribute.html>`__. They can be present on many C# elements, such as classes, methods, fields, and parameters. The database contains attributes from the source code and all assembly references.
C# attributes are represented by the class `Attribute <https://help.semmle.com/qldoc/csharp/semmle/code/cil/Attribute.qll/type.Attribute$Attribute.html>`__. They can be present on many C# elements, such as classes, methods, fields, and parameters. The database contains attributes from the source code and all assembly references.
The attribute of any ``Element`` can be obtained via ``getAnAttribute()``, whereas if you have an attribute, you can find its element via ``getTarget()``. The following two query fragments are identical:
@ -1122,6 +1120,6 @@ Here is the fixed version:
What next?
----------
- Visit :doc:`Tutorial: Analyzing data flow in C# <dataflow>` to learn more about writing queries using the standard QL for C# data flow and taint tracking libraries.
- Visit :doc:`Tutorial: Analyzing data flow in C# <dataflow>` to learn more about writing queries using the standard data flow and taint tracking libraries.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.

Просмотреть файл

@ -1,5 +1,5 @@
QL for C#
=========
CodeQL for C#
=============
.. toctree::
:glob:
@ -8,17 +8,17 @@ QL for C#
introduce-libraries-csharp
dataflow
These topics provide an overview of the QL C# libraries and show examples of how to use them.
These topics provide an overview of the CodeQL libraries for C# and show examples of how to use them.
- `Basic C# QL query <https://lgtm.com/help/lgtm/console/ql-csharp-basic-example>`__ describes how to write and run queries using LGTM.
- `Basic C# query <https://lgtm.com/help/lgtm/console/ql-csharp-basic-example>`__ describes how to write and run queries using LGTM.
- :doc:`Introducing the C# libraries <introduce-libraries-csharp>` introduces the standard libraries used to write queries for C# code.
- :doc:`Introducing the CodeQL libraries for C# <introduce-libraries-csharp>` introduces the standard libraries used to write queries for C# code.
.. raw:: html
<!-- Working with generic types and methods(generics) - how to query generic types and methods. -->
- :doc:`Tutorial: Analyzing data flow in C# <dataflow>` demonstrates how to write queries using the standard QL for C# data flow and taint tracking libraries.
- :doc:`Tutorial: Analyzing data flow in C# <dataflow>` demonstrates how to write queries using the standard data flow and taint tracking libraries for C#.
.. raw:: html
@ -35,6 +35,6 @@ These topics provide an overview of the QL C# libraries and show examples of how
Other resources
---------------
- For examples of how to query common C# elements, see the `C# QL cookbook <https://help.semmle.com/wiki/display/CBCSHARP>`__.
- For the queries used in LGTM, display a `C# query <https://lgtm.com/search?q=language%3Acsharp&t=rules>`__ and click **Open in query console** to see the QL code used to find alerts.
- For more information about the C/C++ QL library see the `QL library for C# <https://help.semmle.com/qldoc/csharp>`__.
- For examples of how to query common C# elements, see the `C# cookbook <https://help.semmle.com/wiki/display/CBCSHARP>`__.
- For the queries used in LGTM, display a `C# query <https://lgtm.com/search?q=language%3Acsharp&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for C# see the `CodeQL library for C# <https://help.semmle.com/qldoc/csharp>`__.

Просмотреть файл

@ -0,0 +1,33 @@
What's in a CodeQL database?
============================
A CodeQL database contains a variety of data related to a particular code base at a particular point in time. For details of how the database is generated see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__.
The database contains a full, hierarchical representation of the program defined by the code base. The database schema varies according to the language analyzed. The schema provides an interface between the initial lexical analysis during the extraction process, and the actual complex analysis using CodeQL. When the source code languages being analyzed change (such as Java 7 evolving into Java 8), this interface between the analysis phases can also change.
For each language, a CodeQL library defines classes to provide a layer of abstraction over the database tables. This provides an object-oriented view of the data which makes it easier to write queries. This is easiest to explain using an example.
Example
-------
For a Java program, two key tables are:
- The ``expressions`` table containing a row for every single expression in the source code that was analyzed during the build process.
- The ``statements`` table containing a row for every single statement in the source code that was analyzed during the build process.
The CodeQL library defines classes to provide a layer of abstraction over each of these tables (and the related auxiliary tables): ``Expr`` and ``Stmt``.
Most classes in the library are similar: they are abstractions over one or more database tables. Looking at one of the libraries illustrates this:
.. code-block:: ql
class Expr extends StmtParent, @expr {
...
/** the location of this expression */
Location getLocation() { exprs(this,_,_,result) }
...
}
The ``Expr`` class, shown here, extends from the database type ``@expr``. Member predicates of the ``Expr`` class are implemented in terms of the database-provided ``exprs`` table.

Просмотреть файл

@ -1,7 +1,7 @@
QL for Go
=========
CodeQL for Go
=============
This page provides an overview of the QL for Go documentation that is currently available.
This page provides an overview of the CodeQL for Go documentation that is currently available.
- `Basic Go query <https://lgtm.com/help/lgtm/console/ql-go-basic-example>`__ describes how to write and run queries using LGTM.
@ -9,5 +9,5 @@ This page provides an overview of the QL for Go documentation that is currently
Other resources
---------------
- For the queries used in LGTM, display a `Go query <https://lgtm.com/search?q=language%3Ago&t=rules>`__ and click **Open in query console** to see the QL code used to find alerts.
- For more information about the Go QL library see the `QL library for Go <https://help.semmle.com/qldoc/go/>`__.
- For the queries used in LGTM, display a `Go query <https://lgtm.com/search?q=language%3Ago&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for Go see the `CodeQL library for Go <https://help.semmle.com/qldoc/go/>`__.

Просмотреть файл

@ -1,14 +1,13 @@
Learning QL
###########
Learning CodeQL
###############
CodeQL is the code analysis platform used by security researchers to automate `variant analysis <https://semmle.com/variant-analysis>`__.
You can use CodeQL queries to explore code and quickly find variants of security vulnerabilities and bugs.
These queries are easy to write and share–visit the topics below and `our open source repository on GitHub <https://github.com/Semmle/ql>`__ to learn more.
You can also try out CodeQL in the `query console <https://lgtm.com/query>`__ on `LGTM.com <https://lgtm.com>`__.
Here, you can query open source projects directly, without having to download CodeQL databases and libraries.
`QL <https://semmle.com/ql>`__ is the query language used in Semmle's `variant analysis <https://semmle.com/variant-analysis>`__ engine.
You can use queries written in QL to explore code and quickly find variants of security vulnerabilities and bugs.
The QL language is also part of the technology behind `LGTM <https://lgtm.com>`__, Semmle's analysis platform that combines deep semantic code search with data science insights to help developers ship secure code.
QL queries are easy to write and share–visit the topics below and `our open source repository on GitHub <https://github.com/Semmle/ql>`__ to learn more.
You can also try out QL in the `query console <https://lgtm.com/query>`__ on `LGTM.com <https://lgtm.com>`__.
Here, you can write QL code to query open source projects directly, without having to download snapshots and libraries.
CodeQL is based on a powerful query language called QL. The following topics help you understand QL in general, as well as how to use it when analyzing code with CodeQL.
.. _getting-started:
@ -25,10 +24,10 @@ If you are new to QL, start by looking at the following topics:
beginner/ql-tutorials
ql-etudes/river-crossing
QL training and variant analysis examples
******************************************
CodeQL training and variant analysis examples
*********************************************
To start learning how to use QL in variant analysis for a specific language, see:
To start learning how to use CodeQL for variant analysis for code written in a specific language, see:
.. toctree::
:maxdepth: -1
@ -37,8 +36,8 @@ To start learning how to use QL in variant analysis for a specific language, see
.. _writing-ql-queries:
Writing QL queries
******************
Writing CodeQL queries
**********************
To learn more about writing your own queries, see:
@ -48,7 +47,7 @@ To learn more about writing your own queries, see:
writing-queries/writing-queries
For more information on writing QL to query code written in a specific language see:
For more information on using CodeQL to query code written in a specific language, see:
.. toctree::
:maxdepth: 2
@ -77,10 +76,10 @@ For more technical information see:
Reference topics
****************
For a more comprehensive guide to QL see the following reference topics:
For a more comprehensive guide to the query language itself, see the following reference topics:
- `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__—a description of important concepts in QL
- `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__—a formal specification of the QL language.
- `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__—a description of important concepts in QL.
- `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__—a formal specification of QL.
Search
******

Просмотреть файл

@ -1,15 +1,15 @@
Introduction to data flow analysis in QL
########################################
Introduction to data flow analysis with CodeQL
##############################################
Overview
********
Data flow analysis computes the possible values that a variable can hold at various points in a program, determining how those values propagate through the program and where they are used.
Many of Semmle's built-in security queries implement data flow analysis, which can highlight the fate of potentially malicious or insecure data that can cause vulnerabilities in your code base.
Many CodeQL security queries implement data flow analysis, which can highlight the fate of potentially malicious or insecure data that can cause vulnerabilities in your code base.
These queries help you understand if data is used in an insecure way, whether dangerous arguments are passed to functions, or whether sensitive data can leak.
As well as highlighting potential security issues, you can also use data flow analysis to understand other aspects of how a program behaves, by finding, for example, uses of unititialized variables and resource leaks.
As well as highlighting potential security issues, you can also use data flow analysis to understand other aspects of how a program behaves, by finding, for example, uses of uninitialized variables and resource leaks.
The following sections provide a brief introduction to data flow analysis in QL.
The following sections provide a brief introduction to data flow analysis with CodeQL.
See the following tutorials for more information about analyzing data flow in specific languages:
@ -30,7 +30,7 @@ See the following tutorials for more information about analyzing data flow in sp
Data flow graph
***************
The QL data flow libraries implement data flow analysis on a program or function by modeling its data flow graph.
The CodeQL data flow libraries implement data flow analysis on a program or function by modeling its data flow graph.
Unlike the `abstract syntax tree <https://en.wikipedia.org/wiki/Abstract_syntax_tree>`__, the
data flow graph does not reflect the syntactic structure of the program, but models the way data flows through the program at runtime. Nodes in the abstract syntax tree
represent syntactic elements such as statements or expressions. Nodes in the data flow graph, on the other hand, represent semantic elements that carry values at runtime.
@ -58,18 +58,18 @@ Computing an accurate and complete data flow graph presents several challenges:
- Aliasing between variables can result in a single write changing the value that multiple pointers point to.
- The data flow graph can be very large and slow to compute.
To overcome these potential problems, two kinds of data flow are modeled in the QL libraries:
To overcome these potential problems, two kinds of data flow are modeled in the libraries:
- Local data flow, concerning the data flow within a single function. When reasoning about local, you only considers edges between data flow nodes belonging to the same function.It is generally sufficiently fast, efficient and precise for many queries, and it is usually possible to compute the local data flow for all functions in a snapshot.
- Local data flow, concerning the data flow within a single function. When reasoning about local data flow, you only consider edges between data flow nodes belonging to the same function. It is generally sufficiently fast, efficient and precise for many queries, and it is usually possible to compute the local data flow for all functions in a CodeQL database.
- Global data flow, effectively considers the data flow within an entire program, by calculating data flow between functions and through object properties. Computing global data flow is typically more time and energy intensive than local data flow, therefore queries should be refined to look for more specific sources and sinks.
Many of the built-in queries included in the latest Semmle release contain examples of both local and global data flow analysis. See `the built-in queries <https://help.semmle.com/wiki/display/QL/Built-in+queries>`__ for details.
Many CodeQL queries contain examples of both local and global data flow analysis. See `the built-in queries <https://help.semmle.com/wiki/display/QL/Built-in+queries>`__ for details.
Normal data flow vs taint tracking
**********************************
In the QL standard libraries, we make a distinction between 'normal' data flow and taint tracking.
In the standard libraries, we make a distinction between 'normal' data flow and taint tracking.
The normal data flow libraries are used to analyze the information flow in which data values are preserved at each step.
For example, if you are tracking an insecure object ``x`` (which might be some untrusted or potentially malicious data), a step in the program may 'change' its value. So, in a simple process such as ``y = x + 1``, a normal data flow analysis will highlight the use of ``x``, but not ``y``.
@ -81,5 +81,5 @@ These flow steps are modeled in the taint-tracking library using predicates that
What next?
**********
- Search for ``DataFlow`` and ``TaintTracking`` in the `QL standard libraries <https://help.semmle.com/wiki/display/QL/QL+standard+libraries>`__ to learn more about the technical implementation of data flow analysis in QL for specific programming languages.
- Visit `Learning QL <https://help.semmle.com/QL/learn-ql/>`__ to find language-specific QL tutorials on data flow and other topics.
- Search for ``DataFlow`` and ``TaintTracking`` in the `standard CodeQL libraries <https://help.semmle.com/wiki/display/QL/QL+standard+libraries>`__ to learn more about the technical implementation of data flow analysis for specific programming languages.
- Visit `Learning CodeQL <https://help.semmle.com/QL/learn-ql/>`__ to find language-specific tutorials on data flow and other topics.

Просмотреть файл

@ -1,18 +1,22 @@
Introduction to the QL language
===============================
Introduction to QL
==================
QL is a powerful query language that is used to analyze code. Queries written in QL can be used to find errors and uncover variants of important security vulnerabilities. Visit Semmle's `security research page <https://lgtm.com/security>`__ to read about examples of vulnerabilities that we have recently found in open source projects using QL queries.
QL is the powerful query language that underlies CodeQL, which is used to analyze code.
Queries written with CodeQL can find errors and uncover variants of important security vulnerabilities.
Visit Semmle's `security research page <https://lgtm.com/security>`__ to read about examples of vulnerabilities that we have recently found in open source projects.
Before diving into code analysis with CodeQL, it can be helpful to learn about the underlying language more generally.
QL is a logic programming language, so it is built up of logical formulas. QL uses common logical connectives (such as ``and``, ``or``, and ``not``), quantifiers (such as ``forall`` and ``exists``), and other important logical concepts such as predicates.
QL also supports recursion and aggregates. This allows you to write complex recursive queries using simple QL syntax and directly use aggregates such as ``count``, ``sum`` and ``average``.
QL also supports recursion and aggregates. This allows you to write complex recursive queries using simple QL syntax and directly use aggregates such as ``count``, ``sum``, and ``average``.
Basic syntax
------------
The basic syntax will look familiar to anyone who has used SQL, but it is used somewhat differently.
The basic syntax of QL will look familiar to anyone who has used SQL, but it is used somewhat differently.
A QL query is defined by a **select** clause, which specifies what the result of the query should be. You can try out the examples and exercises in this topic directly in LGTM. Open the `query console <https://lgtm.com/query>`__. Before you can run a query, you need to select a language and project to query (for these logic examples, any language and project will do).
A query is defined by a **select** clause, which specifies what the result of the query should be. You can try out the examples and exercises in this topic directly in LGTM. Open the `query console <https://lgtm.com/query>`__. Before you can run a query, you need to select a language and project to query (for these logic examples, any language and project will do).
Once you have selected a language, the query console is populated with the query:
@ -110,9 +114,12 @@ To simplify the query, we can introduce a class ``SmallInt`` representing the in
`See this in the query console <https://lgtm.com/query/2101340747/>`__
Now that you've seen some general examples, let's use QL queries to analyze projects. In particular, LGTM generates a database representing the code and then QL is used to query this database. See `Database generation <https://lgtm.com/help/lgtm/generate-database>`__ for more details on how the database is built.
Now that you've seen some general examples, let's use the CodeQL libraries to analyze projects.
In particular, LGTM generates a database representing the code and then CodeQL is used to query this database. See `Database generation <https://lgtm.com/help/lgtm/generate-database>`__ for more details on how the database is built.
The previous exercises just used the primitive types built in to QL. Although we chose a project to query, they did not use the project-specific database. The following example queries *do* use these databases and give you an idea of what QL can be used for. There are more details about how to write QL `below <#learning-ql>`__, so don't worry if you don't fully understand these examples yet!
.. XX: Perhaps a link to the "CodeQL libraries for X"?
The previous exercises just used the primitive types built in to QL. Although we chose a project to query, they did not use the project-specific database. The following example queries *do* use these databases and give you an idea of what CodeQL can be used for. There are more details about how to use CodeQL `below <#learning-ql>`__, so don't worry if you don't fully understand these examples yet!
Python
~~~~~~
@ -153,9 +160,9 @@ Java
`See this in the query console <https://lgtm.com/query/2098670762/>`__. The ``from`` clause defines a variable ``p`` representing a parameter. The ``where`` clause finds unused parameters by limiting the parameters ``p`` to those which are not accessed. Finally, the ``select`` clause lists these parameters.
Learning QL
-----------
Learning CodeQL
---------------
- To find out more about how to write your own QL queries, try working through the :doc:`QL detective tutorials <beginner/ql-tutorials>`.
- For an overview of the other available resources, see :doc:`Learning QL <../index>`.
- For a more technical description of QL, see :doc:`About QL <about-ql>`.
- To find out more about how to write your own queries, try working through the :doc:`QL detective tutorials <beginner/ql-tutorials>`.
- For an overview of the other available resources, see :doc:`Learning CodeQL <../index>`.
- For a more technical description of the underlying language, see :doc:`About QL <about-ql>`.

Просмотреть файл

@ -4,9 +4,9 @@ Tutorial: Annotations
Overview
--------
Snapshots of Java projects contain information about all annotations attached to program elements.
CodeQL databases of Java projects contain information about all annotations attached to program elements.
In QL, annotations are represented as follows:
Annotations are represented by the following CodeQL classes:
- The class ``Annotatable`` represents all entities that may have an annotation attached to them (that is, packages, reference types, fields, methods, and local variables).
- The class ``AnnotationType`` represents a Java annotation type, such as ``java.lang.Override``; annotation types are interfaces.
@ -23,7 +23,7 @@ As an example, recall that the Java standard library defines an annotation ``Sup
String[] value;
}
In QL, ``SuppressWarnings`` is represented as an ``AnnotationType``, with ``value`` as its only ``AnnotationElement``.
``SuppressWarnings`` is represented as an ``AnnotationType``, with ``value`` as its only ``AnnotationElement``.
A typical usage of ``SuppressWarnings`` would be the following annotation to prevent a warning about using raw types:
@ -35,7 +35,7 @@ A typical usage of ``SuppressWarnings`` would be the following annotation to pre
}
}
In QL, the expression ``@SuppressWarnings("rawtypes")`` is represented as an ``Annotation``. The string literal ``"rawtypes"`` is used to initialize the annotation element ``value``, and its value can be extracted from the annotation by means of the ``getValue`` predicate.
The expression ``@SuppressWarnings("rawtypes")`` is represented as an ``Annotation``. The string literal ``"rawtypes"`` is used to initialize the annotation element ``value``, and its value can be extracted from the annotation by means of the ``getValue`` predicate.
We could then write the following query to find all ``@SuppressWarnings`` annotations attached to constructors, and return both the annotation itself and the value of its ``value`` element:
@ -101,7 +101,7 @@ As a first step, let us write a query that finds all ``@Override`` annotations.
where ann.getType().hasQualifiedName("java.lang", "Override")
select ann
As always, it is a good idea to try this query on a Java snapshot to make sure it actually produces some results. On the earlier example, it should find the annotation on ``Sub1.m``. Next, we encapsulate the concept of an ``@Override`` annotation as a QL class:
As always, it is a good idea to try this query on a CodeQL database for a Java project to make sure it actually produces some results. On the earlier example, it should find the annotation on ``Sub1.m``. Next, we encapsulate the concept of an ``@Override`` annotation as a CodeQL class:
::
@ -147,7 +147,7 @@ For example, consider the following example program:
Here, both ``A.m`` and ``A.n`` are marked as deprecated. Methods ``n`` and ``r`` both call ``m``, but note that ``n`` itself is deprecated, so we probably should not warn about this call.
Like in the previous example, we start by defining a QL class for representing ``@Deprecated`` annotations:
Like in the previous example, we start by defining a class for representing ``@Deprecated`` annotations:
.. code-block:: ql
@ -204,7 +204,7 @@ For instance, consider this slightly updated example:
Here, the programmer has explicitly suppressed warnings about deprecated calls in ``A.r``, so our query should not flag the call to ``A.m`` any more.
To do so, we first introduce a QL class for representing all ``@SuppressWarnings`` annotations where the string ``deprecated`` occurs among the list of warnings to suppress:
To do so, we first introduce a class for representing all ``@SuppressWarnings`` annotations where the string ``deprecated`` occurs among the list of warnings to suppress:
.. code-block:: ql
@ -238,6 +238,6 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress
What next?
----------
- Take a look at some of the other tutorials: :doc:`Tutorial: Javadoc <javadoc>`, :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the QL standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Take a look at some of the other tutorials: :doc:`Tutorial: Javadoc <javadoc>` and :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.

Просмотреть файл

@ -15,7 +15,7 @@ Statement classes
This table lists all subclasses of `Stmt`_.
+------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+---------------------------------------------+
| Statement syntax | QL class | Superclasses | Remarks |
| Statement syntax | CodeQL class | Superclasses | Remarks |
+========================================================================+===========================================================================================================================================================+===================================+=============================================+
| ``;`` | `EmptyStmt <https://help.semmle.com/qldoc/java/semmle/code/java/Statement.qll/type.Statement$EmptyStmt.html>`__ | | |
+------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------+---------------------------------------------+
@ -87,7 +87,7 @@ Literals
All classes in this subsection are subclasses of `Literal <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Literal.html>`__.
+---------------------------+--------------------------+
| Expression syntax example | QL class |
| Expression syntax example | CodeQL class |
+===========================+==========================+
| ``true`` | ``BooleanLiteral`` |
+---------------------------+--------------------------+
@ -112,7 +112,7 @@ Unary expressions
All classes in this subsection are subclasses of `UnaryExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$UnaryExpr.html>`__.
+---------------------------+-----------------+---------------------+---------------------------------------------------+
| Expression syntax example | QL class | Superclasses | Remarks |
| Expression syntax example | CodeQL class | Superclasses | Remarks |
+===========================+=================+=====================+===================================================+
| ``x++`` | ``PostIncExpr`` | ``UnaryAssignExpr`` | |
+---------------------------+-----------------+---------------------+---------------------------------------------------+
@ -137,7 +137,7 @@ Binary expressions
All classes in this subsection are subclasses of `BinaryExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$BinaryExpr.html>`__.
+---------------------------+--------------------+--------------------+
| Expression syntax example | QL class | Superclasses |
| Expression syntax example | CodeQL class | Superclasses |
+===========================+====================+====================+
| ``x * y`` | ``MulExpr`` | |
+---------------------------+--------------------+--------------------+
@ -184,7 +184,7 @@ Assignment expressions
All classes in this table are subclasses of `Assignment <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$Assignment.html>`__.
+---------------------------+-----------------------+--------------+
| Expression syntax example | QL class | Superclasses |
| Expression syntax example | CodeQL class | Superclasses |
+===========================+=======================+==============+
| ``x = y`` | ``AssignExpr`` | |
+---------------------------+-----------------------+--------------+
@ -215,7 +215,7 @@ Accesses
~~~~~~~~
+--------------------------------------+-------------------------------------------------------------------------------------------------------------------------+
| Expression syntax examples | QL class |
| Expression syntax examples | CodeQL class |
+======================================+=========================================================================================================================+
| ``this`` | `ThisAccess <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$ThisAccess.html>`__ |
+--------------------------------------+ +
@ -250,7 +250,7 @@ Miscellaneous
~~~~~~~~~~~~~
+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+
| Expression syntax examples | QL class | Remarks |
| Expression syntax examples | CodeQL class | Remarks |
+==================================================================+=======================================================================================================================+=============================================================================+
| ``(int) f`` | `CastExpr <https://help.semmle.com/qldoc/java/semmle/code/java/Expr.qll/type.Expr$CastExpr.html>`__ | |
+------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------+

Просмотреть файл

@ -4,7 +4,7 @@ Tutorial: Navigating the call graph
Call graph API
--------------
The QL Java library provides two abstract classes for representing a program's call graph: ``Callable`` and ``Call``. The former is simply the common superclass of ``Method`` and ``Constructor``, the latter is a common superclass of ``MethodAccess``, ``ClassInstanceExpression``, ``ThisConstructorInvocationStmt`` and ``SuperConstructorInvocationStmt``. Simply put, a ``Callable`` is something that can be invoked, and a ``Call`` is something that invokes a ``Callable``.
The CodeQL library for Java provides two abstract classes for representing a program's call graph: ``Callable`` and ``Call``. The former is simply the common superclass of ``Method`` and ``Constructor``, the latter is a common superclass of ``MethodAccess``, ``ClassInstanceExpression``, ``ThisConstructorInvocationStmt`` and ``SuperConstructorInvocationStmt``. Simply put, a ``Callable`` is something that can be invoked, and a ``Call`` is something that invokes a ``Callable``.
For example, in the following program all callables and calls have been annotated with comments:
@ -160,6 +160,6 @@ Finally, on many Java projects there are methods that are invoked indirectly by
What next?
----------
- Find out how to query metadata and white space: :doc:`Tutorial: Annotations <annotations>`, :doc:`Tutorial: Javadoc <javadoc>`, :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the QL standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out how to query metadata and white space: :doc:`Tutorial: Annotations <annotations>`, :doc:`Tutorial: Javadoc <javadoc>`, and :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.

Просмотреть файл

@ -4,10 +4,10 @@ Analyzing data flow in Java
Overview
--------
This topic describes how data flow analysis is implemented in the QL for Java library and includes examples to help you write your own data flow queries.
The following sections describe how to utilize the QL libraries for local data flow, global data flow and taint tracking.
This topic describes how data flow analysis is implemented in the CodeQL libraries for Java and includes examples to help you write your own data flow queries.
The following sections describe how to utilize the libraries for local data flow, global data flow, and taint tracking.
For a more general introduction to modeling data flow in QL, see :doc:`Introduction to data flow analysis in QL <../intro-to-data-flow>`.
For a more general introduction to modeling data flow, see :doc:`Introduction to data flow analysis with CodeQL <../intro-to-data-flow>`.
Local data flow
---------------

Просмотреть файл

@ -22,12 +22,12 @@ If ``l`` is bigger than 2\ :sup:`31`\ - 1 (the largest positive value of type ``
All primitive numeric types have a maximum value, beyond which they will wrap around to their lowest possible value (called an "overflow"). For ``int``, this maximum value is 2\ :sup:`31`\ - 1. Type ``long`` can accommodate larger values up to a maximum of 2\ :sup:`63`\ - 1. In this example, this means that ``l`` can take on a value that is higher than the maximum for type ``int``; ``i`` will never be able to reach this value, instead overflowing and returning to a low value.
We will develop a query that finds code that looks like it might exhibit this kind of behavior. We will be using several of the standard QL library classes for representing statements and functions, a full list of which can be found in the :doc:`AST class reference <ast-class-reference>`.
We will develop a query that finds code that looks like it might exhibit this kind of behavior. We will be using several of the standard library classes for representing statements and functions, a full list of which can be found in the :doc:`AST class reference <ast-class-reference>`.
Initial query
-------------
We start out by writing a query that finds less-than expressions (QL class ``LTExpr``) where the left operand is of type ``int`` and the right operand is of type ``long``:
We start out by writing a query that finds less-than expressions (CodeQL class ``LTExpr``) where the left operand is of type ``int`` and the right operand is of type ``long``:
.. code-block:: ql
@ -57,7 +57,7 @@ Notice that we use the predicate ``getType`` (available on all subclasses of ``E
The class ``LoopStmt`` is a common superclass of all loops, including, in particular, ``for`` loops as in our example above. While different kinds of loops have different syntax, they all have a loop condition, which can be accessed through predicate ``getCondition``. We use the reflexive transitive closure operator ``*`` applied to the ``getAChildExpr`` predicate to express the requirement that ``expr`` should be nested inside the loop condition. In particular, it can be the loop condition itself.
The final conjunct in the ``where`` clause takes advantage of the fact that QL predicates can return more than one value (they are really relations). In particular, ``getAnOperand`` may return *either* operand of ``expr``, so ``expr.getAnOperand().isCompileTimeConstant()`` holds if at least one of the operands is constant. Negating this condition means that the query will only find expressions where *neither* of the operands is constant.
The final conjunct in the ``where`` clause takes advantage of the fact that `predicates <https://help.semmle.com/QL/ql-handbook/predicates.html>`__ can return more than one value (they are really relations). In particular, ``getAnOperand`` may return *either* operand of ``expr``, so ``expr.getAnOperand().isCompileTimeConstant()`` holds if at least one of the operands is constant. Negating this condition means that the query will only find expressions where *neither* of the operands is constant.
Generalizing the query
----------------------
@ -76,7 +76,7 @@ In order to compare the ranges of types, we define a predicate that returns the
(pt.hasName("long") and result=64)
}
We now want to generalize our query to apply to any comparison where the width of the type on the smaller end of the comparison is less than the width of the type on the greater end. Let us call such a comparison *overflow prone*, and introduce an abstract QL class to model it:
We now want to generalize our query to apply to any comparison where the width of the type on the smaller end of the comparison is less than the width of the type on the greater end. Let us call such a comparison *overflow prone*, and introduce an abstract class to model it:
.. code-block:: ql
@ -121,6 +121,6 @@ Now we rewrite our query to make use of these new classes:
What next?
----------
- Have a look at some of the other tutorials: :doc:`Tutorial: Types and the class hierarchy <types-class-hierarchy>`, :doc:`Tutorial: Navigating the call graph <call-graph>`, :doc:`Tutorial: Annotations <annotations>`, :doc:`Tutorial: Javadoc <javadoc>`, :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the QL standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Have a look at some of the other tutorials: :doc:`Tutorial: Types and the class hierarchy <types-class-hierarchy>`, :doc:`Tutorial: Navigating the call graph <call-graph>`, :doc:`Tutorial: Annotations <annotations>`, :doc:`Tutorial: Javadoc <javadoc>`, and :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.

Просмотреть файл

@ -1,25 +1,25 @@
Introducing the QL libraries for Java
=====================================
Introducing the CodeQL libraries for Java
=========================================
Overview
--------
There is an extensive QL library for analyzing Java code. The QL classes in this library present the data from a snapshot database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks.
There is an extensive library for analyzing CodeQL databases extracted from Java projects. The classes in this library present the data from a database in an object-oriented form and provide abstractions and predicates to help you with common analysis tasks.
The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``java.qll`` imports all other standard library modules, so you can include the complete library by beginning your query with:
The library is implemented as a set of QL modules, that is, files with the extension ``.qll``. The module ``java.qll`` imports all the core Java library modules, so you can include the complete library by beginning your query with:
.. code-block:: ql
import java
The rest of this topic briefly summarizes the most important QL classes and predicates provided by this library.
The rest of this topic briefly summarizes the most important classes and predicates provided by this library.
The example queries in this topic illustrate the types of results returned by different library classes. The results themselves are not interesting but can be used as the basis for developing a more complex query. The tutorial topics show how you can take a simple query and fine-tune it to find precisely the results you're interested in.
Summary of the library classes
------------------------------
The most important classes in the standard QL Java library can be grouped into five main categories:
The most important classes in the standard Java library can be grouped into five main categories:
#. Classes for representing program elements (such as classes and methods)
#. Classes for representing AST nodes (such as statements and expressions)
@ -89,7 +89,7 @@ Several more specialized classes are available as well:
- A ``LocalClass``, which is `a class declared inside a method or constructor <http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html>`__.
- An ``AnonymousClass``, which is an `anonymous class <http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html>`__.
Finally, the QL library also has a number of singleton classes that wrap frequently used Java standard library classes: ``TypeObject``, ``TypeCloneable``, ``TypeRuntime``, ``TypeSerializable``, ``TypeString``, ``TypeSystem`` and ``TypeClass``. Each QL class represents the standard Java class suggested by its name.
Finally, the library also has a number of singleton classes that wrap frequently used Java standard library classes: ``TypeObject``, ``TypeCloneable``, ``TypeRuntime``, ``TypeSerializable``, ``TypeString``, ``TypeSystem`` and ``TypeClass``. Each CodeQL class represents the standard Java class suggested by its name.
As an example, we can write a query that finds all nested classes that directly extend ``Object``:
@ -160,7 +160,7 @@ As an example, the following query finds all type variables with type bound ``Nu
`See this in the query console <https://lgtm.com/query/690010016/>`__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *gradle/gradle* and *hibernate/hibernate-orm* projects all contained examples of this pattern.
For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In QL, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``:
For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In the CodeQL libraries, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``:
.. code-block:: ql
@ -342,7 +342,7 @@ For example, the following query finds methods with a `cyclomatic complexity <ht
Call graph
----------
Snapshots databases generated from Java code bases include precomputed information about the program's call graph, that is, which methods or constructors a given call may dispatch to at runtime.
CodeQL databases generated from Java code bases include precomputed information about the program's call graph, that is, which methods or constructors a given call may dispatch to at runtime.
The class ``Callable``, introduced above, includes both methods and constructors. Call expressions are abstracted using class ``Call``, which includes method calls, ``new`` expressions, and explicit constructor calls using ``this`` or ``super``.
@ -376,6 +376,6 @@ For more information about callables and calls, see the :doc:`call graph tutoria
What next?
----------
- Experiment with the worked examples in the QL for Java tutorial topics: :doc:`Types and the class hierarchy <types-class-hierarchy>`, :doc:`Expressions and statements <expressions-statements>`, :doc:`Navigating the call graph <call-graph>`, :doc:`Annotations <annotations>`, :doc:`Javadoc <javadoc>` and :doc:`Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the QL standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Experiment with the worked examples in the CodeQL for Java tutorial topics: :doc:`Types and the class hierarchy <types-class-hierarchy>`, :doc:`Expressions and statements <expressions-statements>`, :doc:`Navigating the call graph <call-graph>`, :doc:`Annotations <annotations>`, :doc:`Javadoc <javadoc>` and :doc:`Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.

Просмотреть файл

@ -49,7 +49,7 @@ The ``JavadocTag`` has several subclasses representing specific kinds of Javadoc
Example: Finding spurious @param tags
-------------------------------------
As an example of using the QL Javadoc API, let us write a query that finds ``@param`` tags that refer to a non-existent parameter.
As an example of using the CodeQL Javadoc API, let us write a query that finds ``@param`` tags that refer to a non-existent parameter.
For example, consider the following program:
@ -110,7 +110,7 @@ For example, consider the following Java program:
Notice that the Javadoc comment of ``A.foo`` documents two thrown exceptions: ``IOException`` and ``RuntimeException``. The former is clearly spurious: ``A.foo`` does not have a ``throws IOException`` clause, and thus cannot throw this kind of exception. On the other hand, ``RuntimeException`` is an unchecked exception, so it can be thrown even if there is no explicit ``throws`` clause listing it. Therefore, our query should flag the ``@throws`` tag for ``IOException``, but not the one for ``RuntimeException.``
Recall from above that QL represents ``@throws`` tags using class ``ThrowsTag``. This class does not provide a member predicate for determining the exception type that is being documented, so we first need to implement our own version. A simple version might look as follows:
Recall from above that the CodeQL library represents ``@throws`` tags using class ``ThrowsTag``. This class does not provide a member predicate for determining the exception type that is being documented, so we first need to implement our own version. A simple version might look as follows:
.. code-block:: ql
@ -170,7 +170,7 @@ This program defines its own class ``IOException``, which is unrelated to the cl
As an example of the second problem, method ``A.foo`` from our previous example was annotated with a ``@throws RuntimeException`` tag. Our current version of ``mayThrow``, however, would think that ``A.foo`` cannot throw a ``RuntimeException``, and thus flag the tag as spurious.
We can make ``mayThrow`` less restrictive by introducing a new QL class to represent unchecked exceptions, which are just the subtypes of ``java.lang.RuntimeException`` and ``java.lang.Error``:
We can make ``mayThrow`` less restrictive by introducing a new class to represent unchecked exceptions, which are just the subtypes of ``java.lang.RuntimeException`` and ``java.lang.Error``:
.. code-block:: ql
@ -220,5 +220,5 @@ What next?
----------
- Find out how you can use the location API to define queries on whitespace: :doc:`Tutorial: Working with source locations <source-locations>`.
- Find out how specific classes in the AST are represented in the QL standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out how specific classes in the AST are represented in the standard library for Java: :doc:`AST class reference <ast-class-reference>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.

Просмотреть файл

@ -1,5 +1,5 @@
QL for Java
===========
CodeQL for Java
===============
.. toctree::
:glob:
@ -15,31 +15,31 @@ QL for Java
source-locations
ast-class-reference
These topics provide an overview of the QL Java standard library and show examples of how to use them.
These topics provide an overview of the CodeQL libraries for Java and show examples of how to use them.
- `Basic Java QL query <https://lgtm.com/help/lgtm/console/ql-java-basic-example>`__ describes how to write and run queries using LGTM.
- `Basic Java query <https://lgtm.com/help/lgtm/console/ql-java-basic-example>`__ describes how to write and run queries using LGTM.
- :doc:`Introducing the QL libraries for Java <introduce-libraries-java>` an introduction to the organization of the standard libraries used to write queries for Java code.
- :doc:`Introducing the CodeQL libraries for Java <introduce-libraries-java>` introduces the standard libraries used to write queries for Java code.
- :doc:`Tutorial: Analyzing data flow in Java <dataflow>` demonstrates how to write queries using the standard QL for Java data flow and taint tracking libraries.
- :doc:`Tutorial: Analyzing data flow in Java <dataflow>` demonstrates how to write queries using the standard data flow and taint tracking libraries for Java.
- :doc:`Tutorial: Types and the class hierarchy <types-class-hierarchy>` introduces the QL classes for representing a program's class hierarchy by means of examples.
- :doc:`Tutorial: Types and the class hierarchy <types-class-hierarchy>` introduces the classes for representing a program's class hierarchy by means of examples.
- :doc:`Tutorial: Expressions and statements <expressions-statements>` introduces the QL classes for representing a program's syntactic structure by means of examples.
- :doc:`Tutorial: Expressions and statements <expressions-statements>` introduces the classes for representing a program's syntactic structure by means of examples.
- :doc:`Tutorial: Navigating the call graph <call-graph>` a worked example of how to write a query that navigates a program's call graph to find unused methods.
- :doc:`Tutorial: Navigating the call graph <call-graph>` is a worked example of how to write a query that navigates a program's call graph to find unused methods.
- :doc:`Tutorial: Annotations <annotations>` introduces the QL classes for representing annotations by means of examples.
- :doc:`Tutorial: Annotations <annotations>` introduces the classes for representing annotations by means of examples.
- :doc:`Tutorial: Javadoc <javadoc>` introduces the QL classes for representing Javadoc comments by means of examples.
- :doc:`Tutorial: Javadoc <javadoc>` introduces the classes for representing Javadoc comments by means of examples.
- :doc:`Tutorial: Working with source locations <source-locations>` a worked example of how to write a query that uses the location information provided in the snapshot for finding likely bugs.
- :doc:`Tutorial: Working with source locations <source-locations>` is a worked example of how to write a query that uses the location information provided in the database for finding likely bugs.
- :doc:`AST class reference <ast-class-reference>` an overview of all AST classes in the QL standard library for Java.
- :doc:`AST class reference <ast-class-reference>` gives an overview of all AST classes in the standard CodeQL library for Java.
Other resources
---------------
- For examples of how to query common Java elements, see the `Java QL cookbook <https://help.semmle.com/wiki/display/CBJAVA>`__.
- For the queries used in LGTM, display a `Java query <https://lgtm.com/search?q=language%3Ajava&t=rules>`__ and click **Open in query console** to see the QL code used to find alerts.
- For more information about the Java QL library see the `QL library for Java <https://help.semmle.com/qldoc/java>`__.
- For examples of how to query common Java elements, see the `Java cookbook <https://help.semmle.com/wiki/display/CBJAVA>`__.
- For the queries used in LGTM, display a `Java query <https://lgtm.com/search?q=language%3Ajava&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for Java see the `CodeQL library for Java <https://help.semmle.com/qldoc/java>`__.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше