Skip to content

Commit 8b13adb

Browse files
committed
Swift: IPA layer tweaks
1 parent 6abd4a6 commit 8b13adb

File tree

9 files changed

+48
-52
lines changed

9 files changed

+48
-52
lines changed

swift/codegen/generators/qlgen.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def get_ql_class(cls: schema.Class, lookup: typing.Dict[str, schema.Class]):
8484

8585
def _to_db_type(x: str) -> str:
8686
if x[0].isupper():
87-
return "@" + inflection.underscore(x)
87+
return "Db::" + x
8888
return x
8989

9090

@@ -93,14 +93,15 @@ def _to_db_type(x: str) -> str:
9393

9494
def get_ql_ipa_class(cls: schema.Class):
9595
if cls.derived:
96-
return ql.Ipa.NonFinalClass(name=cls.name, derived=sorted(cls.derived), root=(cls.name == schema.root_class_name))
96+
return ql.Ipa.NonFinalClass(name=cls.name, derived=sorted(cls.derived),
97+
root=(cls.name == schema.root_class_name))
9798
if cls.ipa and cls.ipa.from_class is not None:
9899
source = cls.ipa.from_class
99100
_final_db_class_lookup.setdefault(source, ql.Ipa.FinalClassDb(source)).subtract_type(cls.name)
100-
return ql.Ipa.FinalClassIpaFrom(name=cls.name, type=_to_db_type(source))
101+
return ql.Ipa.FinalClassDerivedIpa(name=cls.name, params=[ql.Ipa.Param("id", _to_db_type(source))])
101102
if cls.ipa and cls.ipa.on_arguments is not None:
102-
return ql.Ipa.FinalClassIpaOn(name=cls.name,
103-
params=[ql.Ipa.Param(k, _to_db_type(v)) for k, v in cls.ipa.on_arguments.items()])
103+
return ql.Ipa.FinalClassFreshIpa(name=cls.name, params=[ql.Ipa.Param(k, _to_db_type(v)) for k, v in
104+
cls.ipa.on_arguments.items()])
104105
return _final_db_class_lookup.setdefault(cls.name, ql.Ipa.FinalClassDb(cls.name))
105106

106107

@@ -120,9 +121,11 @@ def get_classes_used_by(cls: ql.Class):
120121
return sorted(set(t for t in get_types_used_by(cls) if t[0].isupper()))
121122

122123

123-
_generated_stub_re = re.compile(r"\n*private import .*\n+class \w+ extends \w+ \{[ \n]?\}"
124+
_generated_stub_re = re.compile(r"\n*private import .*\n+("
125+
r"class \w+ extends \w+ \{[ \n]?\}"
124126
"|"
125-
r"\n*predicate construct\w+\(.*?\) \{ none\(\) \}", re.MULTILINE)
127+
r"predicate construct\w+\(.*?\) \{ none\(\) \}"
128+
")", re.MULTILINE)
126129

127130

128131
def _is_generated_stub(file):
@@ -271,7 +274,7 @@ def generate(opts, renderer):
271274
ipa_type = get_ql_ipa_class(cls)
272275
if ipa_type.is_final:
273276
final_ipa_types.append(ipa_type)
274-
if ipa_type.is_ipa_from or (ipa_type.is_ipa_on and ipa_type.has_params):
277+
if ipa_type.is_ipa and ipa_type.has_params:
275278
stub_file = stub_out / cls.dir / f"{cls.name}Constructor.qll"
276279
if not stub_file.is_file() or _is_generated_stub(stub_file):
277280
renderer.render(ql.Ipa.ConstructorStub(ipa_type), stub_file)

swift/codegen/lib/ql.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,13 @@ class Class:
171171
@dataclass
172172
class FinalClass(Class):
173173
is_final: ClassVar = True
174-
is_ipa_from: ClassVar = False
175-
is_ipa_on: ClassVar = False
174+
is_derived_ipa: ClassVar = False
175+
is_fresh_ipa: ClassVar = False
176176
is_db: ClassVar = False
177177

178178
@property
179179
def is_ipa(self):
180-
return self.is_ipa_on or self.is_ipa_from
180+
return self.is_fresh_ipa or self.is_derived_ipa
181181

