From a7c9924bca8c69998b237047ec03a8faf9638a94 Mon Sep 17 00:00:00 2001 From: fche Date: Tue, 18 Apr 2006 19:19:35 +0000 Subject: 2006-04-18 Frank Ch. Eigler PR 2220 * translate.cxx (visit_statement): Tolerate 0 first argument. (visit_for_loop, visit_foreach_loop): Call it thusly for condition expression. (visit_embededcode, visit_block, visit_null_statement): Don't call visit_statement() at all. 2006-04-18 Frank Ch. Eigler * conversions.stp (string, hex_string): Use snprintf for safety. 2006-04-18 Frank Ch. Eigler * systemtap.samples/control_limits.stp: Adapt to new action counting. --- translate.cxx | 60 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 13 deletions(-) (limited to 'translate.cxx') diff --git a/translate.cxx b/translate.cxx index 6e915465..08be0f34 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1834,19 +1834,23 @@ void c_unparser::visit_statement (statement *s, unsigned actions) { // For some constructs, it is important to avoid an error branch - // right to the bottom of the probe/function. The foreach() locking - // construct is one example. Instead, if we are nested within a - // loop, we branch merely to its "break" label. The next statement - // will branch one level higher, and so on, until we can go straight - // "out". + // right to the bottom of the probe/function. The foreach() + // iteration construct is one example. Instead, if we are nested + // within a loop, we branch merely to its "break" label. The next + // statement will branch one level higher, and so on, until we can + // go straight "out". string outlabel = "out"; unsigned loops = loop_break_labels.size(); if (loops > 0) outlabel = loop_break_labels[loops-1]; - o->newline() << "if (unlikely (c->last_error)) goto " << outlabel << ";"; - assert (s->tok); - o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";"; + if (s) + { + o->newline() << "if (unlikely (c->last_error)) goto " << outlabel << ";"; + assert (s->tok); + o->newline() << "c->last_stmt = " << lex_cast_qstring(*s->tok) << ";"; + } + if (actions > 0) { o->newline() << "c->actioncount += " << actions << ";"; @@ -1864,7 +1868,13 @@ c_unparser::visit_block (block *s) { o->newline() << "{"; o->indent (1); - visit_statement (s, 0); + + // visit_statement (s, 0); + // + // NB: this is not necessary, since the last_error can be handled + // just as easily by the first real body statement, and the + // last_stmt won't be used since this nesting structure cannot + // itself cause an error. for (unsigned i=0; istatements.size(); i++) { @@ -1885,7 +1895,12 @@ c_unparser::visit_block (block *s) void c_unparser::visit_embeddedcode (embeddedcode *s) { - visit_statement (s, 1); + // visit_statement (s, 1); + // + // NB: this is not necessary, since this can occur only at the top + // level of a function (so no errors can be pending), and the + // action-count is already incremented at the point of call. + o->newline() << "{"; o->newline(1) << s->code; o->newline(-1) << "}"; @@ -1895,7 +1910,12 @@ c_unparser::visit_embeddedcode (embeddedcode *s) void c_unparser::visit_null_statement (null_statement *s) { - visit_statement (s, 0); + // visit_statement (s, 0); + // + // NB: this is not necessary, since the last_error can be handled just as + // easily by the next statement, and the last_stmt won't be used since this + // statement cannot cause an error. + o->newline() << "/* null */;"; } @@ -1976,7 +1996,14 @@ c_unparser::visit_for_loop (for_loop *s) // condition o->newline(-1) << toplabel << ":"; - o->newline(1) << "if (! ("; + + // Emit an explicit actioncount increment here to cover the act of + // iteration. Equivalently, it can stand for the evaluation of the + // condition expression. + o->indent(1); + visit_statement (0, 1); + + o->newline() << "if (! ("; if (s->cond->type != pe_long) throw semantic_error ("expected numeric type", s->cond->tok); s->cond->visit (this); @@ -2141,7 +2168,14 @@ c_unparser::visit_foreach_loop (foreach_loop *s) // condition o->newline(-1) << toplabel << ":"; - o->newline(1) << "if (! (" << iv << ")) goto " << breaklabel << ";"; + + // Emit an explicit actioncount increment here to cover the act of + // iteration. Equivalently, it can stand for the evaluation of the + // condition expression. + o->indent(1); + visit_statement (0, 1); + + o->newline() << "if (! (" << iv << ")) goto " << breaklabel << ";"; // body loop_break_labels.push_back (breaklabel); -- cgit