mirror of
https://github.com/github/codeql.git
synced 2026-05-05 21:55:19 +02:00
Merge branch 'main' into post-release-prep/codeql-cli-2.25.0
This commit is contained in:
@@ -33,5 +33,11 @@ module Impl {
|
||||
result = "impl " + trait + this.getSelfTy().toAbbreviatedString() + " { ... }"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is an inherent `impl` block, that is, one that does not implement a trait.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate isInherent() { not this.hasTrait() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,15 @@ module Impl {
|
||||
|
||||
private newtype TArgumentPosition =
|
||||
TPositionalArgumentPosition(int i) {
|
||||
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1]
|
||||
// For the type `FunctionPosition` used by type inference, we work with function-call syntax
|
||||
// adjusted positions, so a call like `x.m(a, b, c)` needs positions `0` through `3`; for this
|
||||
// reason, there is no `- 1` after `max(...)` below.
|
||||
i in [0 .. max([
|
||||
any(ParamList l).getNumberOfParams(),
|
||||
any(ArgList l).getNumberOfArgs(),
|
||||
any(StructFieldList l).getNumberOfFields() // Positions are used for struct expressions in type inference
|
||||
]
|
||||
)]
|
||||
} or
|
||||
TSelfArgumentPosition() or
|
||||
TTypeQualifierArgumentPosition()
|
||||
|
||||
@@ -50,5 +50,10 @@ module Impl {
|
||||
or
|
||||
result = this.getVariant().getStructField(name)
|
||||
}
|
||||
|
||||
/** Gets the `i`th struct field of the instantiated struct or variant. */
|
||||
StructField getNthStructField(int i) {
|
||||
result = [this.getStruct().getNthStructField(i), this.getVariant().getNthStructField(i)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@ module Impl {
|
||||
/** Gets a record field, if any. */
|
||||
StructField getAStructField() { result = this.getStructField(_) }
|
||||
|
||||
/** Gets the `i`th struct field, if any. */
|
||||
pragma[nomagic]
|
||||
StructField getNthStructField(int i) {
|
||||
result = this.getFieldList().(StructFieldList).getField(i)
|
||||
}
|
||||
|
||||
/** Gets the `i`th tuple field, if any. */
|
||||
pragma[nomagic]
|
||||
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }
|
||||
|
||||
@@ -42,6 +42,13 @@ module Impl {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `i`th struct field of the instantiated struct or variant. */
|
||||
StructField getNthStructField(int i) {
|
||||
exists(PathResolution::ItemNode item | item = this.getResolvedPath(_) |
|
||||
result = [item.(Struct).getNthStructField(i), item.(Variant).getNthStructField(i)]
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the struct pattern for the field `name`. */
|
||||
pragma[nomagic]
|
||||
StructPatField getPatField(string name) {
|
||||
|
||||
@@ -32,6 +32,12 @@ module Impl {
|
||||
result.getName().getText() = name
|
||||
}
|
||||
|
||||
/** Gets the `i`th struct field, if any. */
|
||||
pragma[nomagic]
|
||||
StructField getNthStructField(int i) {
|
||||
result = this.getFieldList().(StructFieldList).getField(i)
|
||||
}
|
||||
|
||||
/** Gets the `i`th tuple field, if any. */
|
||||
pragma[nomagic]
|
||||
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }
|
||||
|
||||
@@ -41,16 +41,19 @@ private predicate hasFirstNonTrivialTraitBound(TypeParamItemNode tp, Trait trait
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate isBlanketLike(ImplItemNode i, TypePath blanketSelfPath, TypeParam blanketTypeParam) {
|
||||
blanketTypeParam = i.getBlanketImplementationTypeParam() and
|
||||
blanketSelfPath.isEmpty()
|
||||
or
|
||||
exists(TypeMention tm, Type root, TypeParameter tp |
|
||||
tm = i.(Impl).getSelfTy() and
|
||||
complexSelfRoot(root, tp) and
|
||||
tm.getType() = root and
|
||||
tm.getTypeAt(blanketSelfPath) = TTypeParamTypeParameter(blanketTypeParam) and
|
||||
blanketSelfPath = TypePath::singleton(tp) and
|
||||
hasFirstNonTrivialTraitBound(blanketTypeParam, _)
|
||||
i.(Impl).hasTrait() and
|
||||
(
|
||||
blanketTypeParam = i.getBlanketImplementationTypeParam() and
|
||||
blanketSelfPath.isEmpty()
|
||||
or
|
||||
exists(TypeMention tm, Type root, TypeParameter tp |
|
||||
tm = i.(Impl).getSelfTy() and
|
||||
complexSelfRoot(root, tp) and
|
||||
tm.getType() = root and
|
||||
tm.getTypeAt(blanketSelfPath) = TTypeParamTypeParameter(blanketTypeParam) and
|
||||
blanketSelfPath = TypePath::singleton(tp) and
|
||||
hasFirstNonTrivialTraitBound(blanketTypeParam, _)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,8 @@ private predicate functionResolutionDependsOnArgumentCand(
|
||||
implHasSibling(impl, trait) and
|
||||
traitTypeParameterOccurrence(trait, _, functionName, pos, path, traitTp) and
|
||||
f = impl.getASuccessor(functionName) and
|
||||
not pos.isSelfOrTypeQualifier()
|
||||
not pos.isTypeQualifier() and
|
||||
not (f instanceof Method and pos.asPosition() = 0)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,17 +6,23 @@ private import TypeMention
|
||||
private import TypeInference
|
||||
|
||||
private newtype TFunctionPosition =
|
||||
TArgumentFunctionPosition(ArgumentPosition pos) or
|
||||
TArgumentFunctionPosition(ArgumentPosition pos) { not pos.isSelf() } or
|
||||
TReturnFunctionPosition()
|
||||
|
||||
/**
|
||||
* A position of a type related to a function.
|
||||
* A function-call adjusted position of a type related to a function.
|
||||
*
|
||||
* Either `self`, `return`, or a positional parameter index.
|
||||
* Either `return` or a positional parameter index, where `self` is translated
|
||||
* to position `0` and subsequent positional parameters at index `i` are
|
||||
* translated to position `i + 1`.
|
||||
*
|
||||
* Function-call adjusted positions are needed when resolving calls of the
|
||||
* form `Foo::f(x_1, ..., x_n)`, where we do not know up front whether `f` is a
|
||||
* method or a non-method, and hence we need to be able to match `x_1` against
|
||||
* both a potential `self` parameter and a potential first positional parameter
|
||||
* (and `x_2, ... x_n` against all subsequent positional parameters).
|
||||
*/
|
||||
class FunctionPosition extends TFunctionPosition {
|
||||
predicate isSelf() { this.asArgumentPosition().isSelf() }
|
||||
|
||||
int asPosition() { result = this.asArgumentPosition().asPosition() }
|
||||
|
||||
predicate isPosition() { exists(this.asPosition()) }
|
||||
@@ -25,29 +31,18 @@ class FunctionPosition extends TFunctionPosition {
|
||||
|
||||
predicate isTypeQualifier() { this.asArgumentPosition().isTypeQualifier() }
|
||||
|
||||
predicate isSelfOrTypeQualifier() { this.isSelf() or this.isTypeQualifier() }
|
||||
|
||||
predicate isReturn() { this = TReturnFunctionPosition() }
|
||||
|
||||
/** Gets the corresponding position when `f` is invoked via a function call. */
|
||||
bindingset[f]
|
||||
FunctionPosition getFunctionCallAdjusted(Function f) {
|
||||
this.isReturn() and
|
||||
result = this
|
||||
or
|
||||
if f.hasSelfParam()
|
||||
then
|
||||
this.isSelf() and result.asPosition() = 0
|
||||
or
|
||||
result.asPosition() = this.asPosition() + 1
|
||||
else result = this
|
||||
}
|
||||
|
||||
TypeMention getTypeMention(Function f) {
|
||||
this.isSelf() and
|
||||
result = getSelfParamTypeMention(f.getSelfParam())
|
||||
or
|
||||
result = f.getParam(this.asPosition()).getTypeRepr()
|
||||
(
|
||||
if f instanceof Method
|
||||
then
|
||||
result = f.getParam(this.asPosition() - 1).getTypeRepr()
|
||||
or
|
||||
result = getSelfParamTypeMention(f.getSelfParam()) and
|
||||
this.asPosition() = 0
|
||||
else result = f.getParam(this.asPosition()).getTypeRepr()
|
||||
)
|
||||
or
|
||||
this.isReturn() and
|
||||
result = getReturnTypeMention(f)
|
||||
@@ -197,8 +192,7 @@ class AssocFunctionType extends MkAssocFunctionType {
|
||||
exists(Function f, ImplOrTraitItemNode i, FunctionPosition pos | this.appliesTo(f, i, pos) |
|
||||
result = pos.getTypeMention(f)
|
||||
or
|
||||
pos.isSelf() and
|
||||
not f.hasSelfParam() and
|
||||
pos.isTypeQualifier() and
|
||||
result = [i.(Impl).getSelfTy().(AstNode), i.(Trait).getName()]
|
||||
)
|
||||
}
|
||||
@@ -209,7 +203,7 @@ class AssocFunctionType extends MkAssocFunctionType {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Trait getALookupTrait(Type t) {
|
||||
Trait getALookupTrait(Type t) {
|
||||
result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound()
|
||||
or
|
||||
result = t.(SelfTypeParameter).getTrait()
|
||||
@@ -310,10 +304,11 @@ signature module ArgsAreInstantiationsOfInputSig {
|
||||
* Holds if `f` inside `i` needs to have the type corresponding to type parameter
|
||||
* `tp` checked.
|
||||
*
|
||||
* If `i` is an inherent implementation, `tp` is a type parameter of the type being
|
||||
* implemented, otherwise `tp` is a type parameter of the trait (being implemented).
|
||||
* `tp` is a type parameter of the trait being implemented by `f` or the trait to which
|
||||
* `f` belongs.
|
||||
*
|
||||
* `pos` is one of the positions in `f` in which the relevant type occours.
|
||||
* `pos` is one of the function-call adjusted positions in `f` in which the relevant
|
||||
* type occurs.
|
||||
*/
|
||||
predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter tp, FunctionPosition pos);
|
||||
|
||||
@@ -360,7 +355,7 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
|
||||
private newtype TCallAndPos =
|
||||
MkCallAndPos(Input::Call call, FunctionPosition pos) { exists(call.getArgType(pos, _)) }
|
||||
|
||||
/** A call tagged with a position. */
|
||||
/** A call tagged with a function-call adjusted position. */
|
||||
private class CallAndPos extends MkCallAndPos {
|
||||
Input::Call call;
|
||||
FunctionPosition pos;
|
||||
@@ -413,20 +408,21 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate argIsInstantiationOf(
|
||||
Input::Call call, FunctionPosition pos, ImplOrTraitItemNode i, Function f, int rnk
|
||||
Input::Call call, ImplOrTraitItemNode i, Function f, int rnk
|
||||
) {
|
||||
ArgIsInstantiationOfToIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and
|
||||
toCheckRanked(i, f, _, pos, rnk)
|
||||
exists(FunctionPosition pos |
|
||||
ArgIsInstantiationOfToIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and
|
||||
toCheckRanked(i, f, _, pos, rnk)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate argsAreInstantiationsOfToIndex(
|
||||
Input::Call call, ImplOrTraitItemNode i, Function f, int rnk
|
||||
) {
|
||||
exists(FunctionPosition pos |
|
||||
argIsInstantiationOf(call, pos, i, f, rnk) and
|
||||
call.hasTargetCand(i, f)
|
||||
|
|
||||
argIsInstantiationOf(call, i, f, rnk) and
|
||||
call.hasTargetCand(i, f) and
|
||||
(
|
||||
rnk = 0
|
||||
or
|
||||
argsAreInstantiationsOfToIndex(call, i, f, rnk - 1)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user