summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--tapset/ChangeLog4
-rw-r--r--tapset/conversions.stp4
-rw-r--r--translate.cxx60
4 files changed, 62 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index 0726efef..baaf936c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);