Swift: add extraction of ThenStmt

These are currently added implicitly by the compiler in the context of
`if`/`switch` expressions. In the future, there might be explicit
`then <expr>` statement useful for cases where one would like to add
more than one statement in the branch, to mark what value to actually
use.

See https://forums.swift.org/t/pitch-multi-statement-if-switch-do-expressions/68443
This commit is contained in:
Paolo Tranquilli
2024-03-27 12:14:19 +01:00
parent 2382f76317
commit b8e38288e3
20 changed files with 213 additions and 9 deletions

View File

@@ -43,7 +43,7 @@ MAP(swift::Stmt, StmtTag)
MAP(swift::BraceStmt, BraceStmtTag)
MAP(swift::ReturnStmt, ReturnStmtTag)
MAP(swift::YieldStmt, YieldStmtTag)
MAP(swift::ThenStmt, void) // gated behind yet unusable experimental feature
MAP(swift::ThenStmt, ThenStmtTag)
MAP(swift::DeferStmt, DeferStmtTag)
MAP(swift::LabeledStmt, LabeledStmtTag)
MAP(swift::LabeledConditionalStmt, LabeledConditionalStmtTag)

View File

@@ -218,4 +218,10 @@ codeql::DiscardStmt StmtTranslator::translateDiscardStmt(const swift::DiscardStm
return entry;
}
codeql::ThenStmt StmtTranslator::translateThenStmt(const swift::ThenStmt& stmt) {
auto entry = dispatcher.createEntry(stmt);
entry.result = dispatcher.fetchLabel(stmt.getResult());
return entry;
}
} // namespace codeql

View File

