summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip.chimento@gmail.com>2019-12-14 13:43:53 -0800
committerPhilip Chimento <philip.chimento@gmail.com>2019-12-16 23:12:20 -0500
commit325525dba046d89187fce2b01c84796357eff29e (patch)
tree544a6d493c167361acd4fa87e1d1133f05031348
parent3c1250fc78f6fdb6957e523416a599a71d8e7f8d (diff)
assertion: Handle C++ try statements
We assume that in any catch blocks, program state has already been modified since an exception has been thrown, so we only look for assertion statements in the try block.
-rw-r--r--clang-plugin/assertion-extracter.cpp14
-rw-r--r--tests/assertion-extraction-cpp.cpp15
2 files changed, 29 insertions, 0 deletions
diff --git a/clang-plugin/assertion-extracter.cpp b/clang-plugin/assertion-extracter.cpp
index 257e91e..4a5ed2a 100644
--- a/clang-plugin/assertion-extracter.cpp
+++ b/clang-plugin/assertion-extracter.cpp
@@ -428,6 +428,20 @@ AssertionExtracter::is_assertion_stmt (Stmt& stmt, const ASTContext& context)
return is_assertion_stmt (*sub_expr, context);
}
+ case Stmt::StmtClass::CXXTryStmtClass: {
+ /* Handle a C++ try statement. We assume any assertions in any of the
+ * handler blocks happen after program state is modified, so we only
+ * consider the try block.
+ * Transformations:
+ * try { S1 } catch (…) { S2 } [ … catch (…) { Sn } ] ↦ calc(S1) */
+ CXXTryStmt& try_stmt = cast<CXXTryStmt> (stmt);
+
+ CompoundStmt* try_block = try_stmt.getTryBlock ();
+ if (try_block == NULL)
+ return NULL;
+
+ return is_assertion_stmt (*try_block, context);
+ }
case Stmt::StmtClass::GCCAsmStmtClass:
case Stmt::StmtClass::MSAsmStmtClass:
/* Inline assembly. There is no way we are parsing this, so
diff --git a/tests/assertion-extraction-cpp.cpp b/tests/assertion-extraction-cpp.cpp
index cbf79e1..8d52f0c 100644
--- a/tests/assertion-extraction-cpp.cpp
+++ b/tests/assertion-extraction-cpp.cpp
@@ -15,3 +15,18 @@
};
g_return_if_fail (Temp () && some_str);
}
+
+/*
+ * null passed to a callee that requires a non-null argument
+ * assertion_func (NULL, 1, obj);
+ * ~~~~ ^
+ * null passed to a callee that requires a non-null argument
+ * assertion_func (NULL, 3, NULL);
+ * ~~~~ ^
+ */
+{
+ try {
+ g_return_if_fail (some_str);
+ } catch (...) {
+ }
+}