182182
@dataclass
183183
class Param:
@@ -186,19 +186,7 @@ class Param:
186186
first: bool = False
187187

188188
@dataclass
189-
class FinalClassIpaFrom(FinalClass):
190-
is_ipa_from: ClassVar = True
191-
192-
type: str = None
193-
194-
@property
195-
def params(self):
196-
return [Ipa.Param("id", self.type, first=True)]
197-
198-
@dataclass
199-
class FinalClassIpaOn(FinalClass):
200-
is_ipa_on: ClassVar = True
201-
189+
class FinalClassIpa(FinalClass):
202190
params: List["Ipa.Param"] = field(default_factory=list)
203191

204192
def __post_init__(self):
@@ -209,6 +197,14 @@ def __post_init__(self):
209197
def has_params(self) -> bool:
210198
return bool(self.params)
211199

200+
@dataclass
201+
class FinalClassDerivedIpa(FinalClassIpa):
202+
is_derived_ipa: ClassVar = True
203+
204+
@dataclass
205+
class FinalClassFreshIpa(FinalClassIpa):
206+
is_fresh_ipa: ClassVar = True
207+
212208
@dataclass
213209
class FinalClassDb(FinalClass):
214210
is_db: ClassVar = True
@@ -219,11 +215,11 @@ def subtract_type(self, type: str):
219215
self.subtracted_ipa_types.append(Ipa.Class(type, first=not self.subtracted_ipa_types))
220216

221217
@property
222-
def has_subtracted_ipa_types(self):
218+
def has_subtracted_ipa_types(self) -> bool:
223219
return bool(self.subtracted_ipa_types)
224220

225221
@property
226-
def db_id(self):
222+
def db_id(self) -> str:
227223
return "@" + inflection.underscore(self.name)
228224

229225
@dataclass
@@ -252,4 +248,4 @@ def __post_init__(self):
252248
class ConstructorStub:
253249
template: ClassVar = "ql_ipa_constructor_stub"
254250

255-
cls: Union["Ipa.FinalClassIpaFrom", "Ipa.FinalClassIpaOn"]
251+
cls: Union["Ipa.FinalClassDerivedIpa", "Ipa.FinalClassFreshIpa"]

swift/codegen/schema.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ EnumIsCaseExpr:
423423
_extends: Expr
424424
_children:
425425
sub_expr: Expr
426-
element: EnumElementDecl
426+
element: EnumElementDecl
427427

