diff --git a/swift/extractor/translators/StmtTranslator.cpp b/swift/extractor/translators/StmtTranslator.cpp index aeff01d705c..3a9f70756ed 100644 --- a/swift/extractor/translators/StmtTranslator.cpp +++ b/swift/extractor/translators/StmtTranslator.cpp @@ -174,4 +174,16 @@ void StmtTranslator::fillLabeledConditionalStmt(const swift::LabeledConditionalS fillLabeledStmt(stmt, entry); } +codeql::FailStmt StmtTranslator::translateFailStmt(const swift::FailStmt& stmt) { + return dispatcher.createEntry(stmt); +} + +codeql::PoundAssertStmt StmtTranslator::translatePoundAssertStmt( + const swift::PoundAssertStmt& stmt) { + auto entry = dispatcher.createEntry(stmt); + entry.condition = dispatcher.fetchLabel(stmt.getCondition()); + entry.message = stmt.getMessage(); + return entry; +} + } // namespace codeql diff --git a/swift/extractor/translators/StmtTranslator.h b/swift/extractor/translators/StmtTranslator.h index 25df100bfba..765cf6e4ce8 100644 --- a/swift/extractor/translators/StmtTranslator.h +++ b/swift/extractor/translators/StmtTranslator.h @@ -31,6 +31,8 @@ class StmtTranslator : public AstTranslatorBase { codeql::SwitchStmt translateSwitchStmt(const swift::SwitchStmt& stmt); codeql::FallthroughStmt translateFallthroughStmt(const swift::FallthroughStmt& stmt); codeql::YieldStmt translateYieldStmt(const swift::YieldStmt& stmt); + codeql::FailStmt translateFailStmt(const swift::FailStmt& stmt); + codeql::PoundAssertStmt translatePoundAssertStmt(const swift::PoundAssertStmt& stmt); private: void fillLabeledStmt(const swift::LabeledStmt& stmt, codeql::LabeledStmt& entry); diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index d6340128034..46d62581333 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -1116,6 +1116,10 @@ module Raw { class PoundAssertStmt extends @pound_assert_stmt, Stmt { override string toString() { result = "PoundAssertStmt" } + + Expr getCondition() { pound_assert_stmts(this, result, _) } + + string getMessage() { pound_assert_stmts(this, _, result) } } class ReturnStmt extends @return_stmt, Stmt { diff --git a/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll b/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll index 89703530084..52afcc8bb3c 100644 --- a/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll +++ b/swift/ql/lib/codeql/swift/generated/stmt/PoundAssertStmt.qll @@ -1,10 +1,36 @@ // generated by codegen/codegen.py private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw +import codeql.swift.elements.expr.Expr import codeql.swift.elements.stmt.Stmt module Generated { class PoundAssertStmt extends Synth::TPoundAssertStmt, Stmt { override string getAPrimaryQlClass() { result = "PoundAssertStmt" } + + /** + * Gets the condition of this pound assert 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 getImmediateCondition() { + result = + Synth::convertExprFromRaw(Synth::convertPoundAssertStmtToRaw(this) + .(Raw::PoundAssertStmt) + .getCondition()) + } + + /** + * Gets the condition of this pound assert statement. + */ + final Expr getCondition() { result = getImmediateCondition().resolve() } + + /** + * Gets the message of this pound assert statement. + */ + string getMessage() { + result = Synth::convertPoundAssertStmtToRaw(this).(Raw::PoundAssertStmt).getMessage() + } } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 9b503cdd7fc..f7df2a2f214 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -1696,7 +1696,9 @@ labeled_stmt_labels( //dir=stmt ); pound_assert_stmts( //dir=stmt - unique int id: @pound_assert_stmt + unique int id: @pound_assert_stmt, + int condition: @expr_or_none ref, + string message: string ref ); return_stmts( //dir=stmt diff --git a/swift/ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.expected b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.expected new file mode 100644 index 00000000000..a659ffbe751 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.expected @@ -0,0 +1 @@ +| fail.swift:2:15:2:22 | fail | diff --git a/swift/ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.ql b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.ql new file mode 100644 index 00000000000..d4cc968079b --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/FailStmt.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from FailStmt x +where toBeTested(x) and not x.isUnknown() +select x diff --git a/swift/ql/test/extractor-tests/generated/stmt/FailStmt/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/stmt/FailStmt/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/stmt/FailStmt/fail.swift b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/fail.swift new file mode 100644 index 00000000000..0b7e15af1a1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/FailStmt/fail.swift @@ -0,0 +1,3 @@ +struct S { + init?() { return nil } +} diff --git a/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.expected b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.expected new file mode 100644 index 00000000000..d8ba1130d6f --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.expected @@ -0,0 +1,3 @@ +| static_assert.swift:2:1:2:15 | #assert ... | getCondition: | static_assert.swift:2:9:2:14 | ... .==(_:_:) ... | getMessage: | | +| static_assert.swift:3:1:3:24 | #assert ... | getCondition: | static_assert.swift:3:9:3:14 | ... .!=(_:_:) ... | getMessage: | hello | +| static_failing_assert.swift:4:1:4:24 | #assert ... | getCondition: | static_failing_assert.swift:4:9:4:14 | ... .==(_:_:) ... | getMessage: | oh my | diff --git a/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql new file mode 100644 index 00000000000..aa86b7d2057 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/PoundAssertStmt.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from PoundAssertStmt x, Expr getCondition, string getMessage +where + toBeTested(x) and + not x.isUnknown() and + getCondition = x.getCondition() and + getMessage = x.getMessage() +select x, "getCondition:", getCondition, "getMessage:", getMessage diff --git a/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/static_assert.swift b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/static_assert.swift new file mode 100644 index 00000000000..c365b12484e --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/static_assert.swift @@ -0,0 +1,3 @@ +//codeql-extractor-options: -enable-experimental-static-assert +#assert(1 == 1) +#assert(1 != 0, "hello") diff --git a/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/static_failing_assert.swift b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/static_failing_assert.swift new file mode 100644 index 00000000000..2873c0c04b6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/stmt/PoundAssertStmt/static_failing_assert.swift @@ -0,0 +1,4 @@ +//codeql-extractor-options: -enable-experimental-static-assert +//codeql-extractor-expected-status: 1 + +#assert(1 == 0, "oh my") diff --git a/swift/schema.py b/swift/schema.py index 11be598a8c6..054fe879e2a 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -742,7 +742,8 @@ class LabeledStmt(Stmt): label: optional[string] class PoundAssertStmt(Stmt): - pass + condition: Expr + message: string class ReturnStmt(Stmt): result: optional[Expr] | child