From c081af734881ec83041aa5acbd9242112af22794 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Thu, 16 Jan 2014 17:07:03 -0500 Subject: [PATCH] semantic_error: let it own its chain This patch simplifies the way semantic_error chains are used by allowing the parent object to own its chain. Upon setting the chain, the parent creates a copy and keeps it secret, to be de-allocated upon destruction. The patch also modifies the semantic_error constructor to allow the chain to be also set at the same time. --- elaborate.cxx | 7 +++---- session.cxx | 10 ++++------ staptree.cxx | 15 +++++++++++---- staptree.h | 43 +++++++++++++++++++++++++++++++++++++------ tapsets.cxx | 4 ++-- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/elaborate.cxx b/elaborate.cxx index 2e415b667..537bb7d6d 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1061,8 +1061,7 @@ derive_probes (systemtap_session& s, { // XXX: prefer not to print_error at every nest/unroll level semantic_error* er = new SEMANTIC_ERROR (_("while resolving probe point"), - loc->components[0]->tok); - er->chain = & e; + loc->components[0]->tok, NULL, &e); s.print_error (* er); delete er; } @@ -5446,10 +5445,10 @@ typeresolution_info::mismatch (const token *tok, exp_type type, chain_msg << _F(" of index %d", index); chain_msg << _F(" was first inferred here (%s)", lex_cast(decl->type).c_str()); - err.chain = new SEMANTIC_ERROR(chain_msg.str(), original->tok); + semantic_error chain(ERR_SRC, chain_msg.str(), original->tok); + err.set_chain(chain); session.print_error (err); - if (err.chain) delete err.chain; } else if (!assert_resolvability) mismatch_complexity = max(3, mismatch_complexity); diff --git a/session.cxx b/session.cxx index 074253b03..fa40c71af 100644 --- a/session.cxx +++ b/session.cxx @@ -1815,11 +1815,9 @@ systemtap_session::register_library_aliases() } catch (const semantic_error& e) { - semantic_error* er = new SEMANTIC_ERROR (_("while registering probe alias"), - alias->tok); - er->chain = & e; - print_error (* er); - delete er; + semantic_error er(ERR_SRC, _("while registering probe alias"), + alias->tok, NULL, &e); + print_error (er); } } } @@ -1872,7 +1870,7 @@ systemtap_session::print_error (const semantic_error& se) if (verbose > 0 || seen_errors[se.errsrc_chain()] < 1) { seen_errors[se.errsrc_chain()]++; - for (const semantic_error *e = &se; e != NULL; e = e->chain) + for (const semantic_error *e = &se; e != NULL; e = e->get_chain()) cerr << build_error_msg(*e); } else suppressed_errors++; diff --git a/staptree.cxx b/staptree.cxx index c8aede4a7..77bb7f03d 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -169,10 +169,13 @@ vardecl::set_arity (int a, const token* t) if (arity != a && arity >= 0) { semantic_error err (ERR_SRC, _F("inconsistent arity (%s vs %d)", - lex_cast(arity).c_str(), a), t?:tok); + lex_cast(arity).c_str(), a), t?:tok); if (arity_tok) - err.chain = new SEMANTIC_ERROR (_F("arity %s first inferred here", + { + semantic_error chain(ERR_SRC, _F("arity %s first inferred here", lex_cast(arity).c_str()), arity_tok); + err.set_chain(chain); + } throw err; } @@ -276,8 +279,12 @@ void target_symbol::chain (const semantic_error &er) semantic_error* e = new semantic_error(er); if (!e->tok1) e->tok1 = this->tok; - assert (e->chain == 0); - e->chain = this->saved_conversion_error; + assert (e->get_chain() == 0); + if (this->saved_conversion_error) + { + e->set_chain(*this->saved_conversion_error); + delete this->saved_conversion_error; + } this->saved_conversion_error = e; } diff --git a/staptree.h b/staptree.h index 3d263d567..032bb7549 100644 --- a/staptree.h +++ b/staptree.h @@ -32,22 +32,53 @@ struct semantic_error: public std::runtime_error { const token* tok1; const token* tok2; - const semantic_error *chain; - const std::string errsrc; + std::string errsrc; - ~semantic_error () throw () {} + ~semantic_error () throw () + { + if (chain) + delete chain; + } semantic_error (const std::string& src, const std::string& msg, const token* t1=0): - runtime_error (msg), tok1 (t1), tok2 (0), chain (0), errsrc(src) {} + runtime_error (msg), tok1 (t1), tok2 (0), errsrc (src), chain (0) {} semantic_error (const std::string& src, const std::string& msg, const token* t1, - const token* t2): - runtime_error (msg), tok1 (t1), tok2 (t2), chain (0), errsrc(src) {} + const token* t2, const semantic_error* chn=0): + runtime_error (msg), tok1 (t1), tok2 (t2), errsrc (src), chain (0) + { + if (chn) + set_chain(*chn); + } + + /* override copy-ctor to deep-copy chain */ + semantic_error (const semantic_error& other): + runtime_error(other), tok1(other.tok1), tok2(other.tok2), + errsrc(other.errsrc), chain (0) + { + if (other.chain) + set_chain(*other.chain); + } std::string errsrc_chain(void) const { return errsrc + (chain ? "|" + chain->errsrc_chain() : ""); } + + void set_chain(const semantic_error& new_chain) + { + if (chain) + delete chain; + chain = new semantic_error(new_chain); + } + + const semantic_error* get_chain(void) const + { + return chain; + } + +private: + const semantic_error* chain; }; // ------------------------------------------------------------------------ diff --git a/tapsets.cxx b/tapsets.cxx index 85065933f..a34dd486b 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3698,7 +3698,7 @@ dwarf_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) { for (const semantic_error *c = tsym->saved_conversion_error; c != 0; - c = c->chain) { + c = c->get_chain()) { clog << _("variable location problem [man error::dwarf]: ") << c->what() << endl; } } @@ -9604,7 +9604,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) { if (dw.sess.verbose>2) for (const semantic_error *c = tsym->saved_conversion_error; - c != 0; c = c->chain) + c != 0; c = c->get_chain()) clog << _("variable location problem [man error::dwarf]: ") << c->what() << endl; pf->raw_components += "=?"; continue; -- 2.43.5