428428
ErrorExpr:
429429
_extends: Expr
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
// generated by {{generator}}, remove this comment if you wish to edit this file
2+
import codeql.swift.generated.Db
3+
24
predicate construct{{cls.name}}({{#cls.params}}{{^first}}, {{/first}}{{type}} {{param}}{{/cls.params}}) { none() }

swift/codegen/templates/ql_ipa_types.mustache

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ cached module Ipa {
77
{{^first}}
88
or
99
{{/first}}
10-
{{#is_ipa_from}}
11-
T{{name}}(Db::{{type}} id) { construct{{name}}(id) }
12-
{{/is_ipa_from}}
13-
{{#is_ipa_on}}
10+
{{#is_ipa}}
1411
T{{name}}({{#params}}{{^first}}, {{/first}}{{type}} {{param}}{{/params}}){{#has_params}} { construct{{name}}({{#params}}{{^first}}, {{/first}}{{param}}{{/params}}) }{{/has_params}}
15-
{{/is_ipa_on}}
12+
{{/is_ipa}}
1613
{{#is_db}}
1714
T{{name}}(Db::{{name}} id){{#has_subtracted_ipa_types}} { {{#subtracted_ipa_types}}{{^first}} and {{/first}}not construct{{name}}(id){{/subtracted_ipa_types}} }{{/has_subtracted_ipa_types}}
1815
{{/is_db}}
@@ -26,12 +23,12 @@ cached module Ipa {
2623

2724
{{#final_classes}}
2825
cached T{{name}} convert{{name}}FromDb(Db::Element e) {
29-
{{^is_ipa_on}}
26+
{{^is_fresh_ipa}}
3027
result = T{{name}}(e)
31-
{{/is_ipa_on}}
32-
{{#is_ipa_on}}
28+
{{/is_fresh_ipa}}
29+
{{#is_fresh_ipa}}
3330
none()
34-
{{/is_ipa_on}}
31+
{{/is_fresh_ipa}}
3532
}
3633
{{/final_classes}}
3734

@@ -48,12 +45,12 @@ cached module Ipa {
4845

4946
{{#final_classes}}
5047
cached Db::Element convert{{name}}ToDb(T{{name}} e) {
51-
{{^is_ipa_on}}
48+
{{^is_fresh_ipa}}
5249
e = T{{name}}(result)
53-
{{/is_ipa_on}}
54-
{{#is_ipa_on}}
50+
{{/is_fresh_ipa}}
51+
{{#is_fresh_ipa}}
5552
none()
56-
{{/is_ipa_on}}
53+
{{/is_fresh_ipa}}
5754
}
5855
{{/final_classes}}
5956

swift/ql/lib/codeql/swift/controlflow/BasicBlocks.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,10 @@ private module JoinBlockPredecessors {
201201

202202
private predicate idOfDbAstNode(Db::AstNode x, int y) = equivalenceRelation(id/2)(x, y)
203203

204-
// TODO does not work if we use "ipa on" entities...
204+
// TODO does not work if fresh ipa entities (`ipa: on:`) turn out to be first of the block
205205
private predicate idOf(AstNode x, int y) { idOfDbAstNode(Ipa::convertAstNodeToDb(x), y) }
206206

207-
private AstNode projctToAst(ControlFlowElement n) {
207+
private AstNode projectToAst(ControlFlowElement n) {
208208
result = n.asAstNode()
209209
or
210210
isPropertyGetterElement(n, _, result)
@@ -219,7 +219,7 @@ private module JoinBlockPredecessors {
219219
}
220220

221221
int getId(JoinBlockPredecessor jbp) {
222-
idOf(projctToAst(jbp.getFirstNode().(CfgNode).getNode()), result)
222+
idOf(projectToAst(jbp.getFirstNode().(CfgNode).getNode()), result)
223223
or
224224
idOf(jbp.(EntryBasicBlock).getScope(), result)
225225
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
private import codeql.swift.generated.expr.ExplicitCastExpr
22

33
class ExplicitCastExpr extends ExplicitCastExprBase {
4-
override predicate convertsFrom(Expr e) { e = getImmediateSubExpr() }
4+
override predicate convertsFrom(Expr e) { e = this.getImmediateSubExpr() }
55

66
override string toString() { result = "(" + this.getType() + ") ..." }
77
}

swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,6 @@ Element getAnImmediateChild(Element e) {
6767
or
6868
result = e.(EnumIsCaseExpr).getImmediateSubExpr()
6969
or
70-
result = e.(EnumIsCaseExpr).getImmediateElement()
71-
or
7270
result = e.(ExplicitCastExpr).getImmediateSubExpr()
7371
or
7472
result = e.(ForceValueExpr).getImmediateSubExpr()

swift/ql/test/library-tests/controlflow/graph/Cfg.expected

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,18 +1514,15 @@ cfg.swift:
15141514
# 141| case ...
15151515
#-----| -> 0
15161516

1517-
# 141| 0
1518-
#-----| -> 0
1519-
15201517
# 141| 0
15211518
#-----| no-match -> 1
15221519
#-----| match -> true
15231520

15241521
# 141| 0
15251522
#-----| -> 0
15261523

1527-
# 141| 1
1528-
#-----| -> 1
1524+
# 141| 0
1525+
#-----| -> 0
15291526

15301527
# 141| 1
15311528
#-----| match -> true
@@ -1534,6 +1531,9 @@ cfg.swift:
15341531
# 141| 1
15351532
#-----| -> 1
15361533

1534+
# 141| 1
1535+
#-----| -> 1
1536+
15371537
# 142| return ...
15381538
#-----| return -> exit patterns(x:) (normal)
15391539

0 commit comments

Comments
 (0)