diff options
author | Philip Chimento <philip.chimento@gmail.com> | 2019-12-14 13:43:53 -0800 |
---|---|---|
committer | Philip Chimento <philip.chimento@gmail.com> | 2019-12-16 23:12:20 -0500 |
commit | 325525dba046d89187fce2b01c84796357eff29e (patch) | |
tree | 544a6d493c167361acd4fa87e1d1133f05031348 | |
parent | 3c1250fc78f6fdb6957e523416a599a71d8e7f8d (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.cpp | 14 | ||||
-rw-r--r-- | tests/assertion-extraction-cpp.cpp | 15 |
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 (...) { + } +} |