mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Merge branch 'main' into fix-barriers-in-invalid-pointer-deref
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `_Float128x` type is no longer exposed as a builtin type. As this type could not occur any code base, this should only affect queries that explicitly looked at the builtin types.
|
||||
@@ -814,9 +814,6 @@ private predicate floatingPointTypeMapping(
|
||||
// _Float128
|
||||
kind = 49 and base = 2 and domain = TRealDomain() and realKind = 49 and extended = false
|
||||
or
|
||||
// _Float128x
|
||||
kind = 50 and base = 2 and domain = TRealDomain() and realKind = 50 and extended = true
|
||||
or
|
||||
// _Float16
|
||||
kind = 52 and base = 2 and domain = TRealDomain() and realKind = 52 and extended = false
|
||||
or
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CppOldDataFlow>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CppOldDataFlow>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Provides C++-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
@@ -13,7 +13,7 @@ module Public {
|
||||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module CppOldDataFlow implements DataFlowParameter {
|
||||
module CppOldDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CppDataFlow>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CppDataFlow>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Provides IR-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
@@ -13,7 +13,7 @@ module Public {
|
||||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module CppDataFlow implements DataFlowParameter {
|
||||
module CppDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
||||
@@ -1078,7 +1078,7 @@ private IRVariable getIRVariableForParameterNode(ParameterNode p) {
|
||||
|
||||
/** Holds if `v` is the source variable corresponding to the parameter represented by `p`. */
|
||||
pragma[nomagic]
|
||||
private predicate parameterNodeHasSourceVariable(ParameterNode p, Ssa::SourceIRVariable v) {
|
||||
private predicate parameterNodeHasSourceVariable(ParameterNode p, Ssa::SourceVariable v) {
|
||||
v.getIRVariable() = getIRVariableForParameterNode(p) and
|
||||
exists(Position pos | p.isParameterOf(_, pos) |
|
||||
pos instanceof DirectPosition and
|
||||
|
||||
@@ -781,26 +781,12 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
|
||||
override Expr getDefinedExpr() { result = operand.getDef().getUnconvertedResultExpression() }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate indirectReturnOutNodeOperand0(CallInstruction call, Operand operand, int indirectionIndex) {
|
||||
Ssa::hasRawIndirectInstruction(call, indirectionIndex) and
|
||||
operandForFullyConvertedCall(operand, call)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate indirectReturnOutNodeInstruction0(
|
||||
CallInstruction call, Instruction instr, int indirectionIndex
|
||||
) {
|
||||
Ssa::hasRawIndirectInstruction(call, indirectionIndex) and
|
||||
instructionForFullyConvertedCall(instr, call)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is an indirect operand with columns `(operand, indirectionIndex)`, and
|
||||
* `operand` represents a use of the fully converted value of `call`.
|
||||
*/
|
||||
private predicate hasOperand(Node node, CallInstruction call, int indirectionIndex, Operand operand) {
|
||||
indirectReturnOutNodeOperand0(call, operand, indirectionIndex) and
|
||||
operandForFullyConvertedCall(operand, call) and
|
||||
hasOperandAndIndex(node, operand, indirectionIndex)
|
||||
}
|
||||
|
||||
@@ -813,7 +799,7 @@ private predicate hasOperand(Node node, CallInstruction call, int indirectionInd
|
||||
private predicate hasInstruction(
|
||||
Node node, CallInstruction call, int indirectionIndex, Instruction instr
|
||||
) {
|
||||
indirectReturnOutNodeInstruction0(call, instr, indirectionIndex) and
|
||||
instructionForFullyConvertedCall(instr, call) and
|
||||
hasInstructionAndIndex(node, instr, indirectionIndex)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,32 +10,35 @@ private import ssa0.SsaInternals as SsaInternals0
|
||||
import SsaInternalsCommon
|
||||
|
||||
private module SourceVariables {
|
||||
int getMaxIndirectionForIRVariable(IRVariable var) {
|
||||
exists(Type type, boolean isGLValue |
|
||||
var.getLanguageType().hasType(type, isGLValue) and
|
||||
if isGLValue = true
|
||||
then result = 1 + getMaxIndirectionsForType(type)
|
||||
else result = getMaxIndirectionsForType(type)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TSourceVariable =
|
||||
TSourceIRVariable(BaseIRVariable baseVar, int ind) {
|
||||
ind = [0 .. getMaxIndirectionForIRVariable(baseVar.getIRVariable())]
|
||||
} or
|
||||
TCallVariable(AllocationInstruction call, int ind) {
|
||||
ind = [0 .. countIndirectionsForCppType(getResultLanguageType(call))]
|
||||
TMkSourceVariable(SsaInternals0::SourceVariable base, int ind) {
|
||||
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
}
|
||||
|
||||
abstract class SourceVariable extends TSourceVariable {
|
||||
class SourceVariable extends TSourceVariable {
|
||||
SsaInternals0::SourceVariable base;
|
||||
int ind;
|
||||
|
||||
bindingset[ind]
|
||||
SourceVariable() { any() }
|
||||
SourceVariable() { this = TMkSourceVariable(base, ind) }
|
||||
|
||||
/** Gets the IR variable associated with this `SourceVariable`, if any. */
|
||||
IRVariable getIRVariable() { result = base.(BaseIRVariable).getIRVariable() }
|
||||
|
||||
/**
|
||||
* Gets the base source variable (i.e., the variable without any
|
||||
* indirections) of this source variable.
|
||||
*/
|
||||
SsaInternals0::SourceVariable getBaseVariable() { result = base }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
string toString() {
|
||||
ind = 0 and
|
||||
result = this.getBaseVariable().toString()
|
||||
or
|
||||
ind > 0 and
|
||||
result = this.getBaseVariable().toString() + " indirection"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of loads performed on the base source variable
|
||||
@@ -43,65 +46,19 @@ private module SourceVariables {
|
||||
*/
|
||||
int getIndirection() { result = ind }
|
||||
|
||||
/**
|
||||
* Gets the base source variable (i.e., the variable without any
|
||||
* indirections) of this source variable.
|
||||
*/
|
||||
abstract BaseSourceVariable getBaseVariable();
|
||||
|
||||
/** Holds if this variable is a glvalue. */
|
||||
predicate isGLValue() { none() }
|
||||
predicate isGLValue() { ind = 0 }
|
||||
|
||||
/**
|
||||
* Gets the type of this source variable. If `isGLValue()` holds, then
|
||||
* the type of this source variable should be thought of as "pointer
|
||||
* to `getType()`".
|
||||
*/
|
||||
abstract DataFlowType getType();
|
||||
}
|
||||
|
||||
class SourceIRVariable extends SourceVariable, TSourceIRVariable {
|
||||
BaseIRVariable var;
|
||||
|
||||
SourceIRVariable() { this = TSourceIRVariable(var, ind) }
|
||||
|
||||
IRVariable getIRVariable() { result = var.getIRVariable() }
|
||||
|
||||
override BaseIRVariable getBaseVariable() { result.getIRVariable() = this.getIRVariable() }
|
||||
|
||||
override string toString() {
|
||||
ind = 0 and
|
||||
result = this.getIRVariable().toString()
|
||||
or
|
||||
ind > 0 and
|
||||
result = this.getIRVariable().toString() + " indirection"
|
||||
DataFlowType getType() {
|
||||
if this.isGLValue()
|
||||
then result = base.getType()
|
||||
else result = getTypeImpl(base.getType(), ind - 1)
|
||||
}
|
||||
|
||||
override predicate isGLValue() { ind = 0 }
|
||||
|
||||
override DataFlowType getType() {
|
||||
if ind = 0 then result = var.getType() else result = getTypeImpl(var.getType(), ind - 1)
|
||||
}
|
||||
}
|
||||
|
||||
class CallVariable extends SourceVariable, TCallVariable {
|
||||
AllocationInstruction call;
|
||||
|
||||
CallVariable() { this = TCallVariable(call, ind) }
|
||||
|
||||
AllocationInstruction getCall() { result = call }
|
||||
|
||||
override BaseCallVariable getBaseVariable() { result.getCallInstruction() = call }
|
||||
|
||||
override string toString() {
|
||||
ind = 0 and
|
||||
result = "Call"
|
||||
or
|
||||
ind > 0 and
|
||||
result = "Call indirection"
|
||||
}
|
||||
|
||||
override DataFlowType getType() { result = getTypeImpl(call.getResultType(), ind) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +94,9 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
|
||||
|
||||
cached
|
||||
private newtype TDefOrUseImpl =
|
||||
TDefImpl(Operand address, int indirectionIndex) {
|
||||
exists(Instruction base | isDef(_, _, address, base, _, indirectionIndex) |
|
||||
TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) {
|
||||
isDef(_, _, address, base, _, indirectionIndex) and
|
||||
(
|
||||
// We only include the definition if the SSA pruning stage
|
||||
// concluded that the definition is live after the write.
|
||||
any(SsaInternals0::Def def).getAddressOperand() = address
|
||||
@@ -148,8 +106,8 @@ private newtype TDefOrUseImpl =
|
||||
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
|
||||
)
|
||||
} or
|
||||
TUseImpl(Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, _, _, indirectionIndex) and
|
||||
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, base, _, indirectionIndex) and
|
||||
not isDef(_, _, operand, _, _, _)
|
||||
} or
|
||||
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||
@@ -236,7 +194,7 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl {
|
||||
|
||||
/**
|
||||
* Gets the instruction that computes the base of this definition or use.
|
||||
* This is always a `VariableAddressInstruction` or an `AllocationInstruction`.
|
||||
* This is always a `VariableAddressInstruction` or an `CallInstruction`.
|
||||
*/
|
||||
abstract BaseSourceVariableInstruction getBase();
|
||||
|
||||
@@ -308,15 +266,17 @@ abstract class DefImpl extends DefOrUseImpl {
|
||||
}
|
||||
|
||||
private class DirectDef extends DefImpl, TDefImpl {
|
||||
DirectDef() { this = TDefImpl(address, ind) }
|
||||
BaseSourceVariableInstruction base;
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
|
||||
DirectDef() { this = TDefImpl(base, address, ind) }
|
||||
|
||||
override int getIndirection() { isDef(_, _, address, _, result, ind) }
|
||||
override BaseSourceVariableInstruction getBase() { result = base }
|
||||
|
||||
override Node0Impl getValue() { isDef(_, result, address, _, _, _) }
|
||||
override int getIndirection() { isDef(_, _, address, base, result, ind) }
|
||||
|
||||
override predicate isCertain() { isDef(true, _, address, _, _, ind) }
|
||||
override Node0Impl getValue() { isDef(_, result, address, base, _, _) }
|
||||
|
||||
override predicate isCertain() { isDef(true, _, address, base, _, ind) }
|
||||
}
|
||||
|
||||
private class IteratorDef extends DefImpl, TIteratorDef {
|
||||
@@ -359,6 +319,7 @@ abstract class UseImpl extends DefOrUseImpl {
|
||||
|
||||
abstract private class OperandBasedUse extends UseImpl {
|
||||
Operand operand;
|
||||
BaseSourceVariableInstruction base;
|
||||
|
||||
bindingset[ind]
|
||||
OperandBasedUse() { any() }
|
||||
@@ -366,50 +327,44 @@ abstract private class OperandBasedUse extends UseImpl {
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
|
||||
// predicate's implementation.
|
||||
exists(BaseSourceVariableInstruction base | base = this.getBase() |
|
||||
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||
then
|
||||
exists(Operand op, int indirectionIndex, int indirection |
|
||||
indirectionIndex = this.getIndirectionIndex() and
|
||||
indirection = this.getIndirection() and
|
||||
op =
|
||||
min(Operand cand, int i |
|
||||
isUse(_, cand, base, indirection, indirectionIndex) and
|
||||
block.getInstruction(i) = cand.getUse()
|
||||
|
|
||||
cand order by i
|
||||
) and
|
||||
block.getInstruction(index) = op.getUse()
|
||||
)
|
||||
else operand.getUse() = block.getInstruction(index)
|
||||
)
|
||||
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||
then
|
||||
exists(Operand op, int indirectionIndex, int indirection |
|
||||
indirectionIndex = this.getIndirectionIndex() and
|
||||
indirection = this.getIndirection() and
|
||||
op =
|
||||
min(Operand cand, int i |
|
||||
isUse(_, cand, base, indirection, indirectionIndex) and
|
||||
block.getInstruction(i) = cand.getUse()
|
||||
|
|
||||
cand order by i
|
||||
) and
|
||||
block.getInstruction(index) = op.getUse()
|
||||
)
|
||||
else operand.getUse() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
final override BaseSourceVariableInstruction getBase() { result = base }
|
||||
|
||||
final Operand getOperand() { result = operand }
|
||||
|
||||
final override Cpp::Location getLocation() { result = operand.getLocation() }
|
||||
}
|
||||
|
||||
private class DirectUse extends OperandBasedUse, TUseImpl {
|
||||
DirectUse() { this = TUseImpl(operand, ind) }
|
||||
DirectUse() { this = TUseImpl(base, operand, ind) }
|
||||
|
||||
override int getIndirection() { isUse(_, operand, _, result, ind) }
|
||||
override int getIndirection() { isUse(_, operand, base, result, ind) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, ind) }
|
||||
|
||||
override predicate isCertain() { isUse(true, operand, _, _, ind) }
|
||||
override predicate isCertain() { isUse(true, operand, base, _, ind) }
|
||||
|
||||
override Node getNode() { nodeHasOperand(result, operand, ind) }
|
||||
}
|
||||
|
||||
private class IteratorUse extends OperandBasedUse, TIteratorUse {
|
||||
BaseSourceVariableInstruction container;
|
||||
IteratorUse() { this = TIteratorUse(operand, base, ind) }
|
||||
|
||||
IteratorUse() { this = TIteratorUse(operand, container, ind) }
|
||||
|
||||
override int getIndirection() { isIteratorUse(container, operand, result, ind) }
|
||||
|
||||
override BaseSourceVariableInstruction getBase() { result = container }
|
||||
override int getIndirection() { isIteratorUse(base, operand, result, ind) }
|
||||
|
||||
override predicate isCertain() { none() }
|
||||
|
||||
|
||||
@@ -146,14 +146,6 @@ int countIndirectionsForCppType(LanguageType langType) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `CallInstruction` that calls an allocation function such
|
||||
* as `malloc` or `operator new`.
|
||||
*/
|
||||
class AllocationInstruction extends CallInstruction {
|
||||
AllocationInstruction() { this.getStaticCallTarget() instanceof Cpp::AllocationFunction }
|
||||
}
|
||||
|
||||
private predicate isIndirectionType(Type t) { t instanceof Indirection }
|
||||
|
||||
private predicate hasUnspecifiedBaseType(Indirection t, Type base) {
|
||||
@@ -368,17 +360,22 @@ newtype TBaseSourceVariable =
|
||||
// Each IR variable gets its own source variable
|
||||
TBaseIRVariable(IRVariable var) or
|
||||
// Each allocation gets its own source variable
|
||||
TBaseCallVariable(AllocationInstruction call)
|
||||
TBaseCallVariable(CallInstruction call) { not call.getResultIRType() instanceof IRVoidType }
|
||||
|
||||
abstract class BaseSourceVariable extends TBaseSourceVariable {
|
||||
abstract private class AbstractBaseSourceVariable extends TBaseSourceVariable {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the type of this base source variable. */
|
||||
abstract DataFlowType getType();
|
||||
final DataFlowType getType() { this.getLanguageType().hasUnspecifiedType(result, _) }
|
||||
|
||||
/** Gets the `CppType` of this base source variable. */
|
||||
abstract CppType getLanguageType();
|
||||
}
|
||||
|
||||
class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
|
||||
final class BaseSourceVariable = AbstractBaseSourceVariable;
|
||||
|
||||
class BaseIRVariable extends AbstractBaseSourceVariable, TBaseIRVariable {
|
||||
IRVariable var;
|
||||
|
||||
IRVariable getIRVariable() { result = var }
|
||||
@@ -387,19 +384,19 @@ class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
|
||||
|
||||
override string toString() { result = var.toString() }
|
||||
|
||||
override DataFlowType getType() { result = var.getType() }
|
||||
override CppType getLanguageType() { result = var.getLanguageType() }
|
||||
}
|
||||
|
||||
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
|
||||
AllocationInstruction call;
|
||||
class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable {
|
||||
CallInstruction call;
|
||||
|
||||
BaseCallVariable() { this = TBaseCallVariable(call) }
|
||||
|
||||
AllocationInstruction getCallInstruction() { result = call }
|
||||
CallInstruction getCallInstruction() { result = call }
|
||||
|
||||
override string toString() { result = call.toString() }
|
||||
|
||||
override DataFlowType getType() { result = call.getResultType() }
|
||||
override CppType getLanguageType() { result = getResultLanguageType(call) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -499,8 +496,7 @@ private class BaseIRVariableInstruction extends BaseSourceVariableInstruction,
|
||||
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable() = this.getIRVariable() }
|
||||
}
|
||||
|
||||
private class BaseAllocationInstruction extends BaseSourceVariableInstruction, AllocationInstruction
|
||||
{
|
||||
private class BaseCallInstruction extends BaseSourceVariableInstruction, CallInstruction {
|
||||
override BaseCallVariable getBaseSourceVariable() { result.getCallInstruction() = this }
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,12 @@ private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
|
||||
|
||||
private module SourceVariables {
|
||||
class SourceVariable instanceof BaseSourceVariable {
|
||||
string toString() { result = BaseSourceVariable.super.toString() }
|
||||
|
||||
class SourceVariable extends BaseSourceVariable {
|
||||
/**
|
||||
* Gets the base source variable of this `SourceVariable`.
|
||||
*/
|
||||
BaseSourceVariable getBaseVariable() { result = this }
|
||||
}
|
||||
|
||||
class SourceIRVariable = BaseIRVariable;
|
||||
|
||||
class CallVariable = BaseCallVariable;
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
|
||||
@@ -307,3 +307,8 @@ class SemConditionalExpr extends SemKnownExpr {
|
||||
branch = false and result = falseResult
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `upper = true` and `e <= bound` or `upper = false` and `e >= bound`. */
|
||||
predicate semHasConstantBoundConstantSpecific(SemExpr e, float bound, boolean upper) {
|
||||
Specific::hasConstantBoundConstantSpecific(e, bound, upper)
|
||||
}
|
||||
|
||||
@@ -434,6 +434,50 @@ module SemanticExprConfig {
|
||||
|
||||
/** Gets the expression associated with `instr`. */
|
||||
SemExpr getSemanticExpr(IR::Instruction instr) { result = Equiv::getEquivalenceClass(instr) }
|
||||
|
||||
private predicate typeBounds(SemType t, float lb, float ub) {
|
||||
exists(SemIntegerType integralType, float limit |
|
||||
integralType = t and limit = 2.pow(8 * integralType.getByteSize())
|
||||
|
|
||||
if integralType instanceof SemBooleanType
|
||||
then lb = 0 and ub = 1
|
||||
else
|
||||
if integralType.isSigned()
|
||||
then (
|
||||
lb = -(limit / 2) and ub = (limit / 2) - 1
|
||||
) else (
|
||||
lb = 0 and ub = limit - 1
|
||||
)
|
||||
)
|
||||
or
|
||||
// This covers all floating point types. The range is (-Inf, +Inf).
|
||||
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `upper = true` and `e <= bound` or `upper = false` and `e >= bound` based
|
||||
* only on type information.
|
||||
*/
|
||||
predicate hasConstantBoundConstantSpecific(Expr e, float bound, boolean upper) {
|
||||
exists(
|
||||
SemType converted, SemType unconverted, float unconvertedLb, float convertedLb,
|
||||
float unconvertedUb, float convertedUb
|
||||
|
|
||||
unconverted = getSemanticType(e.getUnconverted().getResultIRType()) and
|
||||
converted = getSemanticType(e.getConverted().getResultIRType()) and
|
||||
typeBounds(unconverted, unconvertedLb, unconvertedUb) and
|
||||
typeBounds(converted, convertedLb, convertedUb) and
|
||||
(
|
||||
upper = true and
|
||||
unconvertedUb < convertedUb and
|
||||
bound = unconvertedUb
|
||||
or
|
||||
upper = false and
|
||||
unconvertedLb > convertedLb and
|
||||
bound = unconvertedLb
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1;
|
||||
@@ -457,3 +501,5 @@ IRBound::Bound getCppBound(SemBound bound) { bound = result }
|
||||
SemGuard getSemanticGuard(IRGuards::IRGuardCondition guard) { result = guard }
|
||||
|
||||
IRGuards::IRGuardCondition getCppGuard(SemGuard guard) { guard = result }
|
||||
|
||||
predicate hasConstantBoundConstantSpecific = SemanticExprConfig::hasConstantBoundConstantSpecific/3;
|
||||
|
||||
@@ -74,7 +74,10 @@ module CppLangImplConstant implements LangSig<FloatDelta> {
|
||||
/**
|
||||
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
||||
*/
|
||||
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
|
||||
predicate hasConstantBound(SemExpr e, float bound, boolean upper, SemReason reason) {
|
||||
semHasConstantBoundConstantSpecific(e, bound, upper) and
|
||||
reason instanceof SemTypeReason
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
|
||||
|
||||
@@ -110,7 +110,7 @@ module CppLangImplRelative implements LangSig<FloatDelta> {
|
||||
/**
|
||||
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
||||
*/
|
||||
predicate hasConstantBound(SemExpr e, float bound, boolean upper) { none() }
|
||||
predicate hasConstantBound(SemExpr e, float bound, boolean upper, SemReason reason) { none() }
|
||||
|
||||
/**
|
||||
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
|
||||
|
||||
@@ -155,7 +155,7 @@ signature module LangSig<DeltaSig D> {
|
||||
/**
|
||||
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
||||
*/
|
||||
predicate hasConstantBound(SemExpr e, D::Delta bound, boolean upper);
|
||||
predicate hasConstantBound(SemExpr e, D::Delta bound, boolean upper, SemReason reason);
|
||||
|
||||
/**
|
||||
* Holds if `e >= bound + delta` (if `upper = false`) or `e <= bound + delta` (if `upper = true`).
|
||||
@@ -920,14 +920,15 @@ module RangeStage<
|
||||
* Holds if `e` has an upper (for `upper = true`) or lower
|
||||
* (for `upper = false`) bound of `b`.
|
||||
*/
|
||||
private predicate baseBound(SemExpr e, D::Delta b, boolean upper) {
|
||||
hasConstantBound(e, b, upper)
|
||||
private predicate baseBound(SemExpr e, D::Delta b, boolean upper, SemReason reason) {
|
||||
hasConstantBound(e, b, upper, reason)
|
||||
or
|
||||
upper = false and
|
||||
b = D::fromInt(0) and
|
||||
semPositive(e.(SemBitAndExpr).getAnOperand()) and
|
||||
// REVIEW: We let the language opt out here to preserve original results.
|
||||
not ignoreZeroLowerBound(e)
|
||||
not ignoreZeroLowerBound(e) and
|
||||
reason instanceof SemNoReason
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1055,11 +1056,10 @@ module RangeStage<
|
||||
origdelta = delta and
|
||||
reason instanceof SemNoReason
|
||||
or
|
||||
baseBound(e, delta, upper) and
|
||||
baseBound(e, delta, upper, reason) and
|
||||
b instanceof SemZeroBound and
|
||||
fromBackEdge = false and
|
||||
origdelta = delta and
|
||||
reason instanceof SemNoReason
|
||||
origdelta = delta
|
||||
or
|
||||
exists(SemSsaVariable v, SemSsaReadPositionBlock bb |
|
||||
boundedSsa(v, bb, b, delta, upper, fromBackEdge, origdelta, reason) and
|
||||
|
||||
@@ -20,7 +20,8 @@ private Instruction getABoundIn(SemBound b, IRFunction func) {
|
||||
pragma[inline]
|
||||
private predicate boundedImpl(Instruction i, Instruction b, int delta) {
|
||||
exists(SemBound bound, IRFunction func |
|
||||
semBounded(getSemanticExpr(i), bound, delta, true, _) and
|
||||
semBounded(getSemanticExpr(i), bound, delta, true,
|
||||
any(SemReason reason | not reason instanceof SemTypeReason)) and
|
||||
b = getABoundIn(bound, func) and
|
||||
i.getEnclosingIRFunction() = func
|
||||
)
|
||||
|
||||
@@ -608,7 +608,7 @@ case @builtintype.kind of
|
||||
| 47 = @std_float64 // _Float64
|
||||
| 48 = @float64x // _Float64x
|
||||
| 49 = @std_float128 // _Float128
|
||||
| 50 = @float128x // _Float128x
|
||||
// ... 50 _Float128x
|
||||
| 51 = @char8_t
|
||||
| 52 = @float16 // _Float16
|
||||
| 53 = @complex_float16 // _Complex _Float16
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
class BuiltinType extends @builtintype {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
predicate isFloat128xBuiltinType(BuiltinType type) {
|
||||
exists(int kind | builtintypes(type, _, kind, _, _, _) | kind = 50)
|
||||
}
|
||||
|
||||
from BuiltinType type, string name, int kind, int kind_new, int size, int sign, int alignment
|
||||
where
|
||||
builtintypes(type, name, kind, size, sign, alignment) and
|
||||
if isFloat128xBuiltinType(type) then kind_new = 1 else kind_new = kind
|
||||
select type, name, kind_new, size, sign, alignment
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Remove _Float128 type
|
||||
compatibility: partial
|
||||
builtintypes.rel: run builtintypes.qlo
|
||||
@@ -28,7 +28,8 @@ Instruction getABoundIn(SemBound b, IRFunction func) {
|
||||
pragma[inline]
|
||||
predicate boundedImpl(Instruction i, Instruction b, int delta) {
|
||||
exists(SemBound bound, IRFunction func |
|
||||
semBounded(getSemanticExpr(i), bound, delta, true, _) and
|
||||
semBounded(getSemanticExpr(i), bound, delta, true,
|
||||
any(SemReason reason | not reason instanceof SemTypeReason)) and
|
||||
b = getABoundIn(bound, func) and
|
||||
pragma[only_bind_out](i.getEnclosingIRFunction()) = func
|
||||
)
|
||||
@@ -93,7 +94,8 @@ predicate arrayTypeHasSizes(ArrayType arr, int baseTypeSize, int size) {
|
||||
bindingset[pai]
|
||||
pragma[inline_late]
|
||||
predicate constantUpperBounded(PointerArithmeticInstruction pai, int delta) {
|
||||
semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), delta, true, _)
|
||||
semBounded(getSemanticExpr(pai.getRight()), any(SemZeroBound b), delta, true,
|
||||
any(SemReason reason | not reason instanceof SemTypeReason))
|
||||
}
|
||||
|
||||
bindingset[pai, size]
|
||||
|
||||
@@ -195,18 +195,18 @@ int test13(char c, int i) {
|
||||
int z = i+1; // $ overflow=+
|
||||
range(z); // $ range="==InitializeParameter: i+1"
|
||||
range(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=- MISSING: range=>=1
|
||||
range((double)(c + i + uc + x + y + z)); // $ overflow=+ overflow=+- overflow=- MISSING: range=>=1
|
||||
range((double)(c + i + uc + x + y + z)); // $ overflow=+ overflow=+- overflow=- range=<=4294967295 MISSING: range=>=1
|
||||
return (double)(c + i + uc + x + y + z); // $ overflow=+- overflow=+ overflow=-
|
||||
}
|
||||
|
||||
// Regression test for ODASA-6013.
|
||||
int test14(int x) {
|
||||
int x0 = (int)(char)x;
|
||||
range(x0);
|
||||
range(x0); // $ range=<=127 range=>=-128
|
||||
int x1 = (int)(unsigned char)x;
|
||||
range(x1);
|
||||
range(x1); // $ range=<=255 range=>=0
|
||||
int x2 = (int)(unsigned short)x;
|
||||
range(x2);
|
||||
range(x2); // $ range=<=65535 range=>=0
|
||||
int x3 = (int)(unsigned int)x;
|
||||
range(x3);
|
||||
char c0 = x;
|
||||
@@ -759,9 +759,9 @@ unsigned long mult_overflow() {
|
||||
unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) {
|
||||
if (ui >= 10) {
|
||||
range(ui); // $ range=>=10
|
||||
range((unsigned long)ui); // $ range=>=10
|
||||
unsigned long result = (unsigned long)ui * ui; // $ overflow=+
|
||||
range(result); // $ MISSING: range=>=100
|
||||
range((unsigned long)ui); // $ range=>=10 range=<=4294967295
|
||||
unsigned long result = (unsigned long)ui * ui; // no overflow
|
||||
range(result); // $ range=>=100 range=<=18446744065119617024
|
||||
return result; // BUG: upper bound should be >= 18446744065119617025
|
||||
}
|
||||
if (ul >= 10) {
|
||||
@@ -888,7 +888,7 @@ void notequal_variations(short n, float f) {
|
||||
}
|
||||
|
||||
if (n >= 5) {
|
||||
if (2 * n - 10 == 0) { // $ overflow=+
|
||||
if (2 * n - 10 == 0) { // no overflow
|
||||
range(n); // $ range=>=5 MISSING: range===5
|
||||
return;
|
||||
}
|
||||
@@ -936,7 +936,7 @@ void two_bounds_from_one_test(short ss, unsigned short us) {
|
||||
range(ss); // -32768 .. 32767
|
||||
}
|
||||
|
||||
if (ss + 1 < sizeof(int)) { // $ overflow=+
|
||||
if (ss + 1 < sizeof(int)) { // $ overflow=-
|
||||
range(ss); // -1 .. 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
| file://:0:0:0:0 | _Float64 |
|
||||
| file://:0:0:0:0 | _Float64x |
|
||||
| file://:0:0:0:0 | _Float128 |
|
||||
| file://:0:0:0:0 | _Float128x |
|
||||
| file://:0:0:0:0 | _Imaginary double |
|
||||
| file://:0:0:0:0 | _Imaginary float |
|
||||
| file://:0:0:0:0 | _Imaginary long double |
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
| file://:0:0:0:0 | _Float64 | 8 |
|
||||
| file://:0:0:0:0 | _Float64x | 16 |
|
||||
| file://:0:0:0:0 | _Float128 | 16 |
|
||||
| file://:0:0:0:0 | _Float128x | 32 |
|
||||
| file://:0:0:0:0 | _Imaginary double | 8 |
|
||||
| file://:0:0:0:0 | _Imaginary float | 4 |
|
||||
| file://:0:0:0:0 | _Imaginary long double | 16 |
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
| file://:0:0:0:0 | _Float64 | _Float64 |
|
||||
| file://:0:0:0:0 | _Float64x | _Float64x |
|
||||
| file://:0:0:0:0 | _Float128 | _Float128 |
|
||||
| file://:0:0:0:0 | _Float128x | _Float128x |
|
||||
| file://:0:0:0:0 | _Imaginary double | _Imaginary double |
|
||||
| file://:0:0:0:0 | _Imaginary float | _Imaginary float |
|
||||
| file://:0:0:0:0 | _Imaginary long double | _Imaginary long double |
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
| _Float64 | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float64x | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float128 | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float128x | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Imaginary double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
|
||||
| _Imaginary float | BinaryFloatingPointType, ImaginaryNumberType | | | | |
|
||||
| _Imaginary long double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
|
||||
|
||||
Reference in New Issue
Block a user