return false;
}
+/* class catch_cfg_edge_event : public cfg_edge_event. */
+
+diagnostics::paths::event::meaning
+catch_cfg_edge_event::get_meaning () const
+{
+ return meaning (verb::catch_);
+}
+
/* class call_event : public superedge_event. */
/* call_event's ctor. */
get_user_facing_name (m_setjmp_call));
}
+diagnostics::paths::event::meaning
+setjmp_event::get_meaning () const
+{
+ return meaning (verb::setjmp_);
+}
+
/* Implementation of checker_event::prepare_for_emission vfunc for setjmp_event.
Record this setjmp's event ID into the path, so that rewind events can
return m_eedge->m_dest->get_function ()->decl;
}
+diagnostics::paths::event::meaning
+rewind_event::get_meaning () const
+{
+ return meaning (verb::longjmp_);
+}
+
/* rewind_event's ctor. */
rewind_event::rewind_event (const exploded_edge *eedge,
/* class throw_event : public checker_event. */
+diagnostics::paths::event::meaning
+throw_event::get_meaning () const
+{
+ return meaning (verb::throw_);
+}
+
/* class explicit_throw_event : public throw_event. */
void
explicit_throw_event::print_desc (pretty_printer &pp) const
pp_printf (&pp, "unwinding stack frame");
}
+diagnostics::paths::event::meaning
+unwind_event::get_meaning () const
+{
+ return meaning (verb::unwind_);
+}
+
/* class warning_event : public checker_event. */
/* Implementation of diagnostics::paths::event::print_desc vfunc for
pp_string (&pp, "...catching exception here");
}
+ meaning get_meaning () const override;
+
private:
tree m_type;
};
void print_desc (pretty_printer &pp) const final override;
+ meaning get_meaning () const override;
+
void prepare_for_emission (checker_path *path,
pending_diagnostic *pd,
diagnostics::paths::event_id_t emission_id) final override;
tree get_setjmp_caller () const;
const exploded_edge *get_eedge () const { return m_eedge; }
+ meaning get_meaning () const override;
+
protected:
rewind_event (const exploded_edge *eedge,
enum event_kind kind,
{
}
+ meaning get_meaning () const override;
+
protected:
const exploded_node *m_enode;
const gcall &m_throw_call;
{
}
+ meaning get_meaning () const override;
+
void print_desc (pretty_printer &pp) const final override;
int m_num_frames;
return "branch";
case verb::danger:
return "danger";
+
+ /* Special control flow operations.
+
+ These are not part of SARIF v2.1.0 section 3.38.8, but the
+ spec allows other values; see
+ https://github.com/oasis-tcs/sarif-spec/issues/735 */
+ case verb::throw_:
+ return "throw";
+ case verb::catch_:
+ return "catch";
+ case verb::unwind_:
+ return "unwind";
+ case verb::setjmp_:
+ return "setjmp";
+ case verb::longjmp_:
+ return "longjmp";
}
}
return_,
branch,
- danger
+ danger,
+
+ // Special control flow operations:
+ throw_,
+ catch_,
+ unwind_, // unwinding stack frame(s) during exception-handling
+ setjmp_,
+ longjmp_
};
enum class noun
{
m_property (property::unknown)
{
}
+ meaning (enum verb verb)
+ : m_verb (verb), m_noun (noun::unknown), m_property (property::unknown)
+ {
+ }
meaning (enum verb verb, enum noun noun)
: m_verb (verb), m_noun (noun), m_property (property::unknown)
{
--- /dev/null
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_kinds(sarif):
+ result = get_result_by_index(sarif, 0)
+
+ assert result['level'] == 'note'
+
+ events = result["codeFlows"][0]["threadFlows"][0]['locations']
+
+ # Event "(1)": "throwing exception of type 'value_error' here..." (index == 0)
+ assert events[0]['location']['message']['text'] == "throwing exception of type 'value_error' here..."
+ assert events[0]['kinds'] == ["throw"]
+
+ # Event "(2)": "...catching exception of type 'value_error' here" (index == 1)
+ assert events[1]['location']['message']['text'] == "...catching exception of type 'value_error' here"
+ assert events[1]['kinds'] == ["catch"]
+/* { dg-additional-options "-fdiagnostics-add-output=sarif" } */
+
/* Verify that we follow the correct paths when we know the typeinfo of
an exception. */
__analyzer_dump_path (); // { dg-bogus "path" }
return 0;
}
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest exception-path-1.C "exception-path-1-sarif.py" } } */
--- /dev/null
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_kinds(sarif):
+ result = get_result_by_index(sarif, 0)
+
+ assert result['level'] == 'note'
+
+ events = result["codeFlows"][0]["threadFlows"][0]['locations']
+
+ assert events[-4]['location']['message']['text'] == "throwing exception of type 'value_error' here..."
+ assert events[-4]['kinds'] == ["throw"]
+
+ assert events[-3]['location']['message']['text'] == "unwinding 2 stack frames"
+ assert events[-3]['kinds'] == ["unwind"]
+
+ assert events[-2]['location']['message']['text'] == "...catching exception of type 'value_error' here"
+ assert events[-2]['kinds'] == ["catch"]
+/* { dg-additional-options "-fdiagnostics-add-output=sarif" } */
+
/* Verify that we follow the correct paths when we know the typeinfo of
an exception: interprocedural case where unwind multiple frame,
failing to match the type. */
__analyzer_dump_path (); // { dg-bogus "path" }
return 0;
}
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest exception-path-unwind-multiple-2.C "exception-path-unwind-multiple-2-sarif.py" } } */
--- /dev/null
+from sarif import *
+
+import pytest
+
+@pytest.fixture(scope='function', autouse=True)
+def sarif():
+ return sarif_from_env()
+
+def test_kinds(sarif):
+ result = get_result_by_index(sarif, 0)
+
+ assert result['level'] == 'note'
+
+ events = result["codeFlows"][0]["threadFlows"][0]['locations']
+
+ assert events[1]['location']['message']['text'] == "'setjmp' called here"
+ assert events[1]['kinds'] == ["setjmp"]
+
+ assert events[6]['location']['message']['text'] == "rewinding from 'longjmp' in 'inner'..."
+ assert events[6]['kinds'] == ["longjmp"]
+
+ assert events[7]['location']['message']['text'].startswith("...to 'setjmp' in 'outer'")
+ assert events[7]['kinds'] == ["longjmp"]
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
+/* { dg-additional-options "-fdiagnostics-add-output=sarif" } */
+
/* { dg-enable-nn-line-numbers "" } */
/* { dg-require-effective-target indirect_jumps } */
| | (11) here
|
{ dg-end-multiline-output "" } */
+
+/* Verify that some JSON was written to a file with the expected name. */
+/* { dg-final { verify-sarif-file } } */
+
+/* Use a Python script to verify various properties about the generated
+ .sarif file:
+ { dg-final { run-sarif-pytest setjmp-3.c "setjmp-3-sarif.py" } } */