summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2010-02-25 16:20:50 -0800
committerJosh Stone <jistone@redhat.com>2010-02-25 16:20:50 -0800
commitb7aedf26f105793793c66c39c85abe76e1510e66 (patch)
treee38acbbc143220e87a2226b55832264d970fc144
parent70208613b8f9f2584aee89197705f3fddae6a0e4 (diff)
downloadsystemtap-steved-b7aedf26f105793793c66c39c85abe76e1510e66.tar.gz
systemtap-steved-b7aedf26f105793793c66c39c85abe76e1510e66.tar.xz
systemtap-steved-b7aedf26f105793793c66c39c85abe76e1510e66.zip
Expand @defined to support more cases
* tapsets.cxx (var_expanding_visitor::visit_defined_op): If no error was raised or replacement made on a target_symbol, then its @defined state is still indeterminate. Some later pass (like @cast) might handle it. * elaborate.cxx (const_folder::visit_defined_op): Squash any escapees. * testsuite/semok/thirtysix.stp: Add more variants.
-rw-r--r--elaborate.cxx15
-rw-r--r--tapsets.cxx7
-rwxr-xr-xtestsuite/semok/thirtysix.stp13
3 files changed, 34 insertions, 1 deletions
diff --git a/elaborate.cxx b/elaborate.cxx
index 5f3cc8ae..12dbce3a 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -3010,6 +3010,7 @@ struct const_folder: public update_visitor
void visit_comparison (comparison* e);
void visit_concatenation (concatenation* e);
void visit_ternary_expression (ternary_expression* e);
+ void visit_defined_op (defined_op* e);
};
void
@@ -3471,6 +3472,20 @@ const_folder::visit_ternary_expression (ternary_expression* e)
}
}
+void
+const_folder::visit_defined_op (defined_op* e)
+{
+ // If a @defined makes it this far, then it is, de facto, undefined.
+
+ if (session.verbose>2)
+ clog << "Collapsing untouched @defined check " << *e->tok << endl;
+ relaxed_p = false;
+
+ literal_number* n = new literal_number (0);
+ n->tok = e->tok;
+ n->visit (this);
+}
+
static void semantic_pass_const_fold (systemtap_session& s, bool& relaxed_p)
{
// Let's simplify statements with constant values.
diff --git a/tapsets.cxx b/tapsets.cxx
index ca439ede..d470b043 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1982,7 +1982,12 @@ var_expanding_visitor::visit_defined_op (defined_op* e)
else if (foo2 && foo2->probe_context_var != "") // successful
resolved = true;
else if (foo2) // unresolved but not marked either way
- assert (0); // should not happen
+ {
+ // it might be resolved by some other pass
+ e->operand = foo2;
+ provide (e);
+ return;
+ }
else // resolved, rewritten to some other expression type
resolved = true;
} catch (const semantic_error& e) {
diff --git a/testsuite/semok/thirtysix.stp b/testsuite/semok/thirtysix.stp
index e31a51ce..5965a7df 100755
--- a/testsuite/semok/thirtysix.stp
+++ b/testsuite/semok/thirtysix.stp
@@ -19,3 +19,16 @@ probe process("stap").syscall { println(@defined($argZZ)?$argZZ:0) } # invalid
probe process("stap").syscall.return { println(@defined($nosuchvar)?$nosuchvar:0) } # invalid
probe process("stap").syscall.return { println(@defined($syscall)?$syscall:0) } # valid
%)
+
+probe begin,end,error,never { println(@defined($nosuchvar)?$nosuchvar:0) } # invalid
+probe timer.s(1),timer.jiffies(1) { println(@defined($nosuchvar)?$nosuchvar:0) } # invalid
+probe timer.profile { println(@defined($nosuchvar)?$nosuchvar:0) } # invalid
+
+probe begin { println(@defined(@cast(0, "task_struct")->foo)?$nosuchvar:0) } # invalid
+probe begin { println(@defined(@cast(0, "task_struct")->pid)?1:0) } # valid
+probe kernel.function("sys_open") { println(@defined(@cast(0, "task_struct")->foo)?$nosuchvar:0) } # invalid
+probe kernel.function("sys_open") { println(@defined(@cast(0, "task_struct")->pid)?1:0) } # valid
+
+function foo1() { println(@defined(@cast(0, "task_struct")->foo)?$nosuchvar:0) } # invalid
+function foo2() { println(@defined(@cast(0, "task_struct")->pid)?1:0) } # valid
+probe begin { foo1(); foo2(); }