diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | tapset/ChangeLog | 4 | ||||
-rw-r--r-- | tapset/conversions.stp | 4 | ||||
-rw-r--r-- | translate.cxx | 60 |
4 files changed, 62 insertions, 15 deletions
@@ -1,3 +1,12 @@ +2006-04-18 Frank Ch. Eigler <fche@elastic.org> + + 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 Martin Hunt <hunt@redhat.com> * Makefile.am (install-data-local): Tweak previous fix. diff --git a/tapset/ChangeLog b/tapset/ChangeLog index 7d5ce509..9c05f71b 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,7 @@ +2006-04-18 Frank Ch. Eigler <fche@elastic.org> + + * conversions.stp (string, hex_string): Use snprintf for safety. + 2006-04-18 Martin Hunt <hunt@redhat.com> * conversions.stp (user_string): Reenable error message. diff --git a/tapset/conversions.stp b/tapset/conversions.stp index d46f8c18..b05d7a8e 100644 --- a/tapset/conversions.stp +++ b/tapset/conversions.stp @@ -7,11 +7,11 @@ // later version. function hexstring:string (num:long) %{ - sprintf (THIS->__retvalue, "0x%llx", (long long) THIS->num); + snprintf (THIS->__retvalue, MAXSTRINGLEN, "0x%llx", (long long) THIS->num); %} function string:string (num:long) %{ - sprintf (THIS->__retvalue, "%lld", (long long) THIS->num); + snprintf (THIS->__retvalue, MAXSTRINGLEN, "%lld", (long long) THIS->num); %} function kernel_string:string (addr:long) %{ 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; i<s->statements.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); |