@@ -40,6 +40,7 @@ class StmtTranslator : public AstTranslatorBase<StmtTranslator> {
codeql::FailStmt translateFailStmt(const swift::FailStmt& stmt);
codeql::PoundAssertStmt translatePoundAssertStmt(const swift::PoundAssertStmt& stmt);
codeql::DiscardStmt translateDiscardStmt(const swift::DiscardStmt& stmt);
codeql::ThenStmt translateThenStmt(const swift::ThenStmt& stmt);
private:
void fillLabeledStmt(const swift::LabeledStmt& stmt, codeql::LabeledStmt& entry);

View File

@@ -271,6 +271,8 @@ lib/codeql/swift/elements/stmt/ReturnStmtConstructor.qll 2c66c1b1ece31bcfee06c87
lib/codeql/swift/elements/stmt/Stmt.qll b21643c4dd6a7e22c422df36c66d7389918c71cb05e71b58c2086f998035ca8a 2fd87fce67d61461dfd40f1430b67e2611729eb3205fd508a79c4fabf6cc51b8
lib/codeql/swift/elements/stmt/StmtConditionConstructor.qll 978a7c1dd6cc51194c847a6ed4785200515d90d484d013c367d7b86a177656f2 4a0dd278470676232b29e2ed02fef5b88061d9dd3ca082238e5fc4e978dcd66f
lib/codeql/swift/elements/stmt/SwitchStmtConstructor.qll 8431feb4b68505ac0072be07a6ed07d71559daf5443e5164d0aad38bc8c5cc12 98a9e32dc3774e47070ec3b0f7f4febfe2ec298858955275e22471682da270bc
lib/codeql/swift/elements/stmt/ThenStmt.qll 70c38206142fa0bc5bbcfe3661dbfb4dcc53416160eef3e6f301504cddb4b0ae f7066479d4319db057de7d49d723dbfa9a6bc221738f8ea6cea795f5ef1e341a
lib/codeql/swift/elements/stmt/ThenStmtConstructor.qll 88823800957584b9a5f9601f85f75875d45d262718d736851b0e40d4028c5dc1 98c480d82177e5d223307aa0e2fe82bf859915b050ec66a5d959f7d0e58ee068
lib/codeql/swift/elements/stmt/ThrowStmtConstructor.qll 974ec76e814030df10362a516da9aa0f90dbb1040ef3297a12632b0654d95dfc a02f73cd6f36d96d6093ffb4608be6e5fb15d8412f3c4ff0f4648b82b909f582
lib/codeql/swift/elements/stmt/WhileStmtConstructor.qll a49c46100da57dc6e8b3cfcc665bd2d6cfa1b49efb0f7d66f49ed719b42ff34d d527c8f6d08b91917d209554c76aade2b35b90c09caec6aa21c3ba951e8e8bf7
lib/codeql/swift/elements/stmt/YieldStmtConstructor.qll ac2047e02add0796b5eff4180c777dc4ebd4bc52c2083036b959e3a1caa41bad 78209a97874bc3bb2c4c3b919ff4b9e68010b0d047d2b455881b980f5100767a
@@ -390,7 +392,7 @@ lib/codeql/swift/elements/type/UnresolvedTypeConstructor.qll 7f75d489b4d7ce65cae
lib/codeql/swift/elements/type/VariadicSequenceTypeConstructor.qll fc74a5a2a2effa28ef24509b20ee4373d97cf6e8c71840121bb031c6adedf584 c9b2effc1d01c13c5e6a74a111122fa79a2f6554dda3cb016d68ba397e566ec4
lib/codeql/swift/elements/type/WeakStorageType.qll edd13dd97b53040684409e187c1f975bcada6807c919e1345d8977144dbebb6f 9434c044d264a7f5f503a6422c106c9b8fedf74aaae314174473a29ea6ed17b9
lib/codeql/swift/elements/type/WeakStorageTypeConstructor.qll 5fdce3716aba6318522174a2c455a63480970222ae81c732fb19c6dd3ae2d271 60ea79d6943e129deba0deccb566cf9d73f78398b0f7f0212674d91287d6b2ae
lib/codeql/swift/elements.qll 27da89b0b50ea17b96a47aad31453ff0d43b8277ab660385f785879ce6cc243e 27da89b0b50ea17b96a47aad31453ff0d43b8277ab660385f785879ce6cc243e
lib/codeql/swift/elements.qll bb863ff140bfaa0bf887708f421a16c85816886f4d061bbc5af752a4e4d810d3 bb863ff140bfaa0bf887708f421a16c85816886f4d061bbc5af752a4e4d810d3
lib/codeql/swift/generated/AstNode.qll 68877daa9e14b462247ac6b7b724f5e683288e39953a8ebb02a362b7d1df8e4c 54d3512744738e1ee15645f3af116437053cb5209687f4106361a1943b38b666
lib/codeql/swift/generated/AvailabilityInfo.qll e74e218a1ab00416cb8823610ff93642101aa784aa61cbc2b4deef61471a5bac e2c6c19860dc3e6e211041c95d8e6d52c3505ccff7018b80a849735cc98141af
lib/codeql/swift/generated/AvailabilitySpec.qll a8afc5071887a67b4e0dec27356ab8cbf3e176b5358cb34c785e3015b2cad5a2 c7f88b0d701612c821359c983b3102f31b23edc211c3dcfe97de5adec61af386
@@ -407,12 +409,12 @@ lib/codeql/swift/generated/Locatable.qll 6cb437dd7ff7331429ec6586b0af50b1af15e4f
lib/codeql/swift/generated/Location.qll 3f3bad413be87d05a596fe7b8004f415c2caa98cb759021a6aad20b589b7d700 ed30ed646962b3ffb6b47c97c6434fe47a6b1ea8e3f2e0589577bea5cf96c88e
lib/codeql/swift/generated/MacroRole.qll aaf5631c49de81e046854955341202d6d3516713cd09bc2e7b870e40c261cc9f 6cd17d40cbf1d8fa4ef01dfb8b3462b7cee902e6058fb76417c2035be12481d1
lib/codeql/swift/generated/OtherAvailabilitySpec.qll 06393a08e8da36106c5ec6efb9f1bd56a5c7b3d3f3d0bcefc6fa07fa96860c31 06393a08e8da36106c5ec6efb9f1bd56a5c7b3d3f3d0bcefc6fa07fa96860c31
lib/codeql/swift/generated/ParentChild.qll 523f0fdf11a8007a80b35d7f8b99f736face08513311c8e998ca20ae1e535ebe 2829f5e61adbd863f4ad823ecfd7c1bb5eccaf14bb121b85ad460175b733fe30
lib/codeql/swift/generated/ParentChild.qll 2489604e46253d81d7f8e3a8f0a7905481e5b2811d5016794ce5b66846cec22e f10627c078437dc9b8ce98d2a1559e660f86e2aea1d42feac1a79f2e68eeae8a
lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll 5355be9da8b778d1d8ae60d25d9c3394477da24f94e8a6ab4484c6a16d07cd7c 075438c1762ec0a7775004b39032dcf85aada038a4269e6f428c34b8282786e9
lib/codeql/swift/generated/PureSynthConstructors.qll 40f5c0c573ce12f16322d9efb12306750f672254cbc36a200c298cb08e504229 40f5c0c573ce12f16322d9efb12306750f672254cbc36a200c298cb08e504229
lib/codeql/swift/generated/Raw.qll 252bb96829d1c284ec8036e54f14db83d5a3c9be1c2bdc05bc7add7cf46ca618 4cdc6643270b2fc78805635a738dfd506bdee9dc770bc74ec66558c1efff7697
lib/codeql/swift/generated/Synth.qll b8bf274c60f60df473ed9093b50906822613dee047bda19ad37d07c308f04564 692590b0b18556a23cc1de0c8a60fd17534791dccb876cab85170bbf78392bd1
lib/codeql/swift/generated/SynthConstructors.qll d3b4b5d93be989004d7c05bbc32a5b859eaad768b4a52cfb01a767c90542f9a4 d3b4b5d93be989004d7c05bbc32a5b859eaad768b4a52cfb01a767c90542f9a4
lib/codeql/swift/generated/Raw.qll 10633b948918d315b98b6ff6733d4c368e082c5afd78334c0862291f9d883216 66abde4c9a2283773033d90a4633c1203d6563fc238ddbd48fdf1b910f90021a
lib/codeql/swift/generated/Synth.qll 848284b2ae9854c5be74e5ef50a51090e248e5c9c02289a6bc63455e440122da e2607f46a4830e81718ca1636fa65bc29420a18539443d109fafd7f1af1591ce
lib/codeql/swift/generated/SynthConstructors.qll 7edffc30d3dddc4d73241f4e0d3df4501a99eb38d056f82043ed69e481404342 7edffc30d3dddc4d73241f4e0d3df4501a99eb38d056f82043ed69e481404342
lib/codeql/swift/generated/UnknownFile.qll 5325944cf96a72d5d224597745e15960fb6a9448b96b6644ececd6344dfd9d74 5325944cf96a72d5d224597745e15960fb6a9448b96b6644ececd6344dfd9d74
lib/codeql/swift/generated/UnknownLocation.qll dfdeb8eedb2564eccaac416695784ea04fe9754a3e109e8484c695021af4e554 dfdeb8eedb2564eccaac416695784ea04fe9754a3e109e8484c695021af4e554
lib/codeql/swift/generated/UnspecifiedElement.qll 8ecc275cc131fe5aa61052299e10c49c3718f96416df9eeacabf5aea34d97982 b02dfcf0df3859551b176e065291da943670ab4da6ed84d02a0861ff689001c6
@@ -624,6 +626,7 @@ lib/codeql/swift/generated/stmt/ReturnStmt.qll 82910f3c8360b39a2b5b649d41d206372
lib/codeql/swift/generated/stmt/Stmt.qll 3912b8b28aaf01624ac377bdf8caae2c20741c9ef98cef75156e1b0c3a8b5163 9805adf45af0ad4a0734477a5d80b5bcbb2bece8e83411a76aba96042d0c7f18
lib/codeql/swift/generated/stmt/StmtCondition.qll cf03296a32292d836ff9050ffc6d3d5fc56c90f9473e7f70a67116417590ee76 c5694a39bdcab60beaa04a275ec99616dd868c12c878513f783a0eb52f328ba9
lib/codeql/swift/generated/stmt/SwitchStmt.qll 4e0ee2230d295e7b592e837b3ad94f122540f06107139a279302f67cff5cefe8 5bd92a4997e7308b046d985f04f21b1f4284c6f782b56563c1020021f34755a4
lib/codeql/swift/generated/stmt/ThenStmt.qll b0fb20f9ebfa836675912c385c133acbfc57f48b431a58ede48099cac131491d c78838d9084ff18f813e9cad68a56f8a838ed4ac59f046411442226bb41ad763
lib/codeql/swift/generated/stmt/ThrowStmt.qll 888825d19ced5a03dad6a20af8f8d86e8d8eb8fd8f69eaba9c0d0b58cbefac90 517d4aa93a9ae1874ac64dc1d6a170b4cde8e51c8f842dcba058ff2c61086ffd
lib/codeql/swift/generated/stmt/WhileStmt.qll cca25bd25aaea758dce474354d5e57d92eaa5ca5abb918f8d677feb2be6d3b0d d7ae1bdd69c25d8eb882522053b07048f3a0f1bb5ed8dcbd5b3efbfe0f72631b
lib/codeql/swift/generated/stmt/YieldStmt.qll c4619558f406dcf3ed1a0171b6c4b93c415fb5419745391c4df217d45e76b3f0 ca5c954cacf21233a35b88fe3e6de2eba0017e4e08b3f51b9d2bac6b01d8a219
@@ -898,6 +901,7 @@ test/extractor-tests/generated/expr/RebindSelfInInitializerExpr/MISSING_SOURCE.t
test/extractor-tests/generated/expr/RegexLiteralExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/SingleValueStmtExpr/SingleValueStmtExpr.ql efbfaf798a86c5a7d8053a22f61249208db31edcdaf750f2671057ad2f376806 d3256d2315d5bd5420b40a4be9522752bb57897807ea3853a7a4c61e9a05e478
test/extractor-tests/generated/expr/SingleValueStmtExpr/SingleValueStmtExpr_getType.ql bfbeb24e57078b1bbaae331a6f3e8d13d0efbdca2228dbbca53b86d5e287efd8 864351b87f7981825e148a479e997936c653a4581e8a893eaed96ddeed891eab
test/extractor-tests/generated/expr/SingleValueStmtExpr/ThenStmt.ql 0bd26223160e846cfa64fad75672eab18b8ce27e24d802bc711f42a540d13ac7 6a5b7760c44ee34c6e33a517a52622cc70dbdee88eb20eaea787be0e1f888996
test/extractor-tests/generated/expr/StringLiteralExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/SubscriptExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/SuperRefExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7

4
swift/ql/.gitattributes generated vendored
View File

@@ -273,6 +273,8 @@
/lib/codeql/swift/elements/stmt/Stmt.qll linguist-generated
/lib/codeql/swift/elements/stmt/StmtConditionConstructor.qll linguist-generated
/lib/codeql/swift/elements/stmt/SwitchStmtConstructor.qll linguist-generated
/lib/codeql/swift/elements/stmt/ThenStmt.qll linguist-generated
/lib/codeql/swift/elements/stmt/ThenStmtConstructor.qll linguist-generated
/lib/codeql/swift/elements/stmt/ThrowStmtConstructor.qll linguist-generated
/lib/codeql/swift/elements/stmt/WhileStmtConstructor.qll linguist-generated
/lib/codeql/swift/elements/stmt/YieldStmtConstructor.qll linguist-generated
@@ -626,6 +628,7 @@
/lib/codeql/swift/generated/stmt/Stmt.qll linguist-generated
/lib/codeql/swift/generated/stmt/StmtCondition.qll linguist-generated
/lib/codeql/swift/generated/stmt/SwitchStmt.qll linguist-generated
/lib/codeql/swift/generated/stmt/ThenStmt.qll linguist-generated
/lib/codeql/swift/generated/stmt/ThrowStmt.qll linguist-generated
/lib/codeql/swift/generated/stmt/WhileStmt.qll linguist-generated
/lib/codeql/swift/generated/stmt/YieldStmt.qll linguist-generated
@@ -900,6 +903,7 @@
/test/extractor-tests/generated/expr/RegexLiteralExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/SingleValueStmtExpr/SingleValueStmtExpr.ql linguist-generated
/test/extractor-tests/generated/expr/SingleValueStmtExpr/SingleValueStmtExpr_getType.ql linguist-generated
/test/extractor-tests/generated/expr/SingleValueStmtExpr/ThenStmt.ql linguist-generated
/test/extractor-tests/generated/expr/StringLiteralExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/SubscriptExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/SuperRefExpr/MISSING_SOURCE.txt linguist-generated

View File

@@ -227,6 +227,7 @@ import codeql.swift.elements.stmt.ReturnStmt
import codeql.swift.elements.stmt.Stmt
import codeql.swift.elements.stmt.StmtCondition
import codeql.swift.elements.stmt.SwitchStmt
import codeql.swift.elements.stmt.ThenStmt
import codeql.swift.elements.stmt.ThrowStmt
import codeql.swift.elements.stmt.WhileStmt
import codeql.swift.elements.stmt.YieldStmt

View File

@@ -0,0 +1,19 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `ThenStmt`.
*/
private import codeql.swift.generated.stmt.ThenStmt
/**
* A statement implicitly wrapping values to be used in branches of if/switch expressions. For example in:
* ```
* let rank = switch value {
* case 0..<0x80: 1
* case 0x80..<0x0800: 2
* default: 3
* }
* ```
* the literal expressions `1`, `2` and `3` are wrapped in `ThenStmt`.
*/
class ThenStmt extends Generated::ThenStmt { }

View File

@@ -0,0 +1,14 @@
// generated by codegen/codegen.py, remove this comment if you wish to edit this file
/**
* This module defines the hook used internally to tweak the characteristic predicate of
* `ThenStmt` synthesized instances.
* INTERNAL: Do not use.
*/
private import codeql.swift.generated.Raw
/**
* The characteristic predicate of `ThenStmt` synthesized instances.
* INTERNAL: Do not use.
*/
predicate constructThenStmt(Raw::ThenStmt id) { any() }

View File

@@ -3780,6 +3780,19 @@ private module Impl {
)
}
private Element getImmediateChildOfThenStmt(ThenStmt e, int index, string partialPredicateCall) {
exists(int b, int bStmt, int n |
b = 0 and
bStmt = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfStmt(e, i, _)) | i) and
n = bStmt and
(
none()
or
result = getImmediateChildOfStmt(e, index - b, partialPredicateCall)
)
)
}
private Element getImmediateChildOfThrowStmt(ThrowStmt e, int index, string partialPredicateCall) {
exists(int b, int bStmt, int n, int nSubExpr |
b = 0 and
@@ -5466,6 +5479,8 @@ private module Impl {
or
result = getImmediateChildOfReturnStmt(e, index, partialAccessor)
or
result = getImmediateChildOfThenStmt(e, index, partialAccessor)
or
result = getImmediateChildOfThrowStmt(e, index, partialAccessor)
or
result = getImmediateChildOfYieldStmt(e, index, partialAccessor)

View File

@@ -2923,6 +2923,27 @@ module Raw {
Expr getResult() { return_stmt_results(this, result) }
}
/**
* INTERNAL: Do not use.
* A statement implicitly wrapping values to be used in branches of if/switch expressions. For example in:
* ```
* let rank = switch value {
* case 0..<0x80: 1
* case 0x80..<0x0800: 2
* default: 3
* }
* ```
* the literal expressions `1`, `2` and `3` are wrapped in `ThenStmt`.
*/
class ThenStmt extends @then_stmt, Stmt {
override string toString() { result = "ThenStmt" }
/**
* Gets the result of this then statement.
*/
Expr getResult() { then_stmts(this, result) }
}
/**
* INTERNAL: Do not use.
*/

View File

@@ -823,6 +823,10 @@ module Synth {
* INTERNAL: Do not use.
*/
TSwitchStmt(Raw::SwitchStmt id) { constructSwitchStmt(id) } or
/**
* INTERNAL: Do not use.
*/
TThenStmt(Raw::ThenStmt id) { constructThenStmt(id) } or
/**
* INTERNAL: Do not use.
*/
@@ -1311,7 +1315,7 @@ module Synth {
class TStmt =
TBraceStmt or TBreakStmt or TCaseStmt or TContinueStmt or TDeferStmt or TDiscardStmt or
TFailStmt or TFallthroughStmt or TLabeledStmt or TPoundAssertStmt or TReturnStmt or
TThrowStmt or TYieldStmt;
TThenStmt or TThrowStmt or TYieldStmt;
/**
* INTERNAL: Do not use.
@@ -2891,6 +2895,13 @@ module Synth {
cached
TSwitchStmt convertSwitchStmtFromRaw(Raw::Element e) { result = TSwitchStmt(e) }
/**
* INTERNAL: Do not use.
* Converts a raw element to a synthesized `TThenStmt`, if possible.
*/
cached
TThenStmt convertThenStmtFromRaw(Raw::Element e) { result = TThenStmt(e) }
/**
* INTERNAL: Do not use.
* Converts a raw element to a synthesized `TThrowStmt`, if possible.
@@ -4116,6 +4127,8 @@ module Synth {
or
result = convertReturnStmtFromRaw(e)
or
result = convertThenStmtFromRaw(e)
or
result = convertThrowStmtFromRaw(e)
or
result = convertYieldStmtFromRaw(e)
@@ -5854,6 +5867,13 @@ module Synth {
cached
Raw::Element convertSwitchStmtToRaw(TSwitchStmt e) { e = TSwitchStmt(result) }
/**
* INTERNAL: Do not use.
* Converts a synthesized `TThenStmt` to a raw DB element, if possible.
*/
cached
Raw::Element convertThenStmtToRaw(TThenStmt e) { e = TThenStmt(result) }
/**
* INTERNAL: Do not use.
* Converts a synthesized `TThrowStmt` to a raw DB element, if possible.
@@ -7079,6 +7099,8 @@ module Synth {
or
result = convertReturnStmtToRaw(e)
or
result = convertThenStmtToRaw(e)
or
result = convertThrowStmtToRaw(e)
or
result = convertYieldStmtToRaw(e)

View File

@@ -190,6 +190,7 @@ import codeql.swift.elements.stmt.RepeatWhileStmtConstructor
import codeql.swift.elements.stmt.ReturnStmtConstructor
import codeql.swift.elements.stmt.StmtConditionConstructor
import codeql.swift.elements.stmt.SwitchStmtConstructor
import codeql.swift.elements.stmt.ThenStmtConstructor
import codeql.swift.elements.stmt.ThrowStmtConstructor
import codeql.swift.elements.stmt.WhileStmtConstructor
import codeql.swift.elements.stmt.YieldStmtConstructor

View File

@@ -0,0 +1,54 @@
// generated by codegen/codegen.py
/**
* This module provides the generated definition of `ThenStmt`.
* INTERNAL: Do not import directly.
*/
private import codeql.swift.generated.Synth
private import codeql.swift.generated.Raw
import codeql.swift.elements.expr.Expr
import codeql.swift.elements.stmt.Stmt
/**
* INTERNAL: This module contains the fully generated definition of `ThenStmt` and should not
* be referenced directly.
*/
module Generated {
/**
* A statement implicitly wrapping values to be used in branches of if/switch expressions. For example in:
* ```
* let rank = switch value {
* case 0..<0x80: 1
* case 0x80..<0x0800: 2
* default: 3
* }
* ```
* the literal expressions `1`, `2` and `3` are wrapped in `ThenStmt`.
* INTERNAL: Do not reference the `Generated::ThenStmt` class directly.
* Use the subclass `ThenStmt`, where the following predicates are available.
*/
class ThenStmt extends Synth::TThenStmt, Stmt {
override string getAPrimaryQlClass() { result = "ThenStmt" }
/**
* Gets the result of this then statement.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
*/
Expr getImmediateResult() {
result =
Synth::convertExprFromRaw(Synth::convertThenStmtToRaw(this).(Raw::ThenStmt).getResult())
}
/**
* Gets the result of this then statement.
*/
final Expr getResult() {
exists(Expr immediate |
immediate = this.getImmediateResult() and
result = immediate.resolve()
)
}
}
}

View File

@@ -1846,6 +1846,7 @@ condition_element_availabilities( //dir=stmt
| @labeled_stmt
| @pound_assert_stmt
| @return_stmt
| @then_stmt
| @throw_stmt
| @yield_stmt
;
@@ -1974,6 +1975,11 @@ return_stmt_results( //dir=stmt
int result: @expr_or_none ref
);
then_stmts( //dir=stmt
unique int id: @then_stmt,
int result: @expr_or_none ref
);
throw_stmts( //dir=stmt
unique int id: @throw_stmt,
int sub_expr: @expr_or_none ref

View File

@@ -1 +1,2 @@
| test.swift:2:3:5:3 | SingleValueStmtExpr | hasType: | yes | getStmt: | test.swift:2:3:5:3 | switch x { ... } |
| test.swift:2:3:7:3 | SingleValueStmtExpr | hasType: | yes | getStmt: | test.swift:2:3:7:3 | switch x { ... } |
| test.swift:11:3:11:30 | SingleValueStmtExpr | hasType: | yes | getStmt: | test.swift:11:3:11:30 | if ... then { ... } else { ... } |

View File

@@ -1 +1,2 @@
| test.swift:2:3:5:3 | SingleValueStmtExpr | Int |
| test.swift:2:3:7:3 | SingleValueStmtExpr | Int |
| test.swift:11:3:11:30 | SingleValueStmtExpr | Int |

View File

@@ -0,0 +1,4 @@
| test.swift:4:5:4:5 | ThenStmt | getResult: | test.swift:4:5:4:5 | 1 |
| test.swift:6:5:6:5 | ThenStmt | getResult: | test.swift:6:5:6:5 | 0 |
| test.swift:11:17:11:17 | ThenStmt | getResult: | test.swift:11:17:11:17 | 1 |
| test.swift:11:28:11:28 | ThenStmt | getResult: | test.swift:11:28:11:28 | 0 |

View File

@@ -0,0 +1,10 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from ThenStmt x, Expr getResult
where
toBeTested(x) and
not x.isUnknown() and
getResult = x.getResult()
select x, "getResult:", getResult

View File

@@ -1,6 +1,12 @@
func a(_ x: Int) -> Int {
switch x {
case 0:
1
default:
0
}
}
func b(_ x: Int) -> Int {
if (x < 42) { 1 } else { 0 }
}

View File

@@ -994,6 +994,20 @@ class ThrowStmt(Stmt):
class YieldStmt(Stmt):
results: list[Expr] | child
@qltest.test_with('SingleValueStmtExpr')
class ThenStmt(Stmt):
""" A statement implicitly wrapping values to be used in branches of if/switch expressions. For example in:
```
let rank = switch value {
case 0..<0x80: 1
case 0x80..<0x0800: 2
default: 3
}
```
the literal expressions `1`, `2` and `3` are wrapped in `ThenStmt`.
"""
result: Expr
class DoCatchStmt(LabeledStmt):
body: Stmt | child
catches: list[CaseStmt] | child