systemc: Change how errors are handled in some constructors slightly.
authorGabe Black <gabeblack@google.com>
Wed, 3 Oct 2018 23:17:50 +0000 (16:17 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 16 Oct 2018 00:49:44 +0000 (00:49 +0000)
Because SC_REPORT_ERROR usually causes an exception to be thrown, it's
easy to assume it will be the last thing executed in a function. It
might, however, be set up to do nothing, in which case the function
will continue to execute.

This change makes sure sc_prim will be set up properly even if errors
about the time a channel can be set up are ignored.

Also, if an exception is thrown while sc_port is being set up, the
corresponding Port object needs to be cleaned up. Rather than try to
intercept exceptions in the constructor and clean up properly, we'll
just make the allocation of the Port object be the last thing it does.
If the function exits early, then the Port pointer will still be
nullptr and nothing will need to be done.

Change-Id: If8f6f6b7e6830235fee3cd75625240b99e87dfbe
Reviewed-on: https://gem5-review.googlesource.com/c/13289
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/core/sc_port.cc
src/systemc/core/sc_prim.cc

index 3a31e411d2f28fb6ec23ec125e2d4b734e79193a..50a67a3b6f1f72bff1b6a2ac2c1f31a9e10e0882 100644 (file)
@@ -56,7 +56,7 @@ reportError(const char *id, const char *add_msg,
 }
 
 sc_port_base::sc_port_base(const char *n, int max_size, sc_port_policy p) :
-    sc_object(n), _gem5Port(new ::sc_gem5::Port(this, max_size))
+    sc_object(n), _gem5Port(nullptr)
 {
     if (sc_is_running()) {
         reportError("(E110) insert port failed", "simulation running",
@@ -74,6 +74,7 @@ sc_port_base::sc_port_base(const char *n, int max_size, sc_port_policy p) :
     } else {
         m->ports.push_back(this);
     }
+    _gem5Port = new ::sc_gem5::Port(this, max_size);
 }
 
 sc_port_base::~sc_port_base()
index 216bd78f90d7850b04747f29dd09bf55cbad367e..099e5d8bfc4bb82cf23fd5424b94b75dd14fdf39 100644 (file)
@@ -48,12 +48,12 @@ sc_prim_channel::sc_prim_channel() : _gem5_channel(nullptr)
     if (sc_is_running()) {
         SC_REPORT_ERROR("(E113) insert primitive channel failed",
                 "simulation running");
-    } else if (::sc_gem5::scheduler.elaborationDone()) {
+    }
+    if (::sc_gem5::scheduler.elaborationDone()) {
         SC_REPORT_ERROR("(E113) insert primitive channel failed",
                 "elaboration done");
-    } else {
-        _gem5_channel = new sc_gem5::Channel(this);
     }
+    _gem5_channel = new sc_gem5::Channel(this);
 }
 
 sc_prim_channel::sc_prim_channel(const char *_name) :
@@ -62,12 +62,12 @@ sc_prim_channel::sc_prim_channel(const char *_name) :
     if (sc_is_running()) {
         SC_REPORT_ERROR("(E113) insert primitive channel failed",
                 "simulation running");
-    } else if (::sc_gem5::scheduler.elaborationDone()) {
+    }
+    if (::sc_gem5::scheduler.elaborationDone()) {
         SC_REPORT_ERROR("(E113) insert primitive channel failed",
                 "elaboration done");
-    } else {
-        _gem5_channel = new sc_gem5::Channel(this);
     }
+    _gem5_channel = new sc_gem5::Channel(this);
 }
 
 sc_prim_channel::~sc_prim_channel() { delete _gem5_channel; }