Skip to content

Commit 5886197

Browse files
committed
wip
1 parent 629758f commit 5886197

14 files changed

Lines changed: 669 additions & 134 deletions

File tree

‎shared/typeinference/codeql/typeinference/internal/TypeInference.qll‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,6 +3006,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
30063006
exists(e)
30073007
}
30083008

3009+
private Type getInferredType0(AccessEnvironment e, AccessPosition apos, TypePath path) {
3010+
result = this.getInferredType(e, apos, path) and
3011+
exists(this.getTarget(e))
3012+
}
3013+
30093014
Declaration getTarget(AccessEnvironment e) { result = super.getTarget(e) }
30103015
}
30113016
}
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,71 @@
1-
var topLevelDecl : Int = 0
1+
var topLevelDecl: Int = 0
22
0
3-
topLevelDecl + 1 // $ type=topLevelDecl:Int
3+
topLevelDecl + 1 // $ type=topLevelDecl:Int
44

55
class C {
6-
var myInt : Int
6+
var myInt: Int
77
// C.init
88
init(n: Int) {
9-
myInt = n // $ type=n:Int
9+
myInt = n // $ type=n:Int
1010
}
1111

1212
// C.getMyInt
1313
func getMyInt() -> Int {
14-
return myInt // $ type=.myInt:Int
14+
return myInt // $ type=.myInt:Int
1515
}
1616
}
1717

