diff options
-rw-r--r-- | elaborate.cxx | 15 | ||||
-rw-r--r-- | tapsets.cxx | 7 | ||||
-rwxr-xr-x | testsuite/semok/thirtysix.stp | 13 |
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(); } |