18-
class Derived : C {
18+
class Derived: C {
1919
// Derived.init
2020
init() {
21-
super.init(n: 0) // $ type=super:C target=C.init
21+
super.init(n: 0) // $ type=super:C target=C.init
2222
}
2323

2424
// Derived.callGetMyInt
2525
func callGetMyInt() -> Int {
26-
let x = getMyInt(); // $ type=x:Int target=C.getMyInt
26+
let x = getMyInt() // $ type=x:Int target=C.getMyInt
2727
return x
2828
}
2929
}
3030

3131
class Generic<T> {
32-
var value : T
32+
var value: T
3333
// Generic.init
3434
init(v: T) {
35-
value = v // $ type=v:T
35+
value = v // $ type=v:T
3636
}
3737

3838
// Generic.getValue
3939
func getValue() -> T {
40-
return value // $ type=.value:T
40+
return value // $ type=.value:T
4141
}
4242
}
4343

44-
class GenericDerived : Generic<Int> {
44+
class GenericDerived: Generic<Int> {
4545
// GenericDerived.init
4646
init() {
47-
super.init(v: 0) // $ type=super@Generic<T>:Int target=Generic.init
47+
super.init(v: 0) // $ type=super@Generic<T>:Int target=Generic.init
4848
}
4949
}
5050

5151
func testGeneric() {
52-
let g = Generic(v: 42) // $ type=g@Generic<T>:Int target=Generic.init
53-
let x = g.getValue() // $ type=x:Int target=Generic.getValue
52+
let g = Generic(v: 42) // $ type=g@Generic<T>:Int target=Generic.init
53+
let x = g.getValue() // $ type=x:Int target=Generic.getValue
5454

55-
let gd = GenericDerived() // $ type=gd:GenericDerived target=GenericDerived.init
56-
let y = gd.getValue() // $ type=y:Int target=Generic.getValue
55+
let gd = GenericDerived() // $ type=gd:GenericDerived target=GenericDerived.init
56+
let y = gd.getValue() // $ type=y:Int target=Generic.getValue
5757
}
5858

5959
// --- Extensions ---
6060

6161
extension C {
6262
// C.doubled
6363
func doubled() -> Int {
64-
return myInt * 2 // $ type=.myInt:Int
64+
return myInt * 2 // $ type=.myInt:Int
6565
}
6666
}
6767

6868
func testExtension() {
69-
let obj = C(n: 10) // $ target=C.init
70-
let d = obj.doubled() // $ type=d:Int target=C.doubled
69+
let obj = C(n: 10) // $ target=C.init
70+
let d = obj.doubled() // $ type=d:Int target=C.doubled
7171
}
Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
private import unified
22
private import AllDataFlow
3-
private import codeql.unified.internal.NameBinding as N
4-
5-
private Callable getCallableFromNameBinding(NameBinding binding) {
6-
binding = result.(FunctionDeclaration).getNameNode()
7-
}
3+
private import codeql.unified.internal.typeinference.TypeInference as T
84

95
DataFlowCallable viableCallable(DataFlowCall c) {
10-
exists(CallExpr call, Callable callable, NameBinding target |
11-
c.asExplicitCall() = call and
12-
target = N::getStaticBindingTarget(N::getIdentifierFromRef(call.getCallee())) and
13-
callable = getCallableFromNameBinding(target) and
14-
result.asSourceCallable() = callable
15-
)
6+
result.asSourceCallable() = T::resolveCallTarget(c.asExplicitCall(), _)
167
}

‎unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll‎

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ import M2
107107
private module Input3 implements InputSig3 {
108108
private import unified as Unified
109109

110-
predicate cacheRevRef() { exists(resolveCallTarget(_)) implies any() }
110+
predicate cacheRevRef() { exists(lookupMember(_)) implies any() }
111111

112112
predicate inferTypeForDefaults = M3::inferType/2;
113113

@@ -478,6 +478,8 @@ private module Input3 implements InputSig3 {
478478

479479
abstract Expr getArgument(int i);
480480

481+
abstract int getNumberOfArguments();
482+
481483
abstract Callable getTarget(InvocationResolutionContext c);
482484

483485
abstract Callable getATargetForTypeQualifierMatching();
@@ -498,15 +500,28 @@ private module Input3 implements InputSig3 {
498500

499501
override Type getTypeArgument(int pos, TypePath path) { none() }
500502

503+
override int getNumberOfArguments() {
504+
exists(Unified::Callable target, boolean isFunctionExprInvoke |
505+
target = resolveCallTarget(this, isFunctionExprInvoke) and
506+
result = CallExpr.super.getNumberOfArguments() + 1
507+
)
508+
}
509+
501510
override Expr getArgument(int i) {
502-
i = 0 and
503-
result = CallExpr.super.getCallee().(MemberAccessExpr).getBase()
504-
or
505-
result = CallExpr.super.getArgument(i - 1).getValue()
511+
exists(Unified::Callable target, boolean isFunctionExprInvoke |
512+
target = resolveCallTarget(this, isFunctionExprInvoke)
513+
|
514+
i = 0 and
515+
if isFunctionExprInvoke = true
516+
then result = CallExpr.super.getCallee()
517+
else result = CallExpr.super.getCallee().(MemberAccessExpr).getBase()
518+
or
519+
result = CallExpr.super.getArgument(i - 1).getValue()
520+
)
506521
}
507522

508523
override Callable getTarget(InvocationResolutionContext c) {
509-
result.getAstNode() = resolveCallTarget(this) and
524+
result.getAstNode() = resolveCallTarget(this, _) and
510525
exists(c)
511526
}
512527

@@ -517,11 +532,27 @@ private module Input3 implements InputSig3 {
517532
Invocation invocation, InvocationResolutionContext ctx, int i, TypePath path
518533
) {
519534
exists(ctx) and
520-
(
521-
result = inferType(invocation.getArgument(i), path)
522-
or
523-
i = 0 and
524-
result = getImplicitReceiverType(invocation.(CallExpr).getCallee(), path)
535+
exists(boolean isFunctionExprInvoke |
536+
exists(resolveCallTarget(invocation, isFunctionExprInvoke))
537+
|
538+
if isFunctionExprInvoke = true
539+
then
540+
exists(Type t | exists(getInvokeTarget(invocation, t)) |
541+
i = 0 and
542+
result = inferType(invocation.(CallExpr).getCallee(), path)
543+
or
544+
exists(TypePath prefix, TypePath suffix, int j |
545+
functionInvokeSignature(t, invocation.getNumberOfArguments() - 1, j, i, prefix) and
546+
result = inferType(invocation.getArgument(j + 1), suffix) and
547+
path = prefix.append(suffix)
548+
)
549+
)
550+
else (
551+
result = inferType(invocation.getArgument(i), path)
552+
or
553+
i = 0 and
554+
result = getImplicitReceiverType(invocation.(CallExpr).getCallee(), path)
555+
)
525556
)
526557
}
527558

@@ -543,29 +574,40 @@ private module Input3 implements InputSig3 {
543574
Parameter getParameter() { result = TExplicitDeclaration(this.getParam()) }
544575
}
545576

546-
bindingset[c]
577+
pragma[nomagic]
547578
Type getClosureType(Closure c) { result = getFunctionExprType(c.getAstNode()) }
548579

549580
pragma[nomagic]
550581
TypePath getClosureParameterTypePath(Parameter p) {
551-
exists(FunctionExpr fe, int i |
582+
exists(FunctionExpr fe, Type t, int i |
552583
p = TExplicitDeclaration(fe.getParameter(i)) and
553-
result = getFunctionExprParameterTypePath(fe, i)
584+
t = getFunctionExprType(fe) and
585+
result = getFunctionExprParameterTypePath(t, fe.getNumberOfParameters(), i)
554586
)
555587
}
556588

557-
bindingset[c]
589+
pragma[nomagic]
558590
TypePath getClosureReturnTypePath(Closure c) {
559-
result = getFunctionExprReturnTypePath(c.getAstNode())
591+
result = getFunctionExprReturnTypePath(getClosureType(c))
560592
}
561593

562594
predicate stepLanguageSpecific(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) {
563-
none()
595+
n1 = n2.(Block).getLastStmt() and
596+
prefix1.isEmpty() and
597+
prefix2.isEmpty()
564598
}
565599

566600
Type inferTypeLanguageSpecific(AstNode n, TypePath path) {
567601
result = Plugin::inferType(n, path)
568602
or
603+
n instanceof BooleanLiteral and
604+
result instanceof BoolType and
605+
path.isEmpty()
606+
or
607+
n instanceof IntLiteral and
608+
result instanceof IntType and
609+
path.isEmpty()
610+
or
569611
exists(ClassLikeDeclaration c |
570612
c = n.(SuperExpr).getEnclosingClass() and
571613
result = c.getBaseType(0).getType().(TypeMention).getTypeAt(path)
@@ -602,18 +644,31 @@ Identifier lookupMember(MemberAccessExpr mae) {
602644
)
603645
}
604646

605-
Callable resolveCallTarget(CallExpr ce) {
647+
pragma[nomagic]
648+
private Callable getInvokeTarget(CallExpr ce, Type t) {
649+
t = inferType(ce.getCallee()) and
650+
result = getFunctionInvoke(t)
651+
}
652+
653+
// Does not yet take overloading into account
654+
Callable resolveCallTarget(CallExpr ce, boolean isFunctionExprInvoke) {
606655
exists(NameBinding b | b = getStaticBindingTarget(ce.getCallee()) |
656+
// object creation
607657
exists(ClassLikeDeclaration cls, ConstructorDeclaration init |
608658
cls.getNameNode() = b and
609659
init = cls.getAMember() and
610660
result = init
611661
)
612662
or
613663
result.(FunctionDeclaration).getNameNode() = b
614-
)
664+
) and
665+
isFunctionExprInvoke = false
666+
or
667+
result.(Input3::AstDeclaration::Declaration).getNameNode() = lookupMember(ce.getCallee()) and
668+
isFunctionExprInvoke = false
615669
or
616-
result.(Input3::AstDeclaration::Declaration).getNameNode() = lookupMember(ce.getCallee())
670+
result = getInvokeTarget(ce, _) and
671+
isFunctionExprInvoke = true
617672
}
618673

619674
VariableDeclaration resolveFieldAccess(MemberAccessExpr mae) {

0 commit comments

Comments
 (0)