1 // elaboration functions
2 // Copyright (C) 2005-2018 Red Hat Inc.
3 // Copyright (C) 2008 Intel Corporation
5 // This file is part of systemtap, and is free software. You can
6 // redistribute it and/or modify it under the terms of the GNU General
7 // Public License (GPL); either version 2, or (at your option) any
11 #include "elaborate.h"
12 #include "translate.h"
17 #include "task_finder.h"
18 #include "stapregex.h"
19 #include "stringtable.h"
22 #include <sys/utsname.h>
24 #define __STDC_FORMAT_MACROS
42 // ------------------------------------------------------------------------
44 // Used in probe_point condition construction. Either argument may be
45 // NULL; if both, return NULL too. Resulting expression is a deep
46 // copy for symbol resolution purposes.
47 expression
* add_condition (expression
* a
, expression
* b
)
49 if (!a
&& !b
) return 0;
50 if (! a
) return deep_copy_visitor::deep_copy(b
);
51 if (! b
) return deep_copy_visitor::deep_copy(a
);
56 la
.tok
= a
->tok
; // or could be b->tok
57 return deep_copy_visitor::deep_copy(& la
);
60 // ------------------------------------------------------------------------
64 derived_probe::derived_probe (probe
*p
, probe_point
*l
, bool rewrite_loc
):
65 base (p
), base_pp(l
), group(NULL
), sdt_semaphore_addr(0),
66 session_index((unsigned)-1)
70 this->privileged
= p
->privileged
;
71 this->synthetic
= p
->synthetic
;
72 this->body
= deep_copy_visitor::deep_copy(p
->body
);
75 // make a copy for subclasses which want to rewrite the location
77 l
= new probe_point(*l
);
78 this->locations
.push_back (l
);
83 derived_probe::printsig (ostream
& o
) const
90 derived_probe::printsig_nested (ostream
& o
) const
92 // We'd like to enclose the probe derivation chain in a /* */
93 // comment delimiter. But just printing /* base->printsig() */ is
94 // not enough, since base might itself be a derived_probe. So we,
95 // er, "cleverly" encode our nesting state as a formatting flag for
97 ios::fmtflags f
= o
.flags (ios::internal
);
98 if (f
& ios::internal
)
117 derived_probe::collect_derivation_chain (std::vector
<probe
*> &probes_list
) const
119 probes_list
.push_back(const_cast<derived_probe
*>(this));
120 base
->collect_derivation_chain(probes_list
);
125 derived_probe::collect_derivation_pp_chain (std::vector
<probe_point
*> &pp_list
) const
127 pp_list
.push_back(const_cast<probe_point
*>(this->sole_location()));
128 base
->collect_derivation_pp_chain(pp_list
);
133 derived_probe::derived_locations (bool firstFrom
)
136 vector
<probe_point
*> reference_point
;
137 collect_derivation_pp_chain(reference_point
);
138 if (reference_point
.size() > 0)
139 for(unsigned i
=1; i
<reference_point
.size(); ++i
)
141 if (firstFrom
|| i
>1)
143 o
<< reference_point
[i
]->str(false); // no ?,!,etc
150 derived_probe::sole_location () const
152 if (locations
.size() == 0 || locations
.size() > 1)
153 throw SEMANTIC_ERROR (_N("derived_probe with no locations",
154 "derived_probe with too many locations",
155 locations
.size()), this->tok
);
162 derived_probe::script_location () const
164 // This feeds function::pn() in the tapset, which is documented as the
165 // script-level probe point expression, *after wildcard expansion*.
166 vector
<probe_point
*> chain
;
167 collect_derivation_pp_chain (chain
);
169 // Go backwards until we hit the first well-formed probe point
170 for (int i
=chain
.size()-1; i
>=0; i
--)
171 if (chain
[i
]->well_formed
)
174 // If that didn't work, just fallback to -something-.
175 return sole_location();
180 derived_probe::emit_privilege_assertion (translator_output
* o
)
182 // Emit code which will cause compilation to fail if it is compiled in
183 // unprivileged mode.
184 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
185 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
186 o
->newline() << "#error Internal Error: Probe ";
187 probe::printsig (o
->line());
188 o
->line() << " generated in --unprivileged mode";
189 o
->newline() << "#endif";
194 derived_probe::emit_process_owner_assertion (translator_output
* o
)
196 // Emit code which will abort should the current target not belong to the
197 // user in unprivileged mode.
198 o
->newline() << "#if ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPDEV) && \\";
199 o
->newline() << " ! STP_PRIVILEGE_CONTAINS (STP_PRIVILEGE, STP_PR_STAPSYS)";
200 o
->newline(1) << "if (! is_myproc ()) {";
201 o
->newline(1) << "snprintf(c->error_buffer, sizeof(c->error_buffer),";
202 o
->newline() << " \"Internal Error: Process %d does not belong to user %d in probe %s in --unprivileged mode\",";
203 o
->newline() << " current->tgid, _stp_uid, c->probe_point);";
204 o
->newline() << "c->last_error = c->error_buffer;";
205 // NB: since this check occurs before probe locking, its exit should
206 // not be a "goto out", which would attempt unlocking.
207 o
->newline() << "return;";
208 o
->newline(-1) << "}";
209 o
->newline(-1) << "#endif";
213 derived_probe::print_dupe_stamp_unprivileged(ostream
& o
)
215 o
<< _("unprivileged users: authorized") << endl
;
219 derived_probe::print_dupe_stamp_unprivileged_process_owner(ostream
& o
)
221 o
<< _("unprivileged users: authorized for process owner") << endl
;
224 // ------------------------------------------------------------------------
225 // Members of derived_probe_builder
228 derived_probe_builder::build_with_suffix(systemtap_session
&,
231 literal_map_t
const &,
232 std::vector
<derived_probe
*> &,
233 std::vector
<probe_point::component
*>
235 // XXX perhaps build the probe if suffix is empty?
236 // if (suffix.empty()) {
237 // build (sess, use, location, parameters, finished_results);
240 throw SEMANTIC_ERROR (_("invalid suffix for probe"));
244 derived_probe_builder::get_param (literal_map_t
const & params
,
246 interned_string
& value
)
248 literal_map_t::const_iterator i
= params
.find (key
);
249 if (i
== params
.end())
251 literal_string
* ls
= dynamic_cast<literal_string
*>(i
->second
);
260 derived_probe_builder::get_param (literal_map_t
const & params
,
264 literal_map_t::const_iterator i
= params
.find (key
);
265 if (i
== params
.end())
267 if (i
->second
== NULL
)
269 literal_number
* ln
= dynamic_cast<literal_number
*>(i
->second
);
278 derived_probe_builder::has_null_param (literal_map_t
const & params
,
281 literal_map_t::const_iterator i
= params
.find(key
);
282 return (i
!= params
.end() && i
->second
== NULL
);
286 derived_probe_builder::has_param (literal_map_t
const & params
,
289 return (params
.find(key
) != params
.end());
292 // ------------------------------------------------------------------------
293 // Members of match_key.
295 match_key::match_key(interned_string n
)
297 have_parameter(false),
298 parameter_type(pe_unknown
)
302 match_key::match_key(probe_point::component
const & c
)
304 have_parameter(c
.arg
!= NULL
),
305 parameter_type(c
.arg
? c
.arg
->type
: pe_unknown
)
310 match_key::with_number()
312 have_parameter
= true;
313 parameter_type
= pe_long
;
318 match_key::with_string()
320 have_parameter
= true;
321 parameter_type
= pe_string
;
326 match_key::str() const
330 switch (parameter_type
)
332 case pe_string
: return n
+ "(string)";
333 case pe_long
: return n
+ "(number)";
334 default: return n
+ "(...)";
340 match_key::operator<(match_key
const & other
) const
342 return ((name
< other
.name
)
344 || (name
== other
.name
345 && have_parameter
< other
.have_parameter
)
347 || (name
== other
.name
348 && have_parameter
== other
.have_parameter
349 && parameter_type
< other
.parameter_type
));
353 // NB: these are only used in the probe point name components, where
354 // only "*" is permitted.
356 // Within module("bar"), function("foo"), process("baz") strings, real
357 // wildcards are permitted too. See also util.h:contains_glob_chars
360 isglob(interned_string str
)
362 return(str
.find('*') != str
.npos
);
366 isdoubleglob(interned_string str
)
368 return(str
.find("**") != str
.npos
);
372 match_key::globmatch(match_key
const & other
) const
374 const string
& name_str
= name
;
375 const string
& other_str
= other
.name
;
377 return ((fnmatch(name_str
.c_str(), other_str
.c_str(), FNM_NOESCAPE
) == 0)
378 && have_parameter
== other
.have_parameter
379 && parameter_type
== other
.parameter_type
);
382 // ------------------------------------------------------------------------
383 // Members of match_node
384 // ------------------------------------------------------------------------
386 match_node::match_node() :
387 privilege(privilege_t (pr_stapdev
| pr_stapsys
))
392 match_node::bind(match_key
const & k
)
395 throw SEMANTIC_ERROR(_("invalid use of wildcard probe point component"));
397 map
<match_key
, match_node
*>::const_iterator i
= sub
.find(k
);
400 match_node
* n
= new match_node();
401 sub
.insert(make_pair(k
, n
));
406 match_node::bind(derived_probe_builder
* e
)
412 match_node::bind(interned_string k
)
414 return bind(match_key(k
));
418 match_node::bind_str(string
const & k
)
420 return bind(match_key(k
).with_string());
424 match_node::bind_num(string
const & k
)
426 return bind(match_key(k
).with_number());
430 match_node::bind_privilege(privilege_t p
)
437 match_node::find_and_build (systemtap_session
& s
,
438 probe
* p
, probe_point
*loc
, unsigned pos
,
439 vector
<derived_probe
*>& results
,
440 set
<string
>& builders
)
442 save_and_restore
<unsigned> costly(& s
.suppress_costly_diagnostics
,
443 s
.suppress_costly_diagnostics
+ (loc
->optional
|| loc
->sufficient
? 1 : 0));
445 assert (pos
<= loc
->components
.size());
446 if (pos
== loc
->components
.size()) // matched all probe point components so far
451 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
452 alternatives
+= string(" ") + i
->first
.str();
454 throw SEMANTIC_ERROR (_F("probe point truncated (follow: %s)",
455 alternatives
.c_str()),
456 loc
->components
.back()->tok
);
459 if (! pr_contains (privilege
, s
.privilege
))
461 throw SEMANTIC_ERROR (_F("probe point is not allowed for --privilege=%s",
462 pr_name (s
.privilege
)),
463 loc
->components
.back()->tok
);
466 literal_map_t param_map
;
467 for (unsigned i
=0; i
<pos
; i
++)
468 param_map
[loc
->components
[i
]->functor
] = loc
->components
[i
]->arg
;
471 unsigned int num_results
= results
.size();
473 // Iterate over all bound builders
474 for (unsigned k
=0; k
<ends
.size(); k
++)
476 derived_probe_builder
*b
= ends
[k
];
477 b
->build (s
, p
, loc
, param_map
, results
);
480 // Collect names of builders attempted for error reporting
481 if (results
.size() == num_results
)
483 for (unsigned k
=0; k
<ends
.size(); k
++)
484 builders
.insert(ends
[k
]->name());
487 else if (isdoubleglob(loc
->components
[pos
]->functor
)) // ** wildcard?
489 unsigned int num_results
= results
.size();
491 // When faced with "foo**bar", we try "foo*bar" and "foo*.**bar"
493 const probe_point::component
*comp
= loc
->components
[pos
];
494 string functor
= comp
->functor
;
495 size_t glob_start
= functor
.find("**");
496 size_t glob_end
= functor
.find_first_not_of('*', glob_start
);
497 string prefix
= functor
.substr(0, glob_start
);
498 string suffix
= ((glob_end
!= string::npos
) ?
499 functor
.substr(glob_end
) : "");
501 // Synthesize "foo*bar"
502 probe_point
*simple_pp
= new probe_point(*loc
);
503 probe_point::component
*simple_comp
= new probe_point::component(*comp
);
504 simple_comp
->functor
= prefix
+ "*" + suffix
;
505 simple_comp
->from_glob
= true;
506 simple_pp
->components
[pos
] = simple_comp
;
509 find_and_build (s
, p
, simple_pp
, pos
, results
, builders
);
511 catch (const semantic_error
& e
)
513 // Ignore semantic_errors.
516 // Cleanup if we didn't find anything
517 if (results
.size() == num_results
)
523 num_results
= results
.size();
525 // Synthesize "foo*.**bar"
526 // NB: any component arg should attach to the latter part only
527 probe_point
*expanded_pp
= new probe_point(*loc
);
528 probe_point::component
*expanded_comp_pre
= new probe_point::component(*comp
);
529 expanded_comp_pre
->functor
= prefix
+ "*";
530 expanded_comp_pre
->from_glob
= true;
531 expanded_comp_pre
->arg
= NULL
;
532 probe_point::component
*expanded_comp_post
= new probe_point::component(*comp
);
533 expanded_comp_post
->functor
= string("**") + suffix
;
534 expanded_pp
->components
[pos
] = expanded_comp_pre
;
535 expanded_pp
->components
.insert(expanded_pp
->components
.begin() + pos
+ 1,
539 find_and_build (s
, p
, expanded_pp
, pos
, results
, builders
);
541 catch (const semantic_error
& e
)
543 // Ignore semantic_errors.
546 // Cleanup if we didn't find anything
547 if (results
.size() == num_results
)
550 delete expanded_comp_pre
;
551 delete expanded_comp_post
;
554 // Try suffix expansion only if no matches found:
555 if (num_results
== results
.size())
556 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
558 if (! loc
->optional
&& num_results
== results
.size())
560 // We didn't find any wildcard matches (since the size of
561 // the result vector didn't change). Throw an error.
562 string sugs
= suggest_functors(s
, functor
);
563 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
564 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
568 else if (isglob(loc
->components
[pos
]->functor
)) // wildcard?
570 match_key
match (* loc
->components
[pos
]);
572 // Call find_and_build for each possible match. Ignore errors -
573 // unless we don't find any match.
574 unsigned int num_results
= results
.size();
575 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
577 const match_key
& subkey
= i
->first
;
578 match_node
* subnode
= i
->second
;
580 assert_no_interrupts();
582 if (match
.globmatch(subkey
))
585 clog
<< _F("wildcard '%s' matched '%s'",
586 loc
->components
[pos
]->functor
.to_string().c_str(),
587 subkey
.name
.to_string().c_str()) << endl
;
589 // When we have a wildcard, we need to create a copy of
590 // the probe point. Then we'll create a copy of the
591 // wildcard component, and substitute the non-wildcard
593 probe_point
*non_wildcard_pp
= new probe_point(*loc
);
594 probe_point::component
*non_wildcard_component
595 = new probe_point::component(*loc
->components
[pos
]);
596 non_wildcard_component
->functor
= subkey
.name
;
597 non_wildcard_component
->from_glob
= true;
598 non_wildcard_pp
->components
[pos
] = non_wildcard_component
;
600 // NB: probe conditions are not attached at the wildcard
601 // (component/functor) level, but at the overall
602 // probe_point level.
604 unsigned int inner_results
= results
.size();
606 // recurse (with the non-wildcard probe point)
609 subnode
->find_and_build (s
, p
, non_wildcard_pp
, pos
+1,
612 catch (const semantic_error
& e
)
614 // Ignore semantic_errors while expanding wildcards.
615 // If we get done and nothing was expanded, the code
616 // following the loop will complain.
619 if (results
.size() == inner_results
)
621 // If this wildcard didn't match, cleanup.
622 delete non_wildcard_pp
;
623 delete non_wildcard_component
;
628 // Try suffix expansion only if no matches found:
629 if (num_results
== results
.size())
630 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
632 if (! loc
->optional
&& num_results
== results
.size())
634 // We didn't find any wildcard matches (since the size of
635 // the result vector didn't change). Throw an error.
636 string sugs
= suggest_functors(s
, loc
->components
[pos
]->functor
);
637 throw SEMANTIC_ERROR (_F("probe point mismatch: didn't find any wildcard matches%s",
638 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
639 loc
->components
[pos
]->tok
);
644 match_key
match (* loc
->components
[pos
]);
645 sub_map_iterator_t i
= sub
.find (match
);
647 if (i
!= sub
.end()) // match found
649 match_node
* subnode
= i
->second
;
651 subnode
->find_and_build (s
, p
, loc
, pos
+1, results
, builders
);
655 unsigned int num_results
= results
.size();
656 this->try_suffix_expansion (s
, p
, loc
, pos
, results
);
658 // XXX: how to correctly report alternatives + position numbers
659 // for alias suffixes? file a separate PR to address the issue
660 if (! loc
->optional
&& num_results
== results
.size())
662 // We didn't find any alias suffixes (since the size of the
663 // result vector didn't change). Throw an error.
664 string sugs
= suggest_functors(s
, loc
->components
[pos
]->functor
);
665 throw SEMANTIC_ERROR (_F("probe point mismatch%s",
666 sugs
.empty() ? "" : (" (similar: " + sugs
+ ")").c_str()),
667 loc
->components
[pos
]->tok
);
673 match_node::suggest_functors(systemtap_session
& s
, string functor
)
675 // only use prefix if globby (and prefix is non-empty)
676 size_t glob
= functor
.find('*');
677 if (glob
!= string::npos
&& glob
!= 0)
682 // PR18577: There isn't any point in generating a suggestion list if
683 // we're not going to display it.
684 if ((s
.dump_mode
== systemtap_session::dump_matched_probes
685 || s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
689 set
<string
> functors
;
690 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
692 string ftor
= i
->first
.str();
693 if (ftor
.find('(') != string::npos
) // trim any parameter
694 ftor
.erase(ftor
.find('('));
695 functors
.insert(ftor
);
697 return levenshtein_suggest(functor
, functors
, 5); // print top 5
701 match_node::try_suffix_expansion (systemtap_session
& s
,
702 probe
*p
, probe_point
*loc
, unsigned pos
,
703 vector
<derived_probe
*>& results
)
705 // PR12210: match alias suffixes. If the components thus far
706 // have been matched, but there is an additional unknown
707 // suffix, we have a potential alias suffix on our hands. We
708 // need to expand the preceding components as probe aliases,
709 // reattach the suffix, and re-run derive_probes() on the
710 // resulting expansion. This is done by the routine
711 // build_with_suffix().
713 if (strverscmp(s
.compatible
.c_str(), "2.0") >= 0)
715 // XXX: technically, param_map isn't used here. So don't
716 // bother actually assembling it unless some
717 // derived_probe_builder appears that actually takes
718 // suffixes *and* consults parameters (currently no such
720 literal_map_t param_map
;
721 // for (unsigned i=0; i<pos; i++)
722 // param_map[loc->components[i]->functor] = loc->components[i]->arg;
725 vector
<probe_point::component
*> suffix (loc
->components
.begin()+pos
,
726 loc
->components
.end());
728 // Multiple derived_probe_builders may be bound at a
729 // match_node due to the possibility of multiply defined
731 for (unsigned k
=0; k
< ends
.size(); k
++)
733 derived_probe_builder
*b
= ends
[k
];
736 b
->build_with_suffix (s
, p
, loc
, param_map
, results
, suffix
);
738 catch (const recursive_expansion_error
&e
)
741 throw semantic_error(e
);
743 catch (const semantic_error
&e
)
745 // Adjust source coordinate and re-throw:
747 throw semantic_error(e
.errsrc
, e
.what(), loc
->components
[pos
]->tok
);
755 match_node::build_no_more (systemtap_session
& s
)
757 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
758 i
->second
->build_no_more (s
);
759 for (unsigned k
=0; k
<ends
.size(); k
++)
761 derived_probe_builder
*b
= ends
[k
];
762 b
->build_no_more (s
);
767 match_node::dump (systemtap_session
&s
, const string
&name
)
769 // Dump this node, if it is complete.
770 for (unsigned k
=0; k
<ends
.size(); k
++)
772 // Don't print aliases at all (for now) until we can figure out how to determine whether
773 // the probes they resolve to are ok in unprivileged mode.
774 if (ends
[k
]->is_alias ())
777 // In unprivileged mode, don't show the probes which are not allowed for unprivileged
779 if (pr_contains (privilege
, s
.privilege
))
781 cout
<< name
<< endl
;
782 break; // we need only print one instance.
786 // Recursively dump the children of this node
790 for (sub_map_iterator_t i
= sub
.begin(); i
!= sub
.end(); i
++)
792 i
->second
->dump (s
, name
+ dot
+ i
->first
.str());
797 // ------------------------------------------------------------------------
799 // ------------------------------------------------------------------------
801 struct alias_derived_probe
: public derived_probe
803 alias_derived_probe (probe
* base
, probe_point
*l
, const probe_alias
*a
,
804 const vector
<probe_point::component
*> *suffix
= 0);
805 ~alias_derived_probe();
807 void upchuck () { throw SEMANTIC_ERROR (_("inappropriate"), this->tok
); }
809 // Alias probes are immediately expanded to other derived_probe
810 // types, and are not themselves emitted or listed in
811 // systemtap_session.probes
813 void join_group (systemtap_session
&) { upchuck (); }
815 virtual const probe_alias
*get_alias () const { return alias
; }
816 virtual probe_point
*get_alias_loc () const { return alias_loc
; }
817 virtual probe_point
*sole_location () const;
820 const probe_alias
*alias
; // Used to check for recursion
821 probe_point
*alias_loc
; // Hack to recover full probe name
825 alias_derived_probe::alias_derived_probe(probe
*base
, probe_point
*l
,
826 const probe_alias
*a
,
827 const vector
<probe_point::component
*>
829 derived_probe (base
, l
), alias(a
)
831 // XXX pretty nasty -- this was cribbed from printscript() in main.cxx
832 assert (alias
->alias_names
.size() >= 1);
833 alias_loc
= new probe_point(*alias
->alias_names
[0]); // XXX: [0] is arbitrary; it would make just as much sense to collect all of the names
834 alias_loc
->well_formed
= true;
835 vector
<probe_point::component
*>::const_iterator it
;
836 for (it
= suffix
->begin(); it
!= suffix
->end(); ++it
)
838 alias_loc
->components
.push_back(*it
);
839 if (isglob((*it
)->functor
))
840 alias_loc
->well_formed
= false; // needs further derivation
844 alias_derived_probe::~alias_derived_probe ()
851 alias_derived_probe::sole_location () const
853 return const_cast<probe_point
*>(alias_loc
);
858 alias_expansion_builder::build(systemtap_session
& sess
,
860 probe_point
* location
,
861 literal_map_t
const & parameters
,
862 vector
<derived_probe
*> & finished_results
)
864 vector
<probe_point::component
*> empty_suffix
;
865 build_with_suffix (sess
, use
, location
, parameters
,
866 finished_results
, empty_suffix
);
870 alias_expansion_builder::build_with_suffix(systemtap_session
& sess
,
872 probe_point
* location
,
873 literal_map_t
const &,
874 vector
<derived_probe
*>
876 vector
<probe_point::component
*>
879 // Don't build the alias expansion if infinite recursion is detected.
880 if (checkForRecursiveExpansion (use
)) {
882 msg
<< _F("recursive loop in alias expansion of %s at %s",
883 lex_cast(*location
).c_str(), lex_cast(location
->components
.front()->tok
->location
).c_str());
884 // semantic_errors thrown here might be ignored, so we need a special class:
885 throw recursive_expansion_error (msg
.str());
886 // XXX The point of throwing this custom error is to suppress a
887 // cascade of "probe mismatch" messages that appear in addition to
888 // the error. The current approach suppresses most of the error
889 // cascade, but leaves one spurious error; in any case, the way
890 // this particular error is reported could be improved.
893 // We're going to build a new probe and wrap it up in an
894 // alias_expansion_probe so that the expansion loop recognizes it as
895 // such and re-expands its expansion.
897 alias_derived_probe
* n
= new alias_derived_probe (use
, location
/* soon overwritten */, this->alias
, &suffix
);
898 n
->body
= new block();
900 // The new probe gets a deep copy of the location list of the alias
901 // (with incoming condition joined) plus the suffix (if any),
902 n
->locations
.clear();
903 for (unsigned i
=0; i
<alias
->locations
.size(); i
++)
905 probe_point
*pp
= new probe_point(*alias
->locations
[i
]);
906 pp
->components
.insert(pp
->components
.end(), suffix
.begin(), suffix
.end());
907 pp
->condition
= add_condition (pp
->condition
, location
->condition
);
908 n
->locations
.push_back(pp
);
911 // the token location of the alias,
912 n
->tok
= location
->components
.front()->tok
;
914 // and statements representing the concatenation of the alias'
915 // body with the use's.
917 // NB: locals are *not* copied forward, from either alias or
918 // use. The expansion should have its locals re-inferred since
919 // there's concatenated code here and we only want one vardecl per
920 // resulting variable.
922 if (alias
->epilogue_style
)
923 n
->body
= new block (use
->body
, alias
->body
);
925 n
->body
= new block (alias
->body
, use
->body
);
927 unsigned old_num_results
= finished_results
.size();
928 // If expanding for an alias suffix, be sure to pass on any errors
929 // to the caller instead of printing them in derive_probes():
930 derive_probes (sess
, n
, finished_results
, location
->optional
, !suffix
.empty());
932 // Check whether we resolved something. If so, put the
933 // whole library into the queue if not already there.
934 if (finished_results
.size() > old_num_results
)
936 stapfile
*f
= alias
->tok
->location
.file
;
937 if (find (sess
.files
.begin(), sess
.files
.end(), f
)
939 sess
.files
.push_back (f
);
944 alias_expansion_builder::checkForRecursiveExpansion (probe
*use
)
946 // Collect the derivation chain of this probe.
947 vector
<probe
*>derivations
;
948 use
->collect_derivation_chain (derivations
);
950 // Check all probe points in the alias expansion against the currently-being-expanded probe point
951 // of each of the probes in the derivation chain, looking for a match. This
952 // indicates infinite recursion.
953 // The first element of the derivation chain will be the derived_probe representing 'use', so
954 // start the search with the second element.
955 assert (derivations
.size() > 0);
956 assert (derivations
[0] == use
);
957 for (unsigned d
= 1; d
< derivations
.size(); ++d
) {
958 if (use
->get_alias() == derivations
[d
]->get_alias())
959 return true; // recursion detected
965 // ------------------------------------------------------------------------
967 // ------------------------------------------------------------------------
969 // The match-and-expand loop.
971 derive_probes (systemtap_session
& s
,
972 probe
*p
, vector
<derived_probe
*>& dps
,
976 // We need a static to track whether the current probe is optional so that
977 // even if we recurse into derive_probes with optional = false, errors will
978 // still be ignored. The undo_parent_optional bool ensures we reset the
979 // static at the same level we had it set.
980 static bool parent_optional
= false;
981 bool undo_parent_optional
= false;
983 if (optional
&& !parent_optional
)
985 parent_optional
= true;
986 undo_parent_optional
= true;
989 vector
<semantic_error
> optional_errs
;
991 for (unsigned i
= 0; i
< p
->locations
.size(); ++i
)
993 set
<string
> builders
;
994 assert_no_interrupts();
996 probe_point
*loc
= p
->locations
[i
];
999 clog
<< "derive-probes (location #" << i
<< "): " << *loc
<< " of " << *p
->tok
<< endl
;
1003 unsigned num_atbegin
= dps
.size();
1007 s
.pattern_root
->find_and_build (s
, p
, loc
, 0, dps
, builders
); // <-- actual derivation!
1009 catch (const semantic_error
& e
)
1011 if (!loc
->optional
&& !parent_optional
)
1012 throw semantic_error(e
);
1013 else /* tolerate failure for optional probe */
1015 // remember err, we will print it (in catch block) if any
1016 // non-optional loc fails to resolve
1017 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1018 loc
->components
[0]->tok
, NULL
, &e
);
1019 optional_errs
.push_back(err
);
1024 unsigned num_atend
= dps
.size();
1026 if (! (loc
->optional
||parent_optional
) && // something required, but
1027 num_atbegin
== num_atend
) // nothing new derived!
1028 throw SEMANTIC_ERROR (_("no match"));
1030 if (loc
->sufficient
&& (num_atend
> num_atbegin
))
1034 clog
<< "Probe point ";
1035 p
->locations
[i
]->print(clog
);
1036 clog
<< " sufficient, skipped";
1037 for (unsigned j
= i
+1; j
< p
->locations
.size(); ++j
)
1040 p
->locations
[j
]->print(clog
);
1044 break; // we need not try to derive for any other locations
1047 catch (const semantic_error
& e
)
1049 // The rethrow_errors parameter lets the caller decide an
1050 // alternative to printing the error. This is necessary when
1051 // calling derive_probes() recursively during expansion of
1052 // an alias with suffix -- any message printed here would
1053 // point to the alias declaration and not the invalid suffix
1054 // usage, so the caller needs to catch the error themselves
1055 // and print a more appropriate message.
1058 throw semantic_error(e
);
1060 // Only output in dump mode if -vv is supplied:
1061 else if (!s
.dump_mode
|| (s
.verbose
> 1))
1063 // print this one manually first because it's more important than
1064 // the optional errs
1065 semantic_error
err(ERR_SRC
, _("while resolving probe point"),
1066 loc
->components
[0]->tok
, NULL
, &e
);
1067 // provide some details about which builders were tried
1068 if (s
.verbose
> 0 && !builders
.empty())
1071 for (auto it
= builders
.begin(); it
!= builders
.end(); ++it
)
1073 if (it
!= builders
.begin())
1077 semantic_error
err2(ERR_SRC
, _F("resolution failed in %s", msg
.c_str()));
1078 err2
.set_chain(err
);
1079 s
.print_error(err2
);
1086 // print optional errs accumulated while visiting other probe points
1087 for (vector
<semantic_error
>::const_iterator it
= optional_errs
.begin();
1088 it
!= optional_errs
.end(); ++it
)
1096 if (undo_parent_optional
)
1098 parent_optional
= false;
1104 // ------------------------------------------------------------------------
1106 // Indexable usage checks
1109 struct symbol_fetcher
1110 : public throwing_visitor
1114 symbol_fetcher (symbol
*&sym
): sym(sym
)
1117 void visit_symbol (symbol
* e
)
1122 void visit_arrayindex (arrayindex
* e
)
1124 e
->base
->visit (this);
1127 void throwone (const token
* t
)
1129 throw SEMANTIC_ERROR (_("Expecting symbol or array index expression"), t
);
1134 get_symbol_within_expression (expression
*e
)
1137 symbol_fetcher
fetcher(sym
);
1138 e
->visit (&fetcher
);
1139 return sym
; // NB: may be null!
1143 get_symbol_within_indexable (indexable
*ix
)
1145 symbol
*array
= NULL
;
1146 hist_op
*hist
= NULL
;
1147 classify_indexable(ix
, array
, hist
);
1151 return get_symbol_within_expression (hist
->stat
);
1154 struct mutated_var_collector
1155 : public traversing_visitor
1157 set
<vardecl
*> * mutated_vars
;
1159 mutated_var_collector (set
<vardecl
*> * mm
)
1163 void visit_assignment(assignment
* e
)
1165 if (e
->type
== pe_stats
&& e
->op
== "<<<")
1167 vardecl
*vd
= get_symbol_within_expression (e
->left
)->referent
;
1169 mutated_vars
->insert (vd
);
1171 traversing_visitor::visit_assignment(e
);
1174 void visit_arrayindex (arrayindex
*e
)
1176 if (is_active_lvalue (e
))
1179 if (e
->base
->is_symbol (sym
))
1180 mutated_vars
->insert (sym
->referent
);
1182 throw SEMANTIC_ERROR(_("Assignment to read-only histogram bucket"), e
->tok
);
1184 traversing_visitor::visit_arrayindex (e
);
1189 struct no_var_mutation_during_iteration_check
1190 : public traversing_visitor
1192 systemtap_session
& session
;
1193 map
<functiondecl
*,set
<vardecl
*> *> & function_mutates_vars
;
1194 vector
<vardecl
*> vars_being_iterated
;
1196 no_var_mutation_during_iteration_check
1197 (systemtap_session
& sess
,
1198 map
<functiondecl
*,set
<vardecl
*> *> & fmv
)
1199 : session(sess
), function_mutates_vars (fmv
)
1202 void visit_arrayindex (arrayindex
*e
)
1204 if (is_active_lvalue(e
))
1206 vardecl
*vd
= get_symbol_within_indexable (e
->base
)->referent
;
1209 for (unsigned i
= 0; i
< vars_being_iterated
.size(); ++i
)
1211 vardecl
*v
= vars_being_iterated
[i
];
1214 string err
= _F("variable '%s' modified during 'foreach' iteration",
1215 v
->unmangled_name
.to_string().c_str());
1216 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1221 traversing_visitor::visit_arrayindex (e
);
1224 void visit_functioncall (functioncall
* e
)
1226 for (unsigned fd
= 0; fd
< e
->referents
.size(); fd
++)
1228 map
<functiondecl
*,set
<vardecl
*> *>::const_iterator i
1229 = function_mutates_vars
.find (e
->referents
[fd
]);
1231 if (i
!= function_mutates_vars
.end())
1233 for (unsigned j
= 0; j
< vars_being_iterated
.size(); ++j
)
1235 vardecl
*m
= vars_being_iterated
[j
];
1236 if (i
->second
->find (m
) != i
->second
->end())
1238 string err
= _F("function call modifies var '%s' during 'foreach' iteration",
1239 m
->unmangled_name
.to_string().c_str());
1240 session
.print_error (SEMANTIC_ERROR (err
, e
->tok
));
1246 traversing_visitor::visit_functioncall (e
);
1249 void visit_foreach_loop(foreach_loop
* s
)
1251 vardecl
*vd
= get_symbol_within_indexable (s
->base
)->referent
;
1254 vars_being_iterated
.push_back (vd
);
1256 traversing_visitor::visit_foreach_loop (s
);
1259 vars_being_iterated
.pop_back();
1264 // ------------------------------------------------------------------------
1266 struct stat_decl_collector
1267 : public traversing_visitor
1269 systemtap_session
& session
;
1271 stat_decl_collector(systemtap_session
& sess
)
1275 void visit_stat_op (stat_op
* e
)
1277 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1278 statistic_decl new_stat
= statistic_decl();
1279 int bit_shift
= (e
->params
.size() == 0) ? 0 : e
->params
[0];
1280 int stat_op
= STAT_OP_NONE
;
1282 if ((bit_shift
< 0) || (bit_shift
> 62))
1283 throw SEMANTIC_ERROR (_F("bit shift (%d) out of range <0..62>",
1287 // The following helps to track which statistical operators are being
1288 // used with given global/local variable. This information later helps
1289 // to optimize the runtime behaviour.
1291 if (e
->ctype
== sc_count
)
1292 stat_op
= STAT_OP_COUNT
;
1293 else if (e
->ctype
== sc_sum
)
1294 stat_op
= STAT_OP_SUM
;
1295 else if (e
->ctype
== sc_min
)
1296 stat_op
= STAT_OP_MIN
;
1297 else if (e
->ctype
== sc_max
)
1298 stat_op
= STAT_OP_MAX
;
1299 else if (e
->ctype
== sc_average
)
1300 stat_op
= STAT_OP_AVG
;
1301 else if (e
->ctype
== sc_variance
)
1302 stat_op
= STAT_OP_VARIANCE
;
1304 new_stat
.bit_shift
= bit_shift
;
1305 new_stat
.stat_ops
|= stat_op
;
1307 map
<interned_string
, statistic_decl
>::iterator i
= session
.stat_decls
.find(sym
->name
);
1308 if (i
== session
.stat_decls
.end())
1309 session
.stat_decls
[sym
->name
] = new_stat
;
1312 i
->second
.stat_ops
|= stat_op
;
1314 // The @variance operator for given stat S (i.e. call to
1315 // _stp_stat_init()) is optionally parametrizeable
1316 // (@variance(S[, N]), where N is a bit shift (the default is
1317 // N=0). The bit_shift helps to improve precision if integer
1318 // arithemtic, namely divisions ().
1320 // Ref: https://en.wikipedia.org/wiki/Scale_factor_%28computer_science%29
1322 if (e
->tok
->content
!= "@variance")
1324 else if ((i
->second
.bit_shift
!= 0)
1325 && (i
->second
.bit_shift
!= bit_shift
))
1327 // FIXME: Support multiple co-declared bit shifts
1328 // (analogy to multiple co-declared histogram types)
1329 throw SEMANTIC_ERROR (_F("conflicting bit shifts declared (previously %d)",
1330 i
->second
.bit_shift
),
1335 i
->second
.bit_shift
= bit_shift
;
1340 void visit_foreach_loop (foreach_loop
* s
)
1345 classify_indexable (s
->base
, array
, hist
);
1347 if (array
&& array
->type
== pe_stats
1348 && s
->sort_direction
1349 && s
->sort_column
== 0)
1351 int stat_op
= STAT_OP_NONE
;
1353 switch (s
->sort_aggr
) {
1354 default: case sc_none
: case sc_count
: stat_op
= STAT_OP_COUNT
; break;
1355 case sc_sum
: stat_op
= STAT_OP_SUM
; break;
1356 case sc_min
: stat_op
= STAT_OP_MIN
; break;
1357 case sc_max
: stat_op
= STAT_OP_MAX
; break;
1358 case sc_average
: stat_op
= STAT_OP_AVG
; break;
1361 map
<interned_string
, statistic_decl
>::iterator i
1362 = session
.stat_decls
.find(array
->name
);
1364 if (i
== session
.stat_decls
.end())
1365 session
.stat_decls
[array
->name
] = statistic_decl(stat_op
);
1367 i
->second
.stat_ops
|= stat_op
;
1370 traversing_visitor::visit_foreach_loop (s
);
1373 void visit_assignment (assignment
* e
)
1377 symbol
*sym
= get_symbol_within_expression (e
->left
);
1378 if (session
.stat_decls
.find(sym
->name
) == session
.stat_decls
.end())
1379 session
.stat_decls
[sym
->name
] = statistic_decl();
1382 traversing_visitor::visit_assignment(e
);
1385 void visit_hist_op (hist_op
* e
)
1387 symbol
*sym
= get_symbol_within_expression (e
->stat
);
1388 statistic_decl new_stat
;
1390 if (e
->htype
== hist_linear
)
1392 new_stat
.type
= statistic_decl::linear
;
1393 assert (e
->params
.size() == 3);
1394 new_stat
.linear_low
= e
->params
[0];
1395 new_stat
.linear_high
= e
->params
[1];
1396 new_stat
.linear_step
= e
->params
[2];
1400 assert (e
->htype
== hist_log
);
1401 new_stat
.type
= statistic_decl::logarithmic
;
1402 assert (e
->params
.size() == 0);
1405 map
<interned_string
, statistic_decl
>::iterator i
= session
.stat_decls
.find(sym
->name
);
1406 if (i
== session
.stat_decls
.end())
1407 session
.stat_decls
[sym
->name
] = new_stat
;
1410 statistic_decl
& old_stat
= i
->second
;
1411 if (!(old_stat
== new_stat
))
1413 if (old_stat
.type
== statistic_decl::none
)
1415 i
->second
.type
= new_stat
.type
;
1416 i
->second
.linear_low
= new_stat
.linear_low
;
1417 i
->second
.linear_high
= new_stat
.linear_high
;
1418 i
->second
.linear_step
= new_stat
.linear_step
;
1422 // FIXME: Support multiple co-declared histogram types
1423 semantic_error
se(ERR_SRC
, _F("multiple histogram types declared on '%s'",
1424 sym
->name
.to_string().c_str()), e
->tok
);
1425 session
.print_error (se
);
1434 semantic_pass_stats (systemtap_session
& sess
)
1436 stat_decl_collector
sdc(sess
);
1438 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1439 it
->second
->body
->visit (&sdc
);
1441 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1442 sess
.probes
[i
]->body
->visit (&sdc
);
1444 for (unsigned i
= 0; i
< sess
.globals
.size(); ++i
)
1446 vardecl
*v
= sess
.globals
[i
];
1447 if (v
->type
== pe_stats
)
1450 if (sess
.stat_decls
.find(v
->name
) == sess
.stat_decls
.end())
1452 semantic_error
se(ERR_SRC
, _F("unable to infer statistic parameters for global '%s'",
1453 v
->unmangled_name
.to_string().c_str()));
1454 sess
.print_error (se
);
1459 return sess
.num_errors();
1462 // ------------------------------------------------------------------------
1464 // Enforce variable-related invariants: no modification of
1465 // a foreach()-iterated array.
1467 semantic_pass_vars (systemtap_session
& sess
)
1470 map
<functiondecl
*, set
<vardecl
*> *> fmv
;
1471 no_var_mutation_during_iteration_check
chk(sess
, fmv
);
1473 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1475 functiondecl
* fn
= it
->second
;
1478 set
<vardecl
*> * m
= new set
<vardecl
*>();
1479 mutated_var_collector
mc (m
);
1480 fn
->body
->visit (&mc
);
1485 for (map
<string
,functiondecl
*>::iterator it
= sess
.functions
.begin(); it
!= sess
.functions
.end(); it
++)
1487 functiondecl
* fn
= it
->second
;
1488 if (fn
->body
) fn
->body
->visit (&chk
);
1491 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1493 if (sess
.probes
[i
]->body
)
1494 sess
.probes
[i
]->body
->visit (&chk
);
1497 return sess
.num_errors();
1501 // ------------------------------------------------------------------------
1503 // Rewrite probe condition expressions into probe bodies. Tricky and
1504 // exciting business, this. This:
1506 // probe foo if (g1 || g2) { ... }
1507 // probe bar { ... g1 ++ ... }
1511 // probe foo { if (! (g1 || g2)) next; ... }
1512 // probe bar { ... g1 ++ ...;
1513 // if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
1516 // In other words, we perform two transformations:
1517 // (1) Inline probe condition into its body.
1518 // (2) For each probe that modifies a global var in use in any probe's
1519 // condition, re-evaluate those probes' condition at the end of that
1522 // Here, we do all of (1), and half of (2): we simply collect the dependency
1523 // info between probes, which the translator will use to emit the affected
1524 // probes' condition re-evaluation. The translator will also ensure that the
1525 // conditions are evaluated using the globals' starting values prior to any
1528 // Adds the condition expression to the front of the probe's body
1530 derived_probe_condition_inline (derived_probe
*p
)
1532 expression
* e
= p
->sole_location()->condition
;
1535 if_statement
*ifs
= new if_statement ();
1537 ifs
->thenblock
= new next_statement ();
1538 ifs
->thenblock
->tok
= e
->tok
;
1539 ifs
->elseblock
= NULL
;
1540 unary_expression
*notex
= new unary_expression ();
1542 notex
->tok
= e
->tok
;
1544 ifs
->condition
= notex
;
1545 p
->body
= new block (ifs
, p
->body
);
1549 semantic_pass_conditions (systemtap_session
& sess
)
1551 map
<derived_probe
*, set
<vardecl
*> > vars_read_in_cond
;
1552 map
<derived_probe
*, set
<vardecl
*> > vars_written_in_body
;
1554 // do a first pass through the probes to ensure safety, inline any condition,
1555 // and collect var usage
1556 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1558 if (pending_interrupts
) return 1;
1560 derived_probe
* p
= sess
.probes
[i
];
1561 expression
* e
= p
->sole_location()->condition
;
1565 varuse_collecting_visitor
vcv_cond(sess
);
1566 e
->visit (& vcv_cond
);
1568 if (!vcv_cond
.written
.empty())
1569 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1570 "modify any variables"),
1572 else if (vcv_cond
.embedded_seen
)
1573 sess
.print_error (SEMANTIC_ERROR (_("probe condition must not "
1574 "include impure embedded-C"),
1577 derived_probe_condition_inline(p
);
1579 vars_read_in_cond
[p
].insert(vcv_cond
.read
.begin(),
1580 vcv_cond
.read
.end());
1583 varuse_collecting_visitor
vcv_body(sess
);
1584 p
->body
->visit (& vcv_body
);
1586 vars_written_in_body
[p
].insert(vcv_body
.written
.begin(),
1587 vcv_body
.written
.end());
1590 // do a second pass to collect affected probes
1591 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1593 if (pending_interrupts
) return 1;
1595 derived_probe
*p
= sess
.probes
[i
];
1597 // for each variable this probe modifies...
1598 set
<vardecl
*>::const_iterator var
;
1599 for (var
= vars_written_in_body
[p
].begin();
1600 var
!= vars_written_in_body
[p
].end(); ++var
)
1602 // collect probes which could be affected
1603 for (unsigned j
= 0; j
< sess
.probes
.size(); ++j
)
1605 if (vars_read_in_cond
[sess
.probes
[j
]].count(*var
))
1607 if (!p
->probes_with_affected_conditions
.count(sess
.probes
[j
]))
1609 p
->probes_with_affected_conditions
.insert(sess
.probes
[j
]);
1610 if (sess
.verbose
> 2)
1611 clog
<< "probe " << i
<< " can affect condition of "
1612 "probe " << j
<< endl
;
1619 // PR18115: We create a begin probe which is artificially registered as
1620 // affecting every other probe. This will serve as the initializer so that
1621 // other probe types with false conditions can be skipped (or registered as
1622 // disabled) during module initialization.
1624 set
<derived_probe
*> targets
;
1625 for (unsigned i
= 0; i
< sess
.probes
.size(); ++i
)
1626 if (!vars_read_in_cond
[sess
.probes
[i
]].empty())
1627 targets
.insert(sess
.probes
[i
]);
1629 if (!targets
.empty())
1631 stringstream
ss("probe begin {}");
1633 // no good token to choose here... let's just use the condition expression
1634 // of one of the probes as the token
1635 const token
*tok
= (*targets
.begin())->sole_location()->condition
->tok
;
1637 probe
*p
= parse_synthetic_probe(sess
, ss
, tok
);
1639 throw SEMANTIC_ERROR (_("can't create cond initializer probe"), tok
);
1641 vector
<derived_probe
*> dps
;
1642 derive_probes(sess
, p
, dps
);
1644 // there should only be one
1645 assert(dps
.size() == 1);
1647 derived_probe
* dp
= dps
[0];
1648 dp
->probes_with_affected_conditions
.insert(targets
.begin(),
1650 sess
.probes
.push_back (dp
);
1651 dp
->join_group (sess
);
1653 // no need to manually do symresolution since body is empty
1656 return sess
.num_errors();
1659 // ------------------------------------------------------------------------
1662 // Simple visitor that just goes through all embedded code blocks that
1663 // are available at the end all the optimizations to register any
1664 // relevant pragmas or other indicators found, so that session flags can
1665 // be set that can be inspected at translation time to trigger any
1666 // necessary initialization of code needed by the embedded code functions.
1668 // This is only for pragmas that don't have any other side-effect than
1669 // needing some initialization at module init time. Currently handles
1670 // /* pragma:vma */ /* pragma:unwind */ /* pragma:symbols */ /* pragma:lines */
1672 // /* pragma:uprobes */ is handled during the typeresolution_info pass.
1673 // /* pure */, /* unprivileged */. /* myproc-unprivileged */ and /* guru */
1674 // are handled by the varuse_collecting_visitor.
1676 struct embeddedcode_info
: public functioncall_traversing_visitor
1679 systemtap_session
& session
;
1680 void examine (const interned_string
&, const token
*tok
);
1683 embeddedcode_info (systemtap_session
& s
): session(s
) { }
1685 void visit_embeddedcode (embeddedcode
* c
) { examine (c
->code
, c
->tok
); }
1686 void visit_embedded_expr (embedded_expr
* e
) { examine (e
->code
, e
->tok
); }
1690 embeddedcode_info::examine (const interned_string
&code
, const token
*tok
)
1692 if (! vma_tracker_enabled(session
)
1693 && code
.find("/* pragma:vma */") != string::npos
)
1695 if (session
.verbose
> 2)
1696 clog
<< _F("Turning on task_finder vma_tracker, pragma:vma found in %s",
1697 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1699 // PR15052: stapdyn doesn't have VMA-tracking yet.
1700 if (session
.runtime_usermode_p())
1701 throw SEMANTIC_ERROR(_("VMA-tracking is only supported by the kernel runtime (PR15052)"), tok
);
1703 enable_vma_tracker(session
);
1706 if (! session
.need_unwind
1707 && code
.find("/* pragma:unwind */") != string::npos
)
1709 if (session
.verbose
> 2)
1710 clog
<< _F("Turning on unwind support, pragma:unwind found in %s",
1711 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1712 session
.need_unwind
= true;
1715 if (! session
.need_symbols
1716 && code
.find("/* pragma:symbols */") != string::npos
)
1718 if (session
.verbose
> 2)
1719 clog
<< _F("Turning on symbol data collecting, pragma:symbols found in %s",
1720 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1721 session
.need_symbols
= true;
1724 if (! session
.need_lines
1725 && code
.find("/* pragma:lines */") != string::npos
)
1727 if (session
.verbose
> 2)
1728 clog
<< _F("Turning on debug line data collecting, pragma:lines found in %s",
1729 current_function
->unmangled_name
.to_string().c_str()) << endl
;
1730 session
.need_lines
= true;
1734 void embeddedcode_info_pass (systemtap_session
& s
)
1736 embeddedcode_info
eci (s
);
1737 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1738 s
.probes
[i
]->body
->visit (& eci
);
1740 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
1741 it
!= s
.functions
.end(); it
++)
1742 it
->second
->body
->visit (& eci
);
1745 // ------------------------------------------------------------------------
1748 // Simple visitor that collects all the regular expressions in the
1749 // file and adds them to the session DFA table.
1751 struct regex_collecting_visitor
: public functioncall_traversing_visitor
1754 systemtap_session
& session
;
1757 regex_collecting_visitor (systemtap_session
& s
): session(s
) { }
1759 void visit_regex_query (regex_query
*q
) {
1760 functioncall_traversing_visitor::visit_regex_query (q
);
1762 string re
= q
->right
->value
;
1763 regex_to_stapdfa (&session
, re
, q
->right
->tok
);
1767 // Go through the regex match invocations and generate corresponding DFAs.
1768 int gen_dfa_table (systemtap_session
& s
)
1770 regex_collecting_visitor
rcv(s
);
1772 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1776 s
.probes
[i
]->body
->visit (& rcv
);
1778 if (s
.probes
[i
]->sole_location()->condition
)
1779 s
.probes
[i
]->sole_location()->condition
->visit (& rcv
);
1781 catch (const semantic_error
& e
)
1787 return s
.num_errors();
1790 // ------------------------------------------------------------------------
1793 static int semantic_pass_symbols (systemtap_session
&);
1794 static int semantic_pass_optimize1 (systemtap_session
&);
1795 static int semantic_pass_optimize2 (systemtap_session
&);
1796 static int semantic_pass_types (systemtap_session
&);
1797 static int semantic_pass_vars (systemtap_session
&);
1798 static int semantic_pass_stats (systemtap_session
&);
1799 static int semantic_pass_conditions (systemtap_session
&);
1802 struct expression_build_no_more_visitor
: public expression_visitor
1804 // Clear extra details from every expression, like DWARF type info, so that
1805 // builders can safely release them in build_no_more. From here on out,
1806 // we're back to basic types only.
1807 void visit_expression(expression
*e
)
1809 e
->type_details
.reset();
1814 build_no_more (systemtap_session
& s
)
1816 expression_build_no_more_visitor v
;
1818 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
1819 s
.probes
[i
]->body
->visit(&v
);
1821 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
1822 it
!= s
.functions
.end(); it
++)
1823 it
->second
->body
->visit(&v
);
1825 // Inform all derived_probe builders that we're done with
1826 // all resolution, so it's time to release caches.
1827 s
.pattern_root
->build_no_more (s
);
1832 // Link up symbols to their declarations. Set the session's
1833 // files/probes/functions/globals vectors from the transitively
1834 // reached set of stapfiles in s.library_files, starting from
1835 // s.user_file. Perform automatic tapset inclusion and probe
1838 semantic_pass_symbols (systemtap_session
& s
)
1840 symresolution_info
sym (s
);
1842 // If we're listing functions, then we need to include all the files. Probe
1843 // aliases won't be visited/derived so all we gain are the functions, global
1844 // variables, and any real probes (e.g. begin probes). NB: type resolution for
1845 // a specific function arg may fail if it could only be determined from a
1846 // function call in one of the skipped aliases.
1847 if (s
.dump_mode
== systemtap_session::dump_functions
)
1849 s
.files
.insert(s
.files
.end(), s
.library_files
.begin(),
1850 s
.library_files
.end());
1852 else if (!s
.user_files
.empty())
1854 // Normal run: seed s.files with user_files and let it grow through the
1855 // find_* functions. NB: s.files can grow during this iteration, so
1856 // size() can return gradually increasing numbers.
1857 s
.files
.insert (s
.files
.end(), s
.user_files
.begin(), s
.user_files
.end());
1860 for (unsigned i
= 0; i
< s
.files
.size(); i
++)
1862 assert_no_interrupts();
1863 stapfile
* dome
= s
.files
[i
];
1865 // Pass 1: add globals and functions to systemtap-session master list,
1866 // so the find_* functions find them
1868 // NB: tapset global/function definitions may duplicate or conflict
1869 // with those already in s.globals/functions. We need to deconflict
1872 for (unsigned i
=0; i
<dome
->globals
.size(); i
++)
1874 vardecl
* g
= dome
->globals
[i
];
1875 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
1877 vardecl
* g2
= s
.globals
[j
];
1878 if (g
->name
== g2
->name
)
1880 s
.print_error (SEMANTIC_ERROR (_("conflicting global variables"),
1884 s
.globals
.push_back (g
);
1887 for (unsigned i
=0; i
<dome
->functions
.size(); i
++)
1889 functiondecl
* f
= dome
->functions
[i
];
1890 functiondecl
* f2
= s
.functions
[f
->name
];
1893 s
.print_error (SEMANTIC_ERROR (_("conflicting functions"),
1896 s
.functions
[f
->name
] = f
;
1899 // NB: embeds don't conflict with each other
1900 for (unsigned i
=0; i
<dome
->embeds
.size(); i
++)
1901 s
.embeds
.push_back (dome
->embeds
[i
]);
1903 // Pass 2: derive probes and resolve any further symbols in the
1906 for (unsigned i
=0; i
<dome
->probes
.size(); i
++)
1908 assert_no_interrupts();
1909 probe
* p
= dome
->probes
[i
];
1910 vector
<derived_probe
*> dps
;
1912 // much magic happens here: probe alias expansion, wildcard
1913 // matching, low-level derived_probe construction.
1914 derive_probes (s
, p
, dps
);
1916 for (unsigned j
=0; j
<dps
.size(); j
++)
1918 assert_no_interrupts();
1919 derived_probe
* dp
= dps
[j
];
1920 s
.probes
.push_back (dp
);
1925 clog
<< _("symbol resolution for derived-probe ");
1932 update_visitor_loop (s
, s
.code_filters
, dp
->body
);
1934 sym
.current_function
= 0;
1935 sym
.current_probe
= dp
;
1936 dp
->body
->visit (& sym
);
1938 // Process the probe-point condition expression.
1939 sym
.current_function
= 0;
1940 sym
.current_probe
= 0;
1941 if (dp
->sole_location()->condition
)
1942 dp
->sole_location()->condition
->visit (& sym
);
1944 catch (const semantic_error
& e
)
1951 // Pass 3: process functions - incl. the synthetic ones,
1952 // so s.functions[] rather than dome->functions[]
1954 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
1956 assert_no_interrupts();
1957 functiondecl
* fd
= it
->second
;
1959 clog
<< _("symbol resolution for function ") << fd
->name
<< endl
;
1963 update_visitor_loop (s
, s
.code_filters
, fd
->body
);
1965 sym
.current_function
= fd
;
1966 sym
.current_probe
= 0;
1967 fd
->body
->visit (& sym
);
1969 catch (const semantic_error
& e
)
1976 if(s
.systemtap_v_check
){
1977 for(unsigned i
=0;i
<s
.globals
.size();i
++){
1978 if(s
.globals
[i
]->systemtap_v_conditional
)
1979 s
.print_warning(_("This global uses tapset constructs that are dependent on systemtap version"), s
.globals
[i
]->tok
);
1982 for(map
<string
, functiondecl
*>::const_iterator i
=s
.functions
.begin();i
!= s
.functions
.end();++i
){
1983 if(i
->second
->systemtap_v_conditional
)
1984 s
.print_warning(_("This function uses tapset constructs that are dependent on systemtap version"), i
->second
->tok
);
1987 for(unsigned i
=0;i
<s
.probes
.size();i
++){
1988 vector
<probe
*> sysvc
;
1989 s
.probes
[i
]->collect_derivation_chain(sysvc
);
1990 for(unsigned j
=0;j
<sysvc
.size();j
++){
1991 if(sysvc
[j
]->systemtap_v_conditional
)
1992 s
.print_warning(_("This probe uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->tok
);
1993 if(sysvc
[j
]->get_alias() && sysvc
[j
]->get_alias()->systemtap_v_conditional
)
1994 s
.print_warning(_("This alias uses tapset constructs that are dependent on systemtap version"), sysvc
[j
]->get_alias()->tok
);
1999 return s
.num_errors(); // all those print_error calls
2003 // Keep unread global variables for probe end value display.
2004 void add_global_var_display (systemtap_session
& s
)
2006 // Don't generate synthetic end probes when in listing mode; it would clutter
2007 // up the list of probe points with "end ...". In fact, don't bother in any
2008 // dump mode at all, since it'll never be used.
2009 if (s
.dump_mode
) return;
2011 // The bpf runtime currently lacks support for foreach statements which
2012 // this function might generate.
2013 if (s
.runtime_mode
== systemtap_session::bpf_runtime
) return;
2015 // User has specified not to display unread global variables.
2016 if (s
.no_global_var_display
) return;
2018 varuse_collecting_visitor
vut(s
);
2020 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
2022 s
.probes
[i
]->body
->visit (& vut
);
2024 if (s
.probes
[i
]->sole_location()->condition
)
2025 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
2028 for (unsigned g
=0; g
< s
.globals
.size(); g
++)
2030 vardecl
* l
= s
.globals
[g
];
2031 if ((vut
.read
.find (l
) != vut
.read
.end()
2032 && vut
.used
.find (l
) != vut
.used
.end())
2033 || vut
.written
.find (l
) == vut
.written
.end())
2036 // Don't generate synthetic end probes for unread globals
2037 // declared only within tapsets. (RHBZ 468139), but rather
2038 // only within the end-user script.
2040 bool tapset_global
= false;
2041 for (size_t m
=0; m
< s
.library_files
.size(); m
++)
2043 for (size_t n
=0; n
< s
.library_files
[m
]->globals
.size(); n
++)
2045 if (l
->name
== s
.library_files
[m
]->globals
[n
]->name
)
2046 {tapset_global
= true; break;}
2053 code
<< "probe end {" << endl
;
2055 string format
= l
->unmangled_name
;
2058 string foreach_value
;
2059 if (!l
->index_types
.empty())
2061 // Add index values to the printf format, and prepare
2062 // a simple list of indexes for passing around elsewhere
2064 for (size_t i
= 0; i
< l
->index_types
.size(); ++i
)
2071 indexes
+= "__idx" + lex_cast(i
);
2072 if (l
->index_types
[i
] == pe_string
)
2073 format
+= "\\\"%#s\\\"";
2079 // Iterate over all indexes in the array, sorted by decreasing value
2080 code
<< "foreach (";
2081 if (l
->type
!= pe_stats
)
2083 foreach_value
= "__val";
2084 code
<< foreach_value
<< " = ";
2086 code
<< "[" << indexes
<< "] in " << l
->unmangled_name
<< "-)" << endl
;
2088 else if (l
->type
== pe_stats
)
2090 // PR7053: Check scalar globals for empty aggregate
2091 code
<< "if (@count(" << l
->unmangled_name
<< ") == 0)" << endl
;
2092 code
<< "printf(\"" << l
->unmangled_name
<< " @count=0x0\\n\")" << endl
;
2093 code
<< "else" << endl
;
2096 static const string stats
[] = { "@count", "@min", "@max", "@sum", "@avg" };
2097 const string stats_format
=
2098 (strverscmp(s
.compatible
.c_str(), "1.4") >= 0) ? "%#d" : "%#x";
2100 // Fill in the printf format for values
2101 if (l
->type
== pe_stats
)
2102 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
2103 format
+= " " + stats
[i
] + "=" + stats_format
;
2104 else if (l
->type
== pe_string
)
2105 format
+= "=\\\"%#s\\\"";
2110 // Output the actual printf
2111 code
<< "printf (\"" << format
<< "\"";
2113 // Feed indexes to the printf, and include them in the value
2114 string value
= !foreach_value
.empty() ? foreach_value
: string(l
->unmangled_name
);
2115 if (!l
->index_types
.empty())
2117 code
<< "," << indexes
;
2118 if (foreach_value
.empty())
2119 value
+= "[" + indexes
+ "]";
2122 // Feed the actual values to the printf
2123 if (l
->type
== pe_stats
)
2124 for (size_t i
= 0; i
< sizeof(stats
)/sizeof(stats
[0]); ++i
)
2125 code
<< "," << stats
[i
] << "(" << value
<< ")";
2127 code
<< "," << value
;
2128 code
<< ")" << endl
;
2131 code
<< "}" << endl
;
2133 probe
*p
= parse_synthetic_probe (s
, code
, l
->tok
);
2135 throw SEMANTIC_ERROR (_("can't create global var display"), l
->tok
);
2137 vector
<derived_probe
*> dps
;
2138 derive_probes (s
, p
, dps
);
2139 for (unsigned i
= 0; i
< dps
.size(); i
++)
2141 derived_probe
* dp
= dps
[i
];
2142 s
.probes
.push_back (dp
);
2145 // Repopulate symbol and type info
2146 symresolution_info
sym (s
);
2147 sym
.current_function
= 0;
2148 sym
.current_probe
= dp
;
2149 dp
->body
->visit (& sym
);
2152 semantic_pass_types(s
);
2153 // Mark that variable is read
2154 vut
.read
.insert (l
);
2158 static void gen_monitor_data(systemtap_session
& s
)
2164 v
->unmangled_name
= v
->name
= "__global___monitor_module_start";
2167 v
->synthetic
= true;
2168 s
.globals
.push_back(v
);
2170 ec
= new embeddedcode
;
2171 ec
->code
= "#define STAP_MONITOR_READ 8192\n"
2172 "static char _monitor_buf[STAP_MONITOR_READ];";
2173 s
.embeds
.push_back(ec
);
2175 functiondecl
* fd
= new functiondecl
;
2176 fd
->synthetic
= true;
2177 fd
->unmangled_name
= fd
->name
= "__private___monitor_data_function_probes";
2178 fd
->type
= pe_string
;
2181 v
->unmangled_name
= v
->name
= "index";
2182 fd
->formal_args
.push_back(v
);
2183 ec
= new embeddedcode
;
2185 code
= "/* unprivileged */ /* pure */"
2186 "const struct stap_probe *const p = &stap_probes[STAP_ARG_index];\n"
2187 "if (likely (probe_timing(STAP_ARG_index))) {\n"
2188 "struct stat_data *stats = _stp_stat_get (probe_timing(STAP_ARG_index), 0);\n"
2189 "if (stats->count) {\n"
2190 "int64_t avg = _stp_div64 (NULL, stats->sum, stats->count);\n"
2191 "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
2192 "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %lld, "
2193 "\\\"min\\\": %lld, \\\"avg\\\": %lld, \\\"max\\\": %lld, \",\n"
2194 "p->index, p->cond_enabled ? \"on\" : \"off\", (long long) stats->count,\n"
2195 "(long long) stats->min, (long long) avg, (long long) stats->max);\n"
2197 "snprintf(_monitor_buf, STAP_MONITOR_READ,\n"
2198 "\"\\\"index\\\": %zu, \\\"state\\\": \\\"%s\\\", \\\"hits\\\": %d, "
2199 "\\\"min\\\": %d, \\\"avg\\\": %d, \\\"max\\\": %d, \",\n"
2200 "p->index, p->cond_enabled ? \"on\" : \"off\", 0, 0, 0, 0);}}\n"
2201 "STAP_RETURN(_monitor_buf);\n";
2204 s
.functions
[fd
->name
] = fd
;
2206 stringstream probe_code
;
2207 probe_code
<< "probe begin {" << endl
;
2208 probe_code
<< "__monitor_module_start = jiffies()" << endl
;
2209 probe_code
<< "}" << endl
;
2211 probe
* p
= parse_synthetic_probe(s
, probe_code
, 0);
2213 throw SEMANTIC_ERROR (_("can't create begin probe"), 0);
2215 vector
<derived_probe
*> dps
;
2216 derive_probes (s
, p
, dps
);
2218 derived_probe
* dp
= dps
[0];
2219 s
.probes
.push_back (dp
);
2222 // Repopulate symbol info
2223 symresolution_info
sym (s
);
2224 sym
.current_function
= 0;
2225 sym
.current_probe
= dp
;
2226 dp
->body
->visit (&sym
);
2229 static void monitor_mode_read(systemtap_session
& s
)
2231 if (!s
.monitor
) return;
2233 gen_monitor_data(s
);
2237 unsigned long rough_max_json_size
= 100 +
2238 s
.globals
.size() * 100 +
2239 s
.probes
.size() * 200;
2241 code
<< "probe procfs(\"monitor_status\").read.maxsize(" << rough_max_json_size
<< ") {" << endl
;
2242 code
<< "try {"; // absorb .= overflows!
2243 code
<< "elapsed = (jiffies()-__monitor_module_start)/HZ()" << endl
;
2244 code
<< "hrs = elapsed/3600; mins = elapsed%3600/60; secs = elapsed%3600%60;" << endl
;
2245 code
<< "$value .= sprintf(\"{\\n\")" << endl
;
2246 code
<< "$value .= sprintf(\"\\\"uptime\\\": \\\"%02d:%02d:%02d\\\",\\n\", hrs, mins, secs)" << endl
;
2247 code
<< "$value .= sprintf(\"\\\"uid\\\": \\\"%d\\\",\\n\", uid())" << endl
;
2248 code
<< "$value .= sprintf(\"\\\"memory\\\": \\\"%s\\\",\\n\", module_size())" << endl
;
2249 code
<< "$value .= sprintf(\"\\\"module_name\\\": \\\"%s\\\",\\n\", module_name())" << endl
;
2251 code
<< "$value .= sprintf(\"\\\"globals\\\": {\\n\")" << endl
;
2252 for (auto it
= s
.globals
.cbegin(); it
!= s
.globals
.cend(); ++it
)
2254 if ((*it
)->synthetic
) continue;
2256 if (it
!= s
.globals
.cbegin())
2257 code
<< "$value .= sprintf(\",\\n\")" << endl
;
2259 code
<< "$value .= sprintf(\"\\\"%s\\\":\", \"" << (*it
)->unmangled_name
<< "\")" << endl
;
2260 if ((*it
)->arity
== 0)
2262 if ((*it
)->type
== pe_stats
)
2263 code
<< "$value .= sprintf(\"\\\"%d(count)\\\"\", @count(" << (*it
)->name
<< "))" << endl
;
2264 else if ((*it
)->type
== pe_string
)
2265 code
<< "$value .= string_quoted(sprintf(\"\\\"%s\\\"\"," << (*it
)->name
<< "))" << endl
;
2267 code
<< "$value .= string_quoted(sprint(" << (*it
)->name
<< "))" << endl
;
2269 else if ((*it
)->arity
> 0)
2270 code
<< "$value .= sprintf(\"\\\"[%d]\\\"\", " << (*it
)->maxsize
<< ")" << endl
;
2272 code
<< "$value .= sprintf(\"\\n},\\n\")" << endl
;
2274 code
<< "$value .= sprintf(\"\\\"probe_list\\\": [\\n\")" << endl
;
2275 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2277 if ((*it
)->synthetic
) continue;
2279 if (it
!= s
.probes
.cbegin())
2280 code
<< "$value .= sprintf(\",\\n\")" << endl
;
2282 istringstream
probe_point((*it
)->sole_location()->str());
2284 probe_point
>> name
;
2285 /* Escape quotes once for systemtap parser and once more for json parser */
2286 name
= lex_cast_qstring(lex_cast_qstring(name
));
2288 code
<< "$value .= sprintf(\"{%s\", __private___monitor_data_function_probes("
2289 << it
-s
.probes
.begin() << "))" << endl
;
2290 code
<< "$value .= sprintf(\"\\\"name\\\": %s}\", " << name
<< ")" << endl
;
2292 code
<< "$value .= sprintf(\"\\n],\\n\")" << endl
;
2294 code
<< "$value .= sprintf(\"}\\n\")" << endl
;
2296 code
<< "} catch(ex) { warn(\"JSON construction error: \" . ex) }" << endl
;
2297 code
<< "}" << endl
;
2298 probe
* p
= parse_synthetic_probe(s
, code
, 0);
2300 throw SEMANTIC_ERROR (_("can't create procfs probe"), 0);
2302 vector
<derived_probe
*> dps
;
2303 derive_probes (s
, p
, dps
);
2305 derived_probe
* dp
= dps
[0];
2306 s
.probes
.push_back (dp
);
2309 // Repopulate symbol info
2310 symresolution_info
sym (s
);
2311 sym
.current_function
= 0;
2312 sym
.current_probe
= dp
;
2313 dp
->body
->visit (&sym
);
2315 // Resolve types for variables used in the new procfs probe
2316 semantic_pass_types(s
);
2319 static void monitor_mode_write(systemtap_session
& s
)
2321 if (!s
.monitor
) return;
2323 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2325 vardecl
* v
= new vardecl
;
2326 v
->unmangled_name
= v
->name
= "__monitor_" + lex_cast(it
-s
.probes
.begin()) + "_enabled";
2327 v
->tok
= (*it
)->tok
;
2328 v
->set_arity(0, (*it
)->tok
);
2330 v
->init
= new literal_number(1);
2331 v
->synthetic
= true;
2332 s
.globals
.push_back(v
);
2334 symbol
* sym
= new symbol
;
2335 sym
->name
= v
->name
;
2337 sym
->type
= pe_long
;
2340 if ((*it
)->sole_location()->condition
)
2342 logical_and_expr
*e
= new logical_and_expr
;
2347 e
->right
= (*it
)->sole_location()->condition
;
2348 (*it
)->sole_location()->condition
= e
;
2352 (*it
)->sole_location()->condition
= sym
;
2358 code
<< "probe procfs(\"monitor_control\").write {" << endl
;
2360 code
<< "if ($value == \"clear\") {";
2361 for (auto it
= s
.globals
.cbegin(); it
!= s
.globals
.cend(); ++it
)
2365 if (v
->synthetic
) continue;
2367 if (v
->arity
== 0 && v
->init
)
2369 if (v
->type
== pe_long
)
2371 literal_number
* ln
= dynamic_cast<literal_number
*>(v
->init
);
2373 throw SEMANTIC_ERROR (_("expected literal number"), 0);
2374 code
<< v
->name
<< " = " << ln
->value
<< endl
;
2376 else if (v
->type
== pe_string
)
2378 literal_string
* ln
= dynamic_cast<literal_string
*>(v
->init
);
2380 throw SEMANTIC_ERROR (_("expected literal string"), 0);
2381 code
<< v
->name
<< " = " << lex_cast_qstring(ln
->value
) << endl
;
2386 // For scalar elements with no initial values, we reset to 0 or empty as
2387 // done with arrays and aggregates.
2388 code
<< "delete " << v
->name
<< endl
;
2392 code
<< "} else if ($value == \"resume\") {" << endl
;
2393 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2395 code
<< " __monitor_" << it
-s
.probes
.begin() << "_enabled" << " = 1" << endl
;
2398 code
<< "} else if ($value == \"pause\") {" << endl
;
2399 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2401 code
<< " __monitor_" << it
-s
.probes
.begin() << "_enabled" << " = 0" << endl
;
2403 code
<< "} else if ($value == \"quit\") {" << endl
;
2404 code
<< " exit()" << endl
;
2407 for (auto it
= s
.probes
.cbegin(); it
!= s
.probes
.cend(); ++it
)
2409 code
<< " if ($value == \"" << it
-s
.probes
.begin() << "\")"
2410 << " __monitor_" << it
-s
.probes
.begin() << "_enabled" << " ^= 1" << endl
;
2413 code
<< "}" << endl
;
2415 probe
* p
= parse_synthetic_probe(s
, code
, 0);
2417 throw SEMANTIC_ERROR (_("can't create procfs probe"), 0);
2419 vector
<derived_probe
*> dps
;
2420 derive_probes (s
, p
, dps
);
2422 derived_probe
* dp
= dps
[0];
2423 s
.probes
.push_back (dp
);
2426 // Repopulate symbol info
2427 symresolution_info
sym (s
, /* omniscient-unmangled */ true);
2428 sym
.current_function
= 0;
2429 sym
.current_probe
= dp
;
2430 dp
->body
->visit (&sym
);
2433 static void setup_timeout(systemtap_session
& s
)
2435 if (!s
.timeout
) return;
2438 code
<< "probe timer.ms(" << s
.timeout
<< ") {exit()}";
2439 probe
* p
= parse_synthetic_probe(s
, code
, 0);
2441 throw SEMANTIC_ERROR (_("can't create timer probe"), 0);
2443 vector
<derived_probe
*> dps
;
2444 derive_probes (s
, p
, dps
);
2446 derived_probe
* dp
= dps
[0];
2447 s
.probes
.push_back (dp
);
2450 // Repopulate symbol info
2451 symresolution_info
sym (s
);
2452 sym
.current_function
= 0;
2453 sym
.current_probe
= dp
;
2454 dp
->body
->visit (&sym
);
2458 semantic_pass (systemtap_session
& s
)
2464 // FIXME: interactive mode, register_library_aliases handles
2465 // both aliases from library files *and* user scripts. It would
2466 // be nice to have them in separate lists and register them
2468 s
.register_library_aliases();
2469 register_standard_tapsets(s
);
2471 if (rc
== 0) setup_timeout(s
);
2472 if (rc
== 0) rc
= semantic_pass_symbols (s
);
2473 if (rc
== 0) monitor_mode_write (s
);
2474 if (rc
== 0) rc
= semantic_pass_conditions (s
);
2475 if (rc
== 0) rc
= semantic_pass_optimize1 (s
);
2476 if (rc
== 0) rc
= semantic_pass_types (s
);
2477 if (rc
== 0) rc
= gen_dfa_table(s
);
2478 if (rc
== 0) add_global_var_display (s
);
2479 if (rc
== 0) monitor_mode_read(s
);
2480 if (rc
== 0) rc
= semantic_pass_optimize2 (s
);
2481 if (rc
== 0) rc
= semantic_pass_vars (s
);
2482 if (rc
== 0) rc
= semantic_pass_stats (s
);
2483 if (rc
== 0) embeddedcode_info_pass (s
);
2485 catch (const semantic_error
& e
)
2491 bool no_primary_probes
= true;
2492 for (unsigned i
= 0; i
< s
.probes
.size(); i
++)
2493 if (s
.is_primary_probe(s
.probes
[i
]))
2494 no_primary_probes
= false;
2496 if (s
.num_errors() == 0 && no_primary_probes
&& !s
.dump_mode
)
2498 s
.print_error(SEMANTIC_ERROR(_("no probes found")));
2505 // NB: listing mode only cares whether we have any probes,
2506 // so all previous error conditions are disregarded.
2507 if (s
.dump_mode
== systemtap_session::dump_matched_probes
||
2508 s
.dump_mode
== systemtap_session::dump_matched_probes_vars
)
2509 rc
= no_primary_probes
;
2511 // If we're dumping functions, only error out if no functions were found
2512 if (s
.dump_mode
== systemtap_session::dump_functions
)
2513 rc
= s
.functions
.empty();
2519 // ------------------------------------------------------------------------
2520 // semantic processing: symbol resolution
2523 symresolution_info::symresolution_info (systemtap_session
& s
, bool omniscient_unmangled
):
2524 session (s
), unmangled_p(omniscient_unmangled
), current_function (0), current_probe (0)
2530 symresolution_info::visit_block (block
* e
)
2532 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
2536 e
->statements
[i
]->visit (this);
2538 catch (const semantic_error
& e
)
2540 session
.print_error (e
);
2547 symresolution_info::visit_foreach_loop (foreach_loop
* e
)
2549 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2550 e
->indexes
[i
]->visit (this);
2551 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
2552 if (e
->array_slice
[i
])
2553 e
->array_slice
[i
]->visit(this);
2555 symbol
*array
= NULL
;
2556 hist_op
*hist
= NULL
;
2557 classify_indexable (e
->base
, array
, hist
);
2561 if (!array
->referent
)
2563 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2566 array
->referent
= d
;
2567 array
->name
= d
->name
;
2572 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2573 e
->indexes
.size(), array
->name
.to_string().c_str());
2574 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2578 if (!e
->array_slice
.empty() && e
->array_slice
.size() != e
->indexes
.size())
2581 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2582 e
->array_slice
.size(), array
->name
.to_string().c_str());
2583 throw SEMANTIC_ERROR (msg
.str(), array
->tok
);
2593 e
->value
->visit (this);
2596 e
->limit
->visit (this);
2598 e
->block
->visit (this);
2603 delete_statement_symresolution_info
:
2604 public traversing_visitor
2606 symresolution_info
*parent
;
2608 delete_statement_symresolution_info (symresolution_info
*p
):
2612 void visit_arrayindex (arrayindex
* e
)
2614 parent
->visit_arrayindex(e
, true);
2617 void visit_functioncall (functioncall
* e
)
2619 parent
->visit_functioncall (e
);
2622 void visit_symbol (symbol
* e
)
2627 vardecl
* d
= parent
->find_var (e
->name
, -1, e
->tok
);
2631 throw SEMANTIC_ERROR (_("unresolved array in delete statement"), e
->tok
);
2636 symresolution_info::visit_delete_statement (delete_statement
* s
)
2638 delete_statement_symresolution_info
di (this);
2639 s
->value
->visit (&di
);
2644 symresolution_info::visit_symbol (symbol
* e
)
2649 if (session
.verbose
> 3)
2650 clog
<< _F("Resolving symbol symbol %p (%s) ...", (void*) e
, ((string
)e
->name
).c_str());
2651 vardecl
* d
= find_var (e
->name
, 0, e
->tok
);
2652 if (session
.verbose
> 3)
2662 vardecl
* v
= new vardecl
;
2663 v
->unmangled_name
= v
->name
= e
->name
;
2665 v
->set_arity(0, e
->tok
);
2666 if (current_function
)
2667 current_function
->locals
.push_back (v
);
2668 else if (current_probe
)
2669 current_probe
->locals
.push_back (v
);
2671 // must be probe-condition expression
2672 throw SEMANTIC_ERROR (_("probe condition must not reference undeclared global"), e
->tok
);
2679 symresolution_info::visit_arrayindex (arrayindex
* e
)
2681 visit_arrayindex(e
, false);
2685 symresolution_info::visit_arrayindex (arrayindex
* e
, bool wildcard_ok
)
2687 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
2689 // assuming that if NULL, it was originally a wildcard (*)
2690 if (e
->indexes
[i
] == NULL
)
2693 throw SEMANTIC_ERROR(_("wildcard not allowed in array index"), e
->tok
);
2696 e
->indexes
[i
]->visit (this);
2699 symbol
*array
= NULL
;
2700 hist_op
*hist
= NULL
;
2701 classify_indexable(e
->base
, array
, hist
);
2705 if (array
->referent
)
2708 vardecl
* d
= find_var (array
->name
, e
->indexes
.size (), array
->tok
);
2711 array
->referent
= d
;
2712 array
->name
= d
->name
;
2717 msg
<< _F("unresolved arity-%zu global array %s, missing global declaration?",
2718 e
->indexes
.size(), array
->name
.to_string().c_str());
2719 throw SEMANTIC_ERROR (msg
.str(), e
->tok
);
2731 symresolution_info::visit_array_in (array_in
* e
)
2733 visit_arrayindex(e
->operand
, true);
2738 symresolution_info::visit_functioncall (functioncall
* e
)
2740 // XXX: we could relax this, if we're going to examine the
2741 // vartracking data recursively. See testsuite/semko/fortytwo.stp.
2742 if (! (current_function
|| current_probe
))
2744 // must be probe-condition expression
2745 throw SEMANTIC_ERROR (_("probe condition must not reference function"), e
->tok
);
2748 for (unsigned i
=0; i
<e
->args
.size(); i
++)
2749 e
->args
[i
]->visit (this);
2751 // already resolved?
2752 if (!e
->referents
.empty())
2755 vector
<functiondecl
*> fds
= find_functions (e
, e
->function
, e
->args
.size (), e
->tok
);
2759 function_priority_order order
;
2760 stable_sort(e
->referents
.begin(), e
->referents
.end(), order
); // preserve declaration order
2761 e
->function
= e
->referents
[0]->name
;
2765 string sugs
= levenshtein_suggest(e
->function
, collect_functions(), 5); // print 5 funcs
2766 throw SEMANTIC_ERROR(_F("unresolved function%s",
2767 sugs
.empty() ? "" : (_(" (similar: ") + sugs
+ ")").c_str()),
2771 // In monitor mode, tapset functions used in the synthetic probe are not resolved and added
2772 // to the master list at the same time as the other functions so we must add them here to
2773 // allow the translator to generate the functions in the module.
2774 if (session
.monitor
&& session
.functions
.find(e
->function
) == session
.functions
.end())
2775 session
.functions
[e
->function
] = fds
[0]; // no overload
2778 /*find_var will return an argument other than zero if the name matches the var
2779 * name ie, if the current local name matches the name passed to find_var*/
2781 symresolution_info::find_var (interned_string name
, int arity
, const token
* tok
)
2783 if (current_function
|| current_probe
)
2786 vector
<vardecl
*>& locals
= (current_function
?
2787 current_function
->locals
:
2788 current_probe
->locals
);
2791 for (unsigned i
=0; i
<locals
.size(); i
++)
2792 if (locals
[i
]->name
== name
)
2794 if (session
.verbose
> 3)
2795 clog
<< _F("to local (%p/%p) vardecl %p",
2796 (void*) current_function
, (void*) current_probe
, (void*) locals
[i
]);
2798 locals
[i
]->set_arity (arity
, tok
);
2803 // search function formal parameters (for scalars)
2804 if (arity
== 0 && current_function
)
2805 for (unsigned i
=0; i
<current_function
->formal_args
.size(); i
++)
2806 if (current_function
->formal_args
[i
]->name
== name
)
2808 // NB: no need to check arity here: formal args always scalar
2809 if (session
.verbose
> 3)
2810 clog
<< _F("to %p param vardecl %p", (void*) current_function
, (void*) current_function
->formal_args
[i
]);
2812 current_function
->formal_args
[i
]->set_arity (0, tok
);
2813 return current_function
->formal_args
[i
];
2816 // search processed globals
2817 string gname
, pname
;
2820 gname
= pname
= string(name
);
2824 gname
= "__global_" + string(name
);
2825 pname
= "__private_" + detox_path(tok
->location
.file
->name
) + string(name
);
2827 for (unsigned i
=0; i
<session
.globals
.size(); i
++)
2829 if ((session
.globals
[i
]->name
== name
&& startswith(name
, "__global_")) ||
2830 (session
.globals
[i
]->name
== gname
) ||
2831 (session
.globals
[i
]->name
== pname
))
2833 if (session
.verbose
> 3)
2834 clog
<< _F("to global vardecl %p", (void*) session
.globals
[i
]);
2836 if (! session
.suppress_warnings
)
2838 vardecl
* v
= session
.globals
[i
];
2839 stapfile
* f
= tok
->location
.file
;
2840 // clog << "resolved " << *tok << " to global " << *v->tok << endl;
2841 if (v
->tok
&& v
->tok
->location
.file
!= f
&& !f
->synthetic
)
2843 session
.print_warning (_F("cross-file global variable reference to %s from",
2844 lex_cast(*v
->tok
).c_str()), tok
);
2847 session
.globals
[i
]->set_arity (arity
, tok
);
2848 return session
.globals
[i
];
2852 // search library globals
2853 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
2855 stapfile
* f
= session
.library_files
[i
];
2856 for (unsigned j
=0; j
<f
->globals
.size(); j
++)
2858 vardecl
* g
= f
->globals
[j
];
2859 if ((g
->name
== gname
) ||
2860 (g
->name
== pname
)) // private global within tapset probe alias
2862 if (session
.verbose
> 3)
2863 clog
<< _F("to tapset global vardecl %p", (void*) g
);
2865 g
->set_arity (arity
, tok
);
2867 // put library into the queue if not already there
2868 if (find (session
.files
.begin(), session
.files
.end(), f
)
2869 == session
.files
.end())
2870 session
.files
.push_back (f
);
2881 class functioncall_security_check
: public traversing_visitor
2883 systemtap_session
& session
;
2885 functiondecl
* current_function
;
2887 functioncall_security_check(systemtap_session
&s
, functioncall
* c
): session(s
),call(c
) {}
2888 void traverse (functiondecl
* d
)
2890 current_function
= d
;
2891 current_function
->body
->visit(this);
2894 void visit_embeddedcode (embeddedcode
*s
)
2896 // Don't allow embedded C functions in unprivileged mode unless
2897 // they are tagged with /* unprivileged */ or /* myproc-unprivileged */
2898 // or we're in a usermode runtime.
2899 if (! pr_contains (session
.privilege
, pr_stapdev
) &&
2900 ! pr_contains (session
.privilege
, pr_stapsys
) &&
2901 ! session
.runtime_usermode_p () &&
2902 s
->code
.find ("/* unprivileged */") == string::npos
&&
2903 s
->code
.find ("/* myproc-unprivileged */") == string::npos
)
2904 throw SEMANTIC_ERROR (_F("function may not be used when --privilege=%s is specified",
2905 pr_name (session
.privilege
)),
2906 current_function
->tok
);
2908 // Allow only /* bpf */ functions in bpf mode.
2909 if ((session
.runtime_mode
== systemtap_session::bpf_runtime
)
2910 != (s
->code
.find ("/* bpf */") != string::npos
))
2912 if (session
.runtime_mode
== systemtap_session::bpf_runtime
)
2913 throw SEMANTIC_ERROR (_("function may not be used with bpf runtime"),
2914 current_function
->tok
);
2916 throw SEMANTIC_ERROR (_("function requires bpf runtime"),
2917 current_function
->tok
);
2920 // Don't allow /* guru */ functions unless caller is privileged.
2921 if (!call
->tok
->location
.file
->privileged
&& s
->code
.find ("/* guru */") != string::npos
)
2922 throw SEMANTIC_ERROR (_("function may not be used unless -g is specified"),
2928 vector
<functiondecl
*>
2929 symresolution_info::find_functions (functioncall
*call
, const string
& name
, unsigned arity
, const token
*tok
)
2931 vector
<functiondecl
*> functions
;
2932 functiondecl
* last
= 0; // used for error message
2936 // internal global functions bypassing the parser, such as __global_dwarf_tvar_[gs]et
2937 if ((session
.functions
.find(name
) != session
.functions
.end()) && startswith(name
, "__private_"))
2939 functiondecl
* fd
= session
.functions
[name
];
2940 assert (fd
->name
== name
);
2941 if (fd
->formal_args
.size() == arity
)
2942 functions
.push_back(fd
);
2947 // functions scanned by the parser are overloaded
2948 unsigned alternatives
= session
.overload_count
[name
];
2949 for (unsigned alt
= 0; alt
< alternatives
; alt
++)
2951 bool found
= false; // multiple inclusion guard
2952 string gname
= "__global_" + string(name
) + "__overload_" + lex_cast(alt
);
2953 string pname
= "__private_" + detox_path(tok
->location
.file
->name
) + string(name
) +
2954 "__overload_" + lex_cast(alt
);
2956 // tapset or user script global functions coming from the parser
2957 if (!found
&& session
.functions
.find(gname
) != session
.functions
.end())
2959 functiondecl
* fd
= session
.functions
[gname
];
2960 assert (fd
->name
== gname
);
2961 if (fd
->formal_args
.size() == arity
)
2963 functions
.push_back(fd
);
2970 // tapset or user script private functions coming from the parser
2971 if (!found
&& session
.functions
.find(pname
) != session
.functions
.end())
2973 functiondecl
* fd
= session
.functions
[pname
];
2974 assert (fd
->name
== pname
);
2975 if (fd
->formal_args
.size() == arity
)
2977 functions
.push_back(fd
);
2984 // search library functions
2985 for (unsigned i
=0; !found
&& i
<session
.library_files
.size(); i
++)
2987 stapfile
* f
= session
.library_files
[i
];
2988 for (unsigned j
=0; !found
&& j
<f
->functions
.size(); j
++)
2990 if ((f
->functions
[j
]->name
== gname
) ||
2991 (f
->functions
[j
]->name
== pname
))
2993 if (f
->functions
[j
]->formal_args
.size() == arity
)
2995 // put library into the queue if not already there
2996 if (0) // session.verbose_resolution
2997 cerr
<< _F(" function %s is defined from %s",
2998 name
.c_str(), f
->name
.c_str()) << endl
;
3000 if (find (session
.files
.begin(), session
.files
.end(), f
)
3001 == session
.files
.end())
3002 session
.files
.push_back (f
);
3003 // else .. print different message?
3005 functions
.push_back(f
->functions
[j
]);
3009 last
= f
->functions
[j
];
3015 // suggest last found function with matching name
3016 if (last
&& functions
.empty())
3018 throw SEMANTIC_ERROR(_F("arity mismatch found (function '%s' takes %zu args)",
3019 name
.c_str(), last
->formal_args
.size()), tok
, last
->tok
);
3022 // check every function for safety/security constraints
3023 functioncall_security_check
fsc(session
, call
);
3024 for (auto gi
= functions
.begin(); gi
!= functions
.end(); gi
++)
3031 symresolution_info::collect_functions(void)
3035 for (map
<string
,functiondecl
*>::const_iterator it
= session
.functions
.begin();
3036 it
!= session
.functions
.end(); ++it
)
3037 funcs
.insert(it
->second
->unmangled_name
);
3039 // search library functions
3040 for (unsigned i
=0; i
<session
.library_files
.size(); i
++)
3042 stapfile
* f
= session
.library_files
[i
];
3043 for (unsigned j
=0; j
<f
->functions
.size(); j
++)
3044 if (! f
->functions
[j
]->name
.starts_with("__private_"))
3045 funcs
.insert(f
->functions
[j
]->unmangled_name
);
3051 // ------------------------------------------------------------------------
3055 // Do away with functiondecls that are never (transitively) called
3057 void semantic_pass_opt1 (systemtap_session
& s
, bool& relaxed_p
)
3059 functioncall_traversing_visitor ftv
;
3060 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3062 s
.probes
[i
]->body
->visit (& ftv
);
3063 if (s
.probes
[i
]->sole_location()->condition
)
3064 s
.probes
[i
]->sole_location()->condition
->visit (& ftv
);
3066 vector
<functiondecl
*> new_unused_functions
;
3067 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3069 functiondecl
* fd
= it
->second
;
3070 if (ftv
.seen
.find(fd
) == ftv
.seen
.end())
3072 if (! fd
->synthetic
&& s
.is_user_file(fd
->tok
->location
.file
->name
))
3073 s
.print_warning (_F("Eliding unused function '%s'",
3074 fd
->unmangled_name
.to_string().c_str()),
3076 // s.functions.erase (it); // NB: can't, since we're already iterating upon it
3077 new_unused_functions
.push_back (fd
);
3081 for (unsigned i
=0; i
<new_unused_functions
.size(); i
++)
3083 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (new_unused_functions
[i
]->name
);
3084 assert (where
!= s
.functions
.end());
3085 s
.functions
.erase (where
);
3086 if (s
.tapset_compile_coverage
)
3087 s
.unused_functions
.push_back (new_unused_functions
[i
]);
3092 // ------------------------------------------------------------------------
3094 // Do away with local & global variables that are never
3095 // written nor read.
3096 void semantic_pass_opt2 (systemtap_session
& s
, bool& relaxed_p
, unsigned iterations
)
3098 varuse_collecting_visitor
vut(s
);
3100 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3102 s
.probes
[i
]->body
->visit (& vut
);
3104 if (s
.probes
[i
]->sole_location()->condition
)
3105 s
.probes
[i
]->sole_location()->condition
->visit (& vut
);
3108 // NB: Since varuse_collecting_visitor also traverses down
3109 // actually called functions, we don't need to explicitly
3110 // iterate over them. Uncalled ones should have been pruned
3113 // for (unsigned i=0; i<s.functions.size(); i++)
3114 // s.functions[i]->body->visit (& vut);
3116 // Now in vut.read/written, we have a mixture of all locals, globals
3118 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3119 for (unsigned j
=0; j
<s
.probes
[i
]->locals
.size(); /* see below */)
3121 vardecl
* l
= s
.probes
[i
]->locals
[j
];
3123 // skip over "special" locals
3124 if (l
->synthetic
) { j
++; continue; }
3126 if (vut
.read
.find (l
) == vut
.read
.end() &&
3127 vut
.written
.find (l
) == vut
.written
.end())
3129 if (!l
->tok
->location
.file
->synthetic
&& s
.is_user_file(l
->tok
->location
.file
->name
))
3130 s
.print_warning (_F("Eliding unused variable '%s'",
3131 l
->unmangled_name
.to_string().c_str()),
3133 if (s
.tapset_compile_coverage
) {
3134 s
.probes
[i
]->unused_locals
.push_back
3135 (s
.probes
[i
]->locals
[j
]);
3137 s
.probes
[i
]->locals
.erase(s
.probes
[i
]->locals
.begin() + j
);
3139 // don't increment j
3143 if (vut
.written
.find (l
) == vut
.written
.end())
3144 if (iterations
== 0 && ! s
.suppress_warnings
)
3148 // like collect_functions()
3149 vector
<vardecl
*>::iterator it
;
3150 for (it
= s
.probes
[i
]->locals
.begin(); it
!= s
.probes
[i
]->locals
.end(); it
++)
3151 vars
.insert((*it
)->unmangled_name
);
3152 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
3153 if (! (*it
)->unmangled_name
.starts_with("__private_"))
3154 vars
.insert((*it
)->unmangled_name
);
3156 vars
.erase(l
->name
);
3157 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
3158 s
.print_warning (_F("never-assigned local variable '%s'%s",
3159 l
->unmangled_name
.to_string().c_str(),
3160 (sugs
.empty() ? "" :
3161 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
3167 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3169 functiondecl
*fd
= it
->second
;
3170 for (unsigned j
=0; j
<fd
->locals
.size(); /* see below */)
3172 vardecl
* l
= fd
->locals
[j
];
3173 if (vut
.read
.find (l
) == vut
.read
.end() &&
3174 vut
.written
.find (l
) == vut
.written
.end())
3176 if (!l
->tok
->location
.file
->synthetic
&& s
.is_user_file(l
->tok
->location
.file
->name
))
3177 s
.print_warning (_F("Eliding unused variable '%s'",
3178 l
->unmangled_name
.to_string().c_str()),
3180 if (s
.tapset_compile_coverage
) {
3181 fd
->unused_locals
.push_back (fd
->locals
[j
]);
3183 fd
->locals
.erase(fd
->locals
.begin() + j
);
3185 // don't increment j
3189 if (vut
.written
.find (l
) == vut
.written
.end())
3190 if (iterations
== 0 && ! s
.suppress_warnings
)
3193 vector
<vardecl
*>::iterator it
;
3194 for (it
= fd
->formal_args
.begin() ;
3195 it
!= fd
->formal_args
.end(); it
++)
3196 vars
.insert((*it
)->unmangled_name
);
3197 for (it
= fd
->locals
.begin(); it
!= fd
->locals
.end(); it
++)
3198 vars
.insert((*it
)->unmangled_name
);
3199 for (it
= s
.globals
.begin(); it
!= s
.globals
.end(); it
++)
3200 if (! (*it
)->unmangled_name
.starts_with("__private_"))
3201 vars
.insert((*it
)->unmangled_name
);
3203 vars
.erase(l
->name
);
3204 string sugs
= levenshtein_suggest(l
->name
, vars
, 5); // suggest top 5 vars
3205 s
.print_warning (_F("never-assigned local variable '%s'%s",
3206 l
->unmangled_name
.to_string().c_str(),
3207 (sugs
.empty() ? "" :
3208 (_(" (similar: ") + sugs
+ ")")).c_str()), l
->tok
);
3215 for (unsigned i
=0; i
<s
.globals
.size(); /* see below */)
3217 vardecl
* l
= s
.globals
[i
];
3218 if (vut
.read
.find (l
) == vut
.read
.end() &&
3219 vut
.written
.find (l
) == vut
.written
.end())
3221 if (!l
->tok
->location
.file
->synthetic
&& s
.is_user_file(l
->tok
->location
.file
->name
))
3222 s
.print_warning (_F("Eliding unused variable '%s'",
3223 l
->unmangled_name
.to_string().c_str()),
3225 if (s
.tapset_compile_coverage
) {
3226 s
.unused_globals
.push_back(s
.globals
[i
]);
3228 s
.globals
.erase(s
.globals
.begin() + i
);
3230 // don't increment i
3234 if (vut
.written
.find (l
) == vut
.written
.end() && ! l
->init
) // no initializer
3235 if (iterations
== 0 && ! s
.suppress_warnings
)
3237 // check if it was initialized on the command line via
3239 bool init_by_gopt
= false;
3240 string
init_prefix (l
->unmangled_name
.to_string() + "=");
3241 for (auto gi
= s
.globalopts
.begin(); gi
!= s
.globalopts
.end();
3243 if (! gi
->compare(0, init_prefix
.size(), init_prefix
))
3245 init_by_gopt
= true;
3251 for (auto it
= s
.globals
.begin(); it
!= s
.globals
.end();
3253 if (l
->name
!= (*it
)->unmangled_name
)
3254 if (! (*it
)->unmangled_name
.starts_with("__private_"))
3255 vars
.insert((*it
)->unmangled_name
);
3257 // suggest top 5 vars
3258 string sugs
= levenshtein_suggest(l
->name
, vars
, 5);
3259 s
.print_warning (_F("never-assigned global variable '%s'%s",
3260 l
->unmangled_name
.to_string().c_str(),
3261 (sugs
.empty() ? "" :
3262 (_(" (similar: ") + sugs
+ ")")).c_str()),
3273 // ------------------------------------------------------------------------
3275 struct dead_assignment_remover
: public update_visitor
3277 systemtap_session
& session
;
3279 const varuse_collecting_visitor
& vut
;
3281 dead_assignment_remover(systemtap_session
& s
, bool& r
,
3282 const varuse_collecting_visitor
& v
):
3283 update_visitor(s
.verbose
), session(s
), relaxed_p(r
), vut(v
) {}
3285 void visit_assignment (assignment
* e
);
3286 void visit_try_block (try_block
*s
);
3290 // symbol_fetcher augmented to allow target-symbol types, but NULLed.
3291 struct assignment_symbol_fetcher
3292 : public symbol_fetcher
3294 const token
* assignment_t
;
3296 assignment_symbol_fetcher (symbol
*&sym
, const token
* a_t
): symbol_fetcher(sym
),
3300 void visit_target_symbol (target_symbol
*)
3305 void visit_atvar_op (atvar_op
*)
3310 void visit_cast_op (cast_op
*)
3315 void visit_autocast_op (autocast_op
*)
3320 void visit_target_deref (target_deref
*)
3325 void visit_target_register (target_register
*)
3330 void throwone (const token
* t
)
3332 if (t
->type
== tok_operator
&& t
->content
== ".")
3333 // guess someone misused . in $foo->bar.baz expression
3334 // XXX why are we only checking this in lvalues?
3335 throw SEMANTIC_ERROR (_("Expecting lvalue for assignment, try -> instead"),
3338 throw SEMANTIC_ERROR (_("Expecting lvalue for assignment"), assignment_t
, t
);
3343 get_assignment_symbol_within_expression (expression
*e
, const token
*a_t
)
3346 assignment_symbol_fetcher
fetcher(sym
, a_t
);
3347 e
->visit (&fetcher
);
3348 return sym
; // NB: may be null!
3353 dead_assignment_remover::visit_assignment (assignment
* e
)
3358 symbol
* left
= get_assignment_symbol_within_expression (e
->left
, e
->tok
);
3359 if (left
) // not unresolved $target, so intended sideeffect may be elided
3361 vardecl
* leftvar
= left
->referent
;
3362 if (vut
.read
.find(leftvar
) == vut
.read
.end()) // var never read?
3364 // NB: Not so fast! The left side could be an array whose
3365 // index expressions may have side-effects. This would be
3366 // OK if we could replace the array assignment with a
3367 // statement-expression containing all the index expressions
3368 // and the rvalue... but we can't.
3369 // Another possibility is that we have an unread global variable
3370 // which are kept for probe end value display.
3372 bool is_global
= false;
3373 vector
<vardecl
*>::iterator it
;
3374 for (it
= session
.globals
.begin(); it
!= session
.globals
.end(); it
++)
3375 if (leftvar
->name
== (*it
)->name
)
3381 varuse_collecting_visitor
lvut(session
);
3382 e
->left
->visit (& lvut
);
3383 if (lvut
.side_effect_free () && !is_global
// XXX: use _wrt() once we track focal_vars
3384 && !leftvar
->synthetic
) // don't elide assignment to synthetic $context variables
3386 /* PR 1119: NB: This is not necessary here. A write-only
3387 variable will also be elided soon at the next _opt2 iteration.
3388 if (e->left->tok->location.file->name == session.user_file->name) // !tapset
3389 session.print_warning("eliding write-only ", *e->left->tok);
3392 if (!e
->left
->tok
->location
.file
->synthetic
&& session
.is_user_file(e
->left
->tok
->location
.file
->name
))
3393 session
.print_warning(_F("Eliding assignment to '%s'",
3394 leftvar
->unmangled_name
.to_string().c_str()), e
->tok
);
3395 provide (e
->right
); // goodbye assignment*
3406 dead_assignment_remover::visit_try_block (try_block
*s
)
3408 replace (s
->try_block
);
3409 if (s
->catch_error_var
)
3411 vardecl
* errvar
= s
->catch_error_var
->referent
;
3412 if (vut
.read
.find(errvar
) == vut
.read
.end()) // never read?
3414 if (session
.verbose
>2)
3415 clog
<< _F("Eliding unused error string catcher %s at %s",
3416 errvar
->unmangled_name
.to_string().c_str(),
3417 lex_cast(*s
->tok
).c_str()) << endl
;
3418 s
->catch_error_var
= 0;
3421 replace (s
->catch_block
);
3426 // Let's remove assignments to variables that are never read. We
3427 // rewrite "(foo = expr)" as "(expr)". This makes foo a candidate to
3428 // be optimized away as an unused variable, and expr a candidate to be
3429 // removed as a side-effect-free statement expression. Wahoo!
3430 void semantic_pass_opt3 (systemtap_session
& s
, bool& relaxed_p
)
3432 // Recompute the varuse data, which will probably match the opt2
3433 // copy of the computation, except for those totally unused
3434 // variables that opt2 removed.
3435 varuse_collecting_visitor
vut(s
);
3436 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3437 s
.probes
[i
]->body
->visit (& vut
); // includes reachable functions too
3439 dead_assignment_remover
dar (s
, relaxed_p
, vut
);
3440 // This instance may be reused for multiple probe/function body trims.
3442 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3443 dar
.replace (s
.probes
[i
]->body
);
3444 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
3445 it
!= s
.functions
.end(); it
++)
3446 dar
.replace (it
->second
->body
);
3447 // The rewrite operation is performed within the visitor.
3449 // XXX: we could also zap write-only globals here
3453 // ------------------------------------------------------------------------
3455 struct dead_stmtexpr_remover
: public update_visitor
3457 systemtap_session
& session
;
3459 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
3461 dead_stmtexpr_remover(systemtap_session
& s
, bool& r
):
3462 update_visitor(s
.verbose
), session(s
), relaxed_p(r
) {}
3464 void visit_block (block
*s
);
3465 void visit_try_block (try_block
*s
);
3466 void visit_null_statement (null_statement
*s
);
3467 void visit_if_statement (if_statement
* s
);
3468 void visit_foreach_loop (foreach_loop
*s
);
3469 void visit_for_loop (for_loop
*s
);
3470 // XXX: and other places where stmt_expr's might be nested
3472 void visit_expr_statement (expr_statement
*s
);
3477 dead_stmtexpr_remover::visit_null_statement (null_statement
*s
)
3480 if (session
.verbose
>2)
3481 clog
<< _("Eliding side-effect-free null statement ") << *s
->tok
<< endl
;
3488 dead_stmtexpr_remover::visit_block (block
*s
)
3490 vector
<statement
*> new_stmts
;
3491 for (unsigned i
=0; i
<s
->statements
.size(); i
++ )
3493 statement
* new_stmt
= require (s
->statements
[i
], true);
3496 // flatten nested blocks into this one
3497 block
*b
= dynamic_cast<block
*>(new_stmt
);
3500 if (session
.verbose
>2)
3501 clog
<< _("Flattening nested block ") << *b
->tok
<< endl
;
3502 new_stmts
.insert(new_stmts
.end(),
3503 b
->statements
.begin(), b
->statements
.end());
3507 new_stmts
.push_back (new_stmt
);
3510 if (new_stmts
.size() == 0)
3512 if (session
.verbose
>2)
3513 clog
<< _("Eliding side-effect-free empty block ") << *s
->tok
<< endl
;
3516 else if (new_stmts
.size() == 1)
3518 if (session
.verbose
>2)
3519 clog
<< _("Eliding side-effect-free singleton block ") << *s
->tok
<< endl
;
3520 provide (new_stmts
[0]);
3524 s
->statements
= new_stmts
;
3530 dead_stmtexpr_remover::visit_try_block (try_block
*s
)
3532 replace (s
->try_block
, true);
3533 replace (s
->catch_block
, true); // null catch{} is ok and useful
3534 if (s
->try_block
== 0)
3536 if (session
.verbose
>2)
3537 clog
<< _("Eliding empty try {} block ") << *s
->tok
<< endl
;
3545 dead_stmtexpr_remover::visit_if_statement (if_statement
*s
)
3547 replace (s
->thenblock
, true);
3548 replace (s
->elseblock
, true);
3550 if (s
->thenblock
== 0)
3552 if (s
->elseblock
== 0)
3554 // We may be able to elide this statement, if the condition
3555 // expression is side-effect-free.
3556 varuse_collecting_visitor
vct(session
);
3557 s
->condition
->visit(& vct
);
3558 if (vct
.side_effect_free ())
3560 if (session
.verbose
>2)
3561 clog
<< _("Eliding side-effect-free if statement ")
3563 s
= 0; // yeah, baby
3567 // We can still turn it into a simple expr_statement though...
3568 if (session
.verbose
>2)
3569 clog
<< _("Creating simple evaluation from if statement ")
3571 expr_statement
*es
= new expr_statement
;
3572 es
->value
= s
->condition
;
3573 es
->tok
= es
->value
->tok
;
3580 // For an else without a then, we can invert the condition logic to
3581 // avoid having a null statement in the thenblock
3582 if (session
.verbose
>2)
3583 clog
<< _("Inverting the condition of if statement ")
3585 unary_expression
*ue
= new unary_expression
;
3586 ue
->operand
= s
->condition
;
3587 ue
->tok
= ue
->operand
->tok
;
3590 s
->thenblock
= s
->elseblock
;
3598 dead_stmtexpr_remover::visit_foreach_loop (foreach_loop
*s
)
3600 replace (s
->block
, true);
3604 // XXX what if s->limit has side effects?
3605 // XXX what about s->indexes or s->value used outside the loop?
3606 if(session
.verbose
> 2)
3607 clog
<< _("Eliding side-effect-free foreach statement ") << *s
->tok
<< endl
;
3608 s
= 0; // yeah, baby
3614 dead_stmtexpr_remover::visit_for_loop (for_loop
*s
)
3616 replace (s
->block
, true);
3620 // We may be able to elide this statement, if the condition
3621 // expression is side-effect-free.
3622 varuse_collecting_visitor
vct(session
);
3623 if (s
->init
) s
->init
->visit(& vct
);
3624 s
->cond
->visit(& vct
);
3625 if (s
->incr
) s
->incr
->visit(& vct
);
3626 if (vct
.side_effect_free ())
3628 if (session
.verbose
>2)
3629 clog
<< _("Eliding side-effect-free for statement ") << *s
->tok
<< endl
;
3630 s
= 0; // yeah, baby
3634 // Can't elide this whole statement; put a null in there.
3635 s
->block
= new null_statement(s
->tok
);
3644 dead_stmtexpr_remover::visit_expr_statement (expr_statement
*s
)
3646 // Run a varuse query against the operand expression. If it has no
3647 // side-effects, replace the entire statement expression by a null
3648 // statement with the provide() call.
3650 // Unlike many other visitors, we do *not* traverse this outermost
3651 // one into the expression subtrees. There is no need - no
3652 // expr_statement nodes will be found there. (Function bodies
3653 // need to be visited explicitly by our caller.)
3655 // NB. While we don't share nodes in the parse tree, let's not
3656 // deallocate *s anyway, just in case...
3658 varuse_collecting_visitor
vut(session
);
3659 s
->value
->visit (& vut
);
3661 if (vut
.side_effect_free_wrt (focal_vars
))
3663 /* PR 1119: NB: this message is not a good idea here. It can
3664 name some arbitrary RHS expression of an assignment.
3665 if (s->value->tok->location.file->name == session.user_file->name) // not tapset
3666 session.print_warning("eliding never-assigned ", *s->value->tok);
3669 if (!s
->value
->tok
->location
.file
->synthetic
&& session
.is_user_file(s
->value
->tok
->location
.file
->name
))
3670 session
.print_warning("Eliding side-effect-free expression ", s
->tok
);
3672 // NB: this 0 pointer is invalid to leave around for any length of
3673 // time, but the parent parse tree objects above handle it.
3681 void semantic_pass_opt4 (systemtap_session
& s
, bool& relaxed_p
)
3683 // Finally, let's remove some statement-expressions that have no
3684 // side-effect. These should be exactly those whose private varuse
3685 // visitors come back with an empty "written" and "embedded" lists.
3687 dead_stmtexpr_remover
duv (s
, relaxed_p
);
3688 // This instance may be reused for multiple probe/function body trims.
3690 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
3692 assert_no_interrupts();
3694 derived_probe
* p
= s
.probes
[i
];
3696 duv
.focal_vars
.clear ();
3697 duv
.focal_vars
.insert (s
.globals
.begin(),
3699 duv
.focal_vars
.insert (p
->locals
.begin(),
3702 duv
.replace (p
->body
, true);
3705 if (! s
.timing
&& // PR10070
3706 !(p
->base
->tok
->location
.file
->synthetic
)) // don't warn for synthetic probes
3707 s
.print_warning (_("side-effect-free probe"), p
->tok
);
3709 p
->body
= new null_statement(p
->tok
);
3711 // XXX: possible duplicate warnings; see below
3714 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
3716 assert_no_interrupts();
3718 functiondecl
* fn
= it
->second
;
3719 duv
.focal_vars
.clear ();
3720 duv
.focal_vars
.insert (fn
->locals
.begin(),
3722 duv
.focal_vars
.insert (fn
->formal_args
.begin(),
3723 fn
->formal_args
.end());
3724 duv
.focal_vars
.insert (s
.globals
.begin(),
3727 duv
.replace (fn
->body
, true);
3730 s
.print_warning (_F("side-effect-free function '%s'",
3731 fn
->unmangled_name
.to_string().c_str()),
3734 fn
->body
= new null_statement(fn
->tok
);
3736 // XXX: the next iteration of the outer optimization loop may
3737 // take this new null_statement away again, and thus give us a
3738 // fresh warning. It would be better if this fixup was performed
3739 // only after the relaxation iterations.
3740 // XXX: or else see bug #6469.
3746 // ------------------------------------------------------------------------
3748 // The goal of this visitor is to reduce top-level expressions in void context
3749 // into separate statements that evaluate each subcomponent of the expression.
3750 // The dead-statement-remover can later remove some parts if they have no side
3753 // All expressions must be overridden here so we never visit their subexpressions
3754 // accidentally. Thus, the only visited expressions should be value of an
3757 // For an expression to replace its expr_statement with something else, it will
3758 // let the new statement provide(), and then provide(0) for itself. The
3759 // expr_statement will take this as a sign that it's been replaced.
3760 struct void_statement_reducer
: public update_visitor
3762 systemtap_session
& session
;
3764 set
<vardecl
*> focal_vars
; // vars considered subject to side-effects
3766 void_statement_reducer(systemtap_session
& s
, bool& r
):
3767 update_visitor(s
.verbose
), session(s
), relaxed_p(r
) {}
3769 void visit_expr_statement (expr_statement
* s
);
3771 // expressions in conditional / loop controls are definitely a side effect,
3772 // but still recurse into the child statements
3773 void visit_if_statement (if_statement
* s
);
3774 void visit_for_loop (for_loop
* s
);
3775 void visit_foreach_loop (foreach_loop
* s
);
3777 // these expressions get rewritten into their statement equivalents
3778 void visit_logical_or_expr (logical_or_expr
* e
);
3779 void visit_logical_and_expr (logical_and_expr
* e
);
3780 void visit_ternary_expression (ternary_expression
* e
);
3782 // all of these can (usually) be reduced into simpler statements
3783 void visit_binary_expression (binary_expression
* e
);
3784 void visit_unary_expression (unary_expression
* e
);
3785 void visit_regex_query (regex_query
* e
); // XXX depends on subexpr extraction
3786 void visit_comparison (comparison
* e
);
3787 void visit_concatenation (concatenation
* e
);
3788 void visit_functioncall (functioncall
* e
);
3789 void visit_print_format (print_format
* e
);
3790 void visit_target_symbol (target_symbol
* e
);
3791 void visit_atvar_op (atvar_op
* e
);
3792 void visit_cast_op (cast_op
* e
);
3793 void visit_autocast_op (autocast_op
* e
);
3794 void visit_defined_op (defined_op
* e
);
3796 // these are a bit hairy to grok due to the intricacies of indexables and
3797 // stats, so I'm chickening out and skipping them...
3798 void visit_array_in (array_in
* e
) { provide (e
); }
3799 void visit_arrayindex (arrayindex
* e
) { provide (e
); }
3800 void visit_stat_op (stat_op
* e
) { provide (e
); }
3801 void visit_hist_op (hist_op
* e
) { provide (e
); }
3803 // these can't be reduced because they always have an effect
3804 void visit_return_statement (return_statement
* s
) { provide (s
); }
3805 void visit_delete_statement (delete_statement
* s
) { provide (s
); }
3806 void visit_pre_crement (pre_crement
* e
) { provide (e
); }
3807 void visit_post_crement (post_crement
* e
) { provide (e
); }
3808 void visit_assignment (assignment
* e
) { provide (e
); }
3811 void reduce_target_symbol (target_symbol
* e
, expression
* operand
=NULL
);
3816 void_statement_reducer::visit_expr_statement (expr_statement
* s
)
3818 replace (s
->value
, true);
3820 // if the expression provides 0, that's our signal that a new
3821 // statement has been provided, so we shouldn't provide this one.
3827 void_statement_reducer::visit_if_statement (if_statement
* s
)
3829 // s->condition is never void
3830 replace (s
->thenblock
);
3831 replace (s
->elseblock
);
3836 void_statement_reducer::visit_for_loop (for_loop
* s
)
3838 // s->init/cond/incr are never void
3844 void_statement_reducer::visit_foreach_loop (foreach_loop
* s
)
3846 // s->indexes/base/value/limit are never void
3852 void_statement_reducer::visit_logical_or_expr (logical_or_expr
* e
)
3854 // In void context, the evaluation of "a || b" is exactly like
3855 // "if (!a) b", so let's do that instead.
3857 if (session
.verbose
>2)
3858 clog
<< _("Creating if statement from unused logical-or ")
3861 if_statement
*is
= new if_statement
;
3865 unary_expression
*ue
= new unary_expression
;
3866 ue
->operand
= e
->left
;
3871 expr_statement
*es
= new expr_statement
;
3872 es
->value
= e
->right
;
3873 es
->tok
= es
->value
->tok
;
3883 void_statement_reducer::visit_logical_and_expr (logical_and_expr
* e
)
3885 // In void context, the evaluation of "a && b" is exactly like
3886 // "if (a) b", so let's do that instead.
3888 if (session
.verbose
>2)
3889 clog
<< _("Creating if statement from unused logical-and ")
3892 if_statement
*is
= new if_statement
;
3895 is
->condition
= e
->left
;
3897 expr_statement
*es
= new expr_statement
;
3898 es
->value
= e
->right
;
3899 es
->tok
= es
->value
->tok
;
3909 void_statement_reducer::visit_ternary_expression (ternary_expression
* e
)
3911 // In void context, the evaluation of "a ? b : c" is exactly like
3912 // "if (a) b else c", so let's do that instead.
3914 if (session
.verbose
>2)
3915 clog
<< _("Creating if statement from unused ternary expression ")
3918 if_statement
*is
= new if_statement
;
3920 is
->condition
= e
->cond
;
3922 expr_statement
*es
= new expr_statement
;
3923 es
->value
= e
->truevalue
;
3924 es
->tok
= es
->value
->tok
;
3927 es
= new expr_statement
;
3928 es
->value
= e
->falsevalue
;
3929 es
->tok
= es
->value
->tok
;
3939 void_statement_reducer::visit_binary_expression (binary_expression
* e
)
3941 // When the result of a binary operation isn't needed, it's just as good to
3942 // evaluate the operands as sequential statements in a block.
3944 if (session
.verbose
>2)
3945 clog
<< _("Eliding unused binary ") << *e
->tok
<< endl
;
3947 block
*b
= new block
;
3950 expr_statement
*es
= new expr_statement
;
3951 es
->value
= e
->left
;
3952 es
->tok
= es
->value
->tok
;
3953 b
->statements
.push_back(es
);
3955 es
= new expr_statement
;
3956 es
->value
= e
->right
;
3957 es
->tok
= es
->value
->tok
;
3958 b
->statements
.push_back(es
);
3967 void_statement_reducer::visit_unary_expression (unary_expression
* e
)
3969 // When the result of a unary operation isn't needed, it's just as good to
3970 // evaluate the operand directly
3972 if (session
.verbose
>2)
3973 clog
<< _("Eliding unused unary ") << *e
->tok
<< endl
;
3976 e
->operand
->visit(this);
3980 void_statement_reducer::visit_regex_query (regex_query
* e
)
3982 // TODOXXX After subexpression extraction is implemented,
3983 // regular expression matches *may* have side-effects in
3984 // terms of producing matched subexpressions, e.g.:
3986 // str =~ "pat"; println(matched(0));
3988 // It's debatable if we want to actually allow this, though.
3990 // Treat e as a unary expression on the left operand -- since the
3991 // right hand side must be a literal (as verified by the parser),
3992 // evaluating it never has side effects.
3994 if (session
.verbose
>2)
3995 clog
<< _("Eliding regex query ") << *e
->tok
<< endl
;
3998 e
->left
->visit(this);
4002 void_statement_reducer::visit_comparison (comparison
* e
)
4004 visit_binary_expression(e
);
4008 void_statement_reducer::visit_concatenation (concatenation
* e
)
4010 visit_binary_expression(e
);
4014 void_statement_reducer::visit_functioncall (functioncall
* e
)
4016 // If a function call is pure and its result ignored, we can elide the call
4017 // and just evaluate the arguments in sequence
4019 if (e
->args
.empty())
4025 bool side_effect_free
= true;
4026 for (unsigned i
= 0; i
< e
->referents
.size(); i
++)
4028 varuse_collecting_visitor
vut(session
);
4029 vut
.seen
.insert (e
->referents
[i
]);
4030 vut
.current_function
= e
->referents
[i
];
4031 e
->referents
[i
]->body
->visit (& vut
);
4032 if (!vut
.side_effect_free_wrt(focal_vars
))
4034 side_effect_free
= false;
4039 if (!side_effect_free
)
4045 if (session
.verbose
>2)
4046 clog
<< _("Eliding side-effect-free function call ") << *e
->tok
<< endl
;
4048 block
*b
= new block
;
4051 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
4053 expr_statement
*es
= new expr_statement
;
4054 es
->value
= e
->args
[i
];
4055 es
->tok
= es
->value
->tok
;
4056 b
->statements
.push_back(es
);
4066 void_statement_reducer::visit_print_format (print_format
* e
)
4068 // When an sprint's return value is ignored, we can simply evaluate the
4069 // arguments in sequence
4071 if (e
->print_to_stream
|| !e
->args
.size())
4077 if (session
.verbose
>2)
4078 clog
<< _("Eliding unused print ") << *e
->tok
<< endl
;
4080 block
*b
= new block
;
4083 for (unsigned i
=0; i
<e
->args
.size(); i
++ )
4085 expr_statement
*es
= new expr_statement
;
4086 es
->value
= e
->args
[i
];
4087 es
->tok
= es
->value
->tok
;
4088 b
->statements
.push_back(es
);
4098 void_statement_reducer::reduce_target_symbol (target_symbol
* e
,
4099 expression
* operand
)
4101 // When the result of any target_symbol isn't needed, it's just as good to
4102 // evaluate the operand and any array indexes directly
4104 block
*b
= new block
;
4109 expr_statement
*es
= new expr_statement
;
4110 es
->value
= operand
;
4111 es
->tok
= es
->value
->tok
;
4112 b
->statements
.push_back(es
);
4115 for (unsigned i
=0; i
<e
->components
.size(); i
++ )
4117 if (e
->components
[i
].type
!= target_symbol::comp_expression_array_index
)
4120 expr_statement
*es
= new expr_statement
;
4121 es
->value
= e
->components
[i
].expr_index
;
4122 es
->tok
= es
->value
->tok
;
4123 b
->statements
.push_back(es
);
4133 void_statement_reducer::visit_atvar_op (atvar_op
* e
)
4135 if (session
.verbose
>2)
4136 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
4137 reduce_target_symbol (e
);
4141 void_statement_reducer::visit_target_symbol (target_symbol
* e
)
4143 if (session
.verbose
>2)
4144 clog
<< _("Eliding unused target symbol ") << *e
->tok
<< endl
;
4145 reduce_target_symbol (e
);
4149 void_statement_reducer::visit_cast_op (cast_op
* e
)
4151 if (session
.verbose
>2)
4152 clog
<< _("Eliding unused typecast ") << *e
->tok
<< endl
;
4153 reduce_target_symbol (e
, e
->operand
);
4157 void_statement_reducer::visit_autocast_op (autocast_op
* e
)
4159 if (session
.verbose
>2)
4160 clog
<< _("Eliding unused autocast ") << *e
->tok
<< endl
;
4161 reduce_target_symbol (e
, e
->operand
);
4166 void_statement_reducer::visit_defined_op (defined_op
* e
)
4168 // When the result of a @defined operation isn't needed, just elide
4169 // it entirely. Its operand $expression must already be
4170 // side-effect-free.
4172 if (session
.verbose
>2)
4173 clog
<< _("Eliding unused check ") << *e
->tok
<< endl
;
4180 void semantic_pass_opt5 (systemtap_session
& s
, bool& relaxed_p
)
4182 // Let's simplify statements with unused computed values.
4184 void_statement_reducer
vuv (s
, relaxed_p
);
4185 // This instance may be reused for multiple probe/function body trims.
4187 vuv
.focal_vars
.insert (s
.globals
.begin(), s
.globals
.end());
4189 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4190 vuv
.replace (s
.probes
[i
]->body
);
4191 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4192 it
!= s
.functions
.end(); it
++)
4193 vuv
.replace (it
->second
->body
);
4199 const_folder::get_literal(expression
*& e
,
4204 n
= (e
== last_number
) ? last_number
: NULL
;
4205 s
= (e
== last_string
) ? last_string
: NULL
;
4209 const_folder::get_number(expression
*& e
)
4212 return (e
== last_number
) ? last_number
: NULL
;
4216 const_folder::visit_literal_number (literal_number
* e
)
4223 const_folder::get_string(expression
*& e
)
4226 return (e
== last_string
) ? last_string
: NULL
;
4230 const_folder::visit_literal_string (literal_string
* e
)
4237 const_folder::visit_if_statement (if_statement
* s
)
4239 literal_number
* cond
= get_number (s
->condition
);
4242 replace (s
->thenblock
);
4243 replace (s
->elseblock
);
4248 if (session
.verbose
>2)
4249 clog
<< _F("Collapsing constant-%" PRIi64
" if-statement %s",
4250 cond
->value
, lex_cast(*s
->tok
).c_str()) << endl
;
4253 statement
* n
= cond
->value
? s
->thenblock
: s
->elseblock
;
4257 provide (new null_statement (s
->tok
));
4262 const_folder::visit_for_loop (for_loop
* s
)
4264 literal_number
* cond
= get_number (s
->cond
);
4265 if (!cond
|| cond
->value
)
4274 if (session
.verbose
>2)
4275 clog
<< _("Collapsing constantly-false for-loop ") << *s
->tok
<< endl
;
4279 s
->init
->visit (this);
4281 provide (new null_statement (s
->tok
));
4286 const_folder::visit_foreach_loop (foreach_loop
* s
)
4288 literal_number
* limit
= get_number (s
->limit
);
4289 if (!limit
|| limit
->value
> 0)
4291 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
4292 replace (s
->indexes
[i
]);
4300 if (session
.verbose
>2)
4301 clog
<< _("Collapsing constantly-limited foreach-loop ") << *s
->tok
<< endl
;
4304 provide (new null_statement (s
->tok
));
4309 const_folder::visit_binary_expression (binary_expression
* e
)
4312 literal_number
* left
= get_number (e
->left
);
4313 literal_number
* right
= get_number (e
->right
);
4315 if (right
&& !right
->value
&& (e
->op
== "/" || e
->op
== "%"))
4317 // Give divide-by-zero a chance to be optimized out elsewhere,
4318 // and if not it will be a runtime error anyway...
4326 value
= left
->value
+ right
->value
;
4327 else if (e
->op
== "-")
4328 value
= left
->value
- right
->value
;
4329 else if (e
->op
== "*")
4330 value
= left
->value
* right
->value
;
4331 else if (e
->op
== "&")
4332 value
= left
->value
& right
->value
;
4333 else if (e
->op
== "|")
4334 value
= left
->value
| right
->value
;
4335 else if (e
->op
== "^")
4336 value
= left
->value
^ right
->value
;
4337 else if (e
->op
== ">>")
4338 value
= left
->value
>> max(min(right
->value
, (int64_t)64), (int64_t)0);
4339 else if (e
->op
== "<<")
4340 value
= left
->value
<< max(min(right
->value
, (int64_t)64), (int64_t)0);
4341 else if (e
->op
== "/")
4342 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? LLONG_MIN
:
4343 left
->value
/ right
->value
;
4344 else if (e
->op
== "%")
4345 value
= (left
->value
== LLONG_MIN
&& right
->value
== -1) ? 0 :
4346 left
->value
% right
->value
;
4348 throw SEMANTIC_ERROR (_("unsupported binary operator ") + (string
)e
->op
);
4351 else if ((left
&& ((left
->value
== 0 && (e
->op
== "*" || e
->op
== "&" ||
4352 e
->op
== ">>" || e
->op
== "<<" )) ||
4353 (left
->value
==-1 && (e
->op
== "|" || e
->op
== ">>"))))
4355 (right
&& ((right
->value
== 0 && (e
->op
== "*" || e
->op
== "&")) ||
4356 (right
->value
== 1 && (e
->op
== "%")) ||
4357 (right
->value
==-1 && (e
->op
== "%" || e
->op
== "|")))))
4359 expression
* other
= left
? e
->right
: e
->left
;
4360 varuse_collecting_visitor
vu(session
);
4362 if (!vu
.side_effect_free())
4368 // we'll pass on type=pe_long inference to the expression
4369 if (other
->type
== pe_unknown
)
4370 other
->type
= pe_long
;
4371 else if (other
->type
!= pe_long
)
4373 // this mismatch was not caught in the initial type resolution pass,
4374 // generate a mismatch (left doesn't match right) error
4375 typeresolution_info
ti(session
);
4376 ti
.assert_resolvability
= true; // need this to get it throw errors
4377 ti
.mismatch_complexity
= 1; // also needed to throw errors
4382 value
= left
->value
;
4383 else if (e
->op
== "%")
4386 value
= right
->value
;
4389 else if ((left
&& ((left
->value
== 0 && (e
->op
== "+" || e
->op
== "|" ||
4391 (left
->value
== 1 && (e
->op
== "*")) ||
4392 (left
->value
==-1 && (e
->op
== "&"))))
4394 (right
&& ((right
->value
== 0 && (e
->op
== "+" || e
->op
== "-" ||
4395 e
->op
== "|" || e
->op
== "^")) ||
4396 (right
->value
== 1 && (e
->op
== "*" || e
->op
== "/")) ||
4397 (right
->value
==-1 && (e
->op
== "&")) ||
4398 (right
->value
<= 0 && (e
->op
== ">>" || e
->op
== "<<")))))
4400 if (session
.verbose
>2)
4401 clog
<< _("Collapsing constant-identity binary operator ") << *e
->tok
<< endl
;
4404 // we'll pass on type=pe_long inference to the expression
4405 expression
* other
= left
? e
->right
: e
->left
;
4406 if (other
->type
== pe_unknown
)
4407 other
->type
= pe_long
;
4408 else if (other
->type
!= pe_long
)
4410 // this mismatch was not caught in the initial type resolution pass,
4411 // generate a mismatch (left doesn't match right) error
4412 typeresolution_info
ti(session
);
4413 ti
.assert_resolvability
= true; // need this to get it throw errors
4414 ti
.mismatch_complexity
= 1; // also needed to throw errors
4428 if (session
.verbose
>2)
4429 clog
<< _F("Collapsing constant-%" PRIi64
" binary operator %s",
4430 value
, lex_cast(*e
->tok
).c_str()) << endl
;
4433 literal_number
* n
= new literal_number(value
);
4439 const_folder::visit_unary_expression (unary_expression
* e
)
4441 literal_number
* operand
= get_number (e
->operand
);
4446 if (session
.verbose
>2)
4447 clog
<< _("Collapsing constant unary ") << *e
->tok
<< endl
;
4450 literal_number
* n
= new literal_number (*operand
);
4454 else if (e
->op
== "-")
4455 n
->value
= -n
->value
;
4456 else if (e
->op
== "!")
4457 n
->value
= !n
->value
;
4458 else if (e
->op
== "~")
4459 n
->value
= ~n
->value
;
4461 throw SEMANTIC_ERROR (_("unsupported unary operator ") + (string
)e
->op
);
4467 const_folder::visit_logical_or_expr (logical_or_expr
* e
)
4470 literal_number
* left
= get_number (e
->left
);
4471 literal_number
* right
= get_number (e
->right
);
4474 value
= left
->value
|| right
->value
;
4476 else if ((left
&& left
->value
) || (right
&& right
->value
))
4478 // If the const is on the left, we get to short-circuit the right
4479 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
4482 varuse_collecting_visitor
vu(session
);
4483 e
->left
->visit(&vu
);
4484 if (!vu
.side_effect_free())
4494 // We might also get rid of useless "0||x" and "x||0", except it does
4495 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
4496 // that this would gain us much.
4504 if (session
.verbose
>2)
4505 clog
<< _("Collapsing constant logical-OR ") << *e
->tok
<< endl
;
4508 literal_number
* n
= new literal_number(value
);
4514 const_folder::visit_logical_and_expr (logical_and_expr
* e
)
4517 literal_number
* left
= get_number (e
->left
);
4518 literal_number
* right
= get_number (e
->right
);
4521 value
= left
->value
&& right
->value
;
4523 else if ((left
&& !left
->value
) || (right
&& !right
->value
))
4525 // If the const is on the left, we get to short-circuit the right
4526 // immediately. Otherwise, we can only eliminate the LHS if it's pure.
4529 varuse_collecting_visitor
vu(session
);
4530 e
->left
->visit(&vu
);
4531 if (!vu
.side_effect_free())
4541 // We might also get rid of useless "1&&x" and "x&&1", except it does
4542 // normalize x to 0 or 1. We could change it to "!!x", but it's not clear
4543 // that this would gain us much.
4551 if (session
.verbose
>2)
4552 clog
<< _("Collapsing constant logical-AND ") << *e
->tok
<< endl
;
4555 literal_number
* n
= new literal_number(value
);
4561 const_folder::visit_compound_expression (compound_expression
* e
)
4563 replace(e
->left
, true);
4564 replace(e
->right
, false);
4566 // If the LHS is pure, we can eliminate it.
4567 // ??? This is unlikely, given how these are created in loc2stap.cxx.
4570 varuse_collecting_visitor
vu(session
);
4571 e
->left
->visit(&vu
);
4572 if (!vu
.side_effect_free())
4579 if (session
.verbose
> 2)
4580 clog
<< _("Collapsing compound expression") << *e
->tok
<< endl
;
4586 const_folder::visit_comparison (comparison
* e
)
4590 literal_number
*left_num
, *right_num
;
4591 literal_string
*left_str
, *right_str
;
4592 get_literal(e
->left
, left_num
, left_str
);
4593 get_literal(e
->right
, right_num
, right_str
);
4595 if (left_str
&& right_str
)
4596 comp
= left_str
->value
.compare(right_str
->value
);
4598 else if (left_num
&& right_num
)
4599 comp
= left_num
->value
< right_num
->value
? -1 :
4600 left_num
->value
> right_num
->value
? 1 : 0;
4602 else if ((left_num
&& ((left_num
->value
== LLONG_MIN
&&
4603 (e
->op
== "<=" || e
->op
== ">")) ||
4604 (left_num
->value
== LLONG_MAX
&&
4605 (e
->op
== ">=" || e
->op
== "<"))))
4607 (right_num
&& ((right_num
->value
== LLONG_MIN
&&
4608 (e
->op
== ">=" || e
->op
== "<")) ||
4609 (right_num
->value
== LLONG_MAX
&&
4610 (e
->op
== "<=" || e
->op
== ">")))))
4612 expression
* other
= left_num
? e
->right
: e
->left
;
4613 varuse_collecting_visitor
vu(session
);
4615 if (!vu
.side_effect_free())
4619 if (session
.verbose
>2)
4620 clog
<< _("Collapsing constant-boundary comparison ") << *e
->tok
<< endl
;
4623 // ops <= and >= are true, < and > are false
4624 literal_number
* n
= new literal_number( e
->op
.length() == 2 );
4637 if (session
.verbose
>2)
4638 clog
<< _("Collapsing constant comparison ") << *e
->tok
<< endl
;
4644 else if (e
->op
== "!=")
4646 else if (e
->op
== "<")
4648 else if (e
->op
== ">")
4650 else if (e
->op
== "<=")
4652 else if (e
->op
== ">=")
4655 throw SEMANTIC_ERROR (_("unsupported comparison operator ") + (string
)e
->op
);
4657 literal_number
* n
= new literal_number(value
);
4663 const_folder::visit_concatenation (concatenation
* e
)
4665 literal_string
* left
= get_string (e
->left
);
4666 literal_string
* right
= get_string (e
->right
);
4670 if (session
.verbose
>2)
4671 clog
<< _("Collapsing constant concatenation ") << *e
->tok
<< endl
;
4674 literal_string
* n
= new literal_string (*left
);
4676 n
->value
= (string
)n
->value
+ (string
)right
->value
;
4679 else if ((left
&& left
->value
.empty()) ||
4680 (right
&& right
->value
.empty()))
4682 if (session
.verbose
>2)
4683 clog
<< _("Collapsing identity concatenation ") << *e
->tok
<< endl
;
4685 provide(left
? e
->right
: e
->left
);
4692 const_folder::visit_ternary_expression (ternary_expression
* e
)
4694 literal_number
* cond
= get_number (e
->cond
);
4697 replace (e
->truevalue
);
4698 replace (e
->falsevalue
);
4703 if (session
.verbose
>2)
4704 clog
<< _F("Collapsing constant-%" PRIi64
" ternary %s",
4705 cond
->value
, lex_cast(*e
->tok
).c_str()) << endl
;
4708 expression
* n
= cond
->value
? e
->truevalue
: e
->falsevalue
;
4714 const_folder::visit_defined_op (defined_op
* e
)
4716 // If a @defined makes it this far, then it was not resolved by
4717 // previous efforts. We could assume that therefore it is a big fat
4718 // zero, but for the @defined(autocast) case PR18079, this just
4719 // means that we didn't know yet.
4721 bool collapse_this
= false;
4723 /* PR20672: not true; we run a const_folder iteratively during
4724 initial probe body variable-expansion, when other @defined()s may
4725 be as-yet-unprocessed. We can't presume to map them to zero.
4727 // We do know that plain target_symbols aren't going anywhere though.
4728 if (get_target_symbol (e->operand))
4730 if (session.verbose>2)
4731 clog << _("Collapsing target_symbol @defined check ") << *e->tok << endl;
4732 collapse_this = true;
4736 if (collapse_defines_p
&& relaxed_p
)
4738 if (session
.verbose
>2)
4739 clog
<< _("Collapsing untouched @defined check ") << *e
->tok
<< endl
;
4741 // If we got to an expression with a known type, call it defined.
4742 if (e
->operand
->type
!= pe_unknown
)
4744 collapse_this
= true;
4749 // Don't be greedy... we'll only collapse one at a time so type
4750 // resolution can have another go at it.
4752 literal_number
* n
= new literal_number (value
);
4758 if (session
.verbose
>2)
4759 clog
<< _("Preserving unresolved @defined check ") << *e
->tok
<< endl
;
4765 const_folder::get_target_symbol(expression
*& e
)
4768 return (e
== last_target_symbol
) ? last_target_symbol
: NULL
;
4772 const_folder::visit_target_symbol (target_symbol
* e
)
4774 if (collapse_defines_p
&& session
.skip_badvars
)
4776 // Upon user request for ignoring context, the symbol is replaced
4777 // with a literal 0 and a warning message displayed
4778 // ... but don't do this during early runs of the const_folder, only
4779 // during the final (collapse_defines_p) one. (Otherwise, during
4780 // a dwarf_var "@defined($foo) ? $foo : 0", the inner $foo could
4781 // get premature mapping to 0.
4783 // XXX this ignores possible side-effects, e.g. in array indexes
4784 literal_number
* ln_zero
= new literal_number (0);
4785 ln_zero
->tok
= e
->tok
;
4787 session
.print_warning (_("Bad $context variable being substituted with literal 0"),
4793 update_visitor::visit_target_symbol (e
);
4794 last_target_symbol
= e
;
4798 static int initial_typeres_pass(systemtap_session
& s
);
4799 static int semantic_pass_const_fold (systemtap_session
& s
, bool& relaxed_p
)
4801 // attempt an initial type resolution pass to see if there are any type
4802 // mismatches before we starting whisking away vars that get switched out
4805 // return if the initial type resolution pass reported errors (type mismatches)
4806 int rc
= initial_typeres_pass(s
);
4813 // Let's simplify statements with constant values.
4814 const_folder
cf (s
, relaxed_p
, true /* collapse remaining @defined()->0 now */ );
4815 // This instance may be reused for multiple probe/function body trims.
4817 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4818 cf
.replace (s
.probes
[i
]->body
);
4819 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4820 it
!= s
.functions
.end(); it
++)
4821 cf
.replace (it
->second
->body
);
4826 struct dead_control_remover
: public traversing_visitor
4828 systemtap_session
& session
;
4832 dead_control_remover(systemtap_session
& s
, bool& r
):
4833 session(s
), relaxed_p(r
), control(NULL
) {}
4835 void visit_block (block
*b
);
4837 // When a block contains any of these, the following statements are dead.
4838 void visit_return_statement (return_statement
* s
) { control
= s
; }
4839 void visit_next_statement (next_statement
* s
) { control
= s
; }
4840 void visit_break_statement (break_statement
* s
) { control
= s
; }
4841 void visit_continue_statement (continue_statement
* s
) { control
= s
; }
4845 void dead_control_remover::visit_block (block
* b
)
4847 vector
<statement
*>& vs
= b
->statements
;
4848 if (vs
.size() == 0) /* else (size_t) size()-1 => very big */
4850 for (size_t i
= 0; i
< vs
.size() - 1; ++i
)
4852 vs
[i
]->visit (this);
4853 if (vs
[i
] == control
)
4855 session
.print_warning(_("statement will never be reached"),
4857 vs
.erase(vs
.begin() + i
+ 1, vs
.end());
4865 static void semantic_pass_dead_control (systemtap_session
& s
, bool& relaxed_p
)
4867 // Let's remove code that follow unconditional control statements
4869 dead_control_remover
dc (s
, relaxed_p
);
4871 for (unsigned i
=0; i
<s
.probes
.size(); i
++)
4872 s
.probes
[i
]->body
->visit(&dc
);
4874 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
4875 it
!= s
.functions
.end(); it
++)
4876 it
->second
->body
->visit(&dc
);
4880 // Looks for next statements in function declarations and marks
4882 struct function_next_check
: public traversing_visitor
4884 functiondecl
* current_function
;
4886 function_next_check()
4887 : current_function(0) { }
4889 void visit_next_statement(next_statement
*)
4891 current_function
->has_next
= true;
4894 void visit_embeddedcode(embeddedcode
* s
)
4896 if (s
->code
.find("STAP_NEXT;") != string::npos
)
4897 current_function
->has_next
= true;
4901 struct dead_overload_remover
: public traversing_visitor
4903 systemtap_session
& s
;
4906 dead_overload_remover(systemtap_session
& sess
,
4908 : s(sess
), relaxed_p(r
) { }
4910 void visit_functioncall(functioncall
* e
);
4913 void dead_overload_remover::visit_functioncall(functioncall
*e
)
4915 unsigned reachable
= 1;
4916 bool chained
= true;
4918 for (unsigned fd
= 0; fd
< e
->referents
.size(); fd
++)
4920 functiondecl
* r
= e
->referents
[fd
];
4922 // Note that this is not a sound inference but it suffices for most
4923 // cases. It may be the case that there is a 'next' statement in the
4924 // function that will never be executed by the control flow.
4925 // We simply use the presence of a 'next' statement as an indicator
4926 // of a potential fall through. Once a function can't be 'nexted' the
4927 // remaining functions are unreachable.
4928 if (chained
&& r
->has_next
)
4934 if (reachable
< e
->referents
.size())
4936 for (unsigned fd
= reachable
; fd
< e
->referents
.size(); fd
++)
4938 functiondecl
* r
= e
->referents
[fd
];
4939 s
.print_warning(_("instance of overloaded function will "
4940 "never be reached"), r
->tok
);
4942 e
->referents
.erase(e
->referents
.begin()+reachable
, e
->referents
.end());
4947 static void semantic_pass_overload(systemtap_session
& s
, bool& relaxed_p
)
4949 set
<functiondecl
*> function_next
;
4950 function_next_check fnc
;
4952 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); ++it
)
4954 functiondecl
* fn
= it
->second
;
4955 fnc
.current_function
= fn
;
4956 fn
->body
->visit(&fnc
);
4959 for (auto it
= s
.probes
.begin(); it
!= s
.probes
.end(); ++it
)
4961 dead_overload_remover
ovr(s
, relaxed_p
);
4962 (*it
)->body
->visit(&ovr
);
4965 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); ++it
)
4967 dead_overload_remover
ovr(s
, relaxed_p
);
4968 it
->second
->body
->visit(&ovr
);
4973 struct duplicate_function_remover
: public functioncall_traversing_visitor
4975 systemtap_session
& s
;
4976 map
<functiondecl
*, functiondecl
*>& duplicate_function_map
;
4978 duplicate_function_remover(systemtap_session
& sess
,
4979 map
<functiondecl
*, functiondecl
*>&dfm
):
4980 s(sess
), duplicate_function_map(dfm
) {};
4982 void visit_functioncall (functioncall
* e
);
4986 duplicate_function_remover::visit_functioncall (functioncall
*e
)
4988 functioncall_traversing_visitor::visit_functioncall (e
);
4990 // If any of the current function call references points to a function that
4991 // is a duplicate, replace it.
4992 for (unsigned i
= 0; i
< e
->referents
.size(); i
++)
4994 functiondecl
* referent
= e
->referents
[i
];
4995 if (duplicate_function_map
.count(referent
) != 0)
4998 clog
<< _F("Changing %s reference to %s reference\n",
4999 referent
->unmangled_name
.to_string().c_str(),
5000 duplicate_function_map
[referent
]->unmangled_name
.to_string().c_str());
5001 e
->tok
= duplicate_function_map
[referent
]->tok
;
5002 e
->function
= duplicate_function_map
[referent
]->name
;
5003 e
->referents
[i
] = duplicate_function_map
[referent
];
5009 get_functionsig (functiondecl
* f
)
5013 // Get the "name:args body" of the function in s. We have to
5014 // include the args since the function 'x1(a, b)' is different than
5015 // the function 'x2(b, a)' even if the bodies of the two functions
5016 // are exactly the same.
5020 // printsig puts f->name + ':' on the front. Remove this
5021 // (otherwise, functions would never compare equal).
5022 string str
= s
.str().erase(0, f
->unmangled_name
.size() + 1);
5024 // Return the function signature.
5028 void semantic_pass_opt6 (systemtap_session
& s
, bool& relaxed_p
)
5030 // Walk through all the functions, looking for duplicates.
5031 map
<string
, functiondecl
*> functionsig_map
;
5032 map
<functiondecl
*, functiondecl
*> duplicate_function_map
;
5035 vector
<functiondecl
*> newly_zapped_functions
;
5036 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin(); it
!= s
.functions
.end(); it
++)
5038 functiondecl
*fd
= it
->second
;
5039 string functionsig
= get_functionsig(fd
);
5041 if (functionsig_map
.count(functionsig
) == 0)
5043 // This function is unique. Remember it.
5044 functionsig_map
[functionsig
] = fd
;
5048 // This function is a duplicate.
5049 duplicate_function_map
[fd
] = functionsig_map
[functionsig
];
5050 newly_zapped_functions
.push_back (fd
);
5054 for (unsigned i
=0; i
<newly_zapped_functions
.size(); i
++)
5056 map
<string
,functiondecl
*>::iterator where
= s
.functions
.find (newly_zapped_functions
[i
]->name
);
5057 assert (where
!= s
.functions
.end());
5058 s
.functions
.erase (where
);
5062 // If we have duplicate functions, traverse down the tree, replacing
5063 // the appropriate function calls.
5064 // duplicate_function_remover::visit_functioncall() handles the
5065 // details of replacing the function calls.
5066 if (duplicate_function_map
.size() != 0)
5068 duplicate_function_remover
dfr (s
, duplicate_function_map
);
5070 for (unsigned i
=0; i
< s
.probes
.size(); i
++)
5071 s
.probes
[i
]->body
->visit(&dfr
);
5075 struct stable_analysis
: public nop_visitor
5078 stable_analysis(): stable(false) {};
5080 void visit_embeddedcode (embeddedcode
* s
);
5083 void stable_analysis::visit_embeddedcode (embeddedcode
* s
)
5085 if (s
->tagged_p("/* stable */"))
5087 if (stable
&& !s
->tagged_p("/* pure */"))
5088 throw SEMANTIC_ERROR(_("stable function must also be /* pure */"),
5092 // Examines entire subtree for any stable functioncalls.
5093 struct stable_finder
: public traversing_visitor
5096 set
<string
>& stable_fcs
;
5097 stable_finder(set
<string
>&s
): stable(false), stable_fcs(s
) {};
5098 void visit_functioncall (functioncall
* e
);
5101 void stable_finder::visit_functioncall (functioncall
* e
)
5103 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
5105 traversing_visitor::visit_functioncall(e
);
5108 // Examines current level of block for stable functioncalls.
5109 // Does not descend into sublevels.
5110 struct level_check
: public traversing_visitor
5113 set
<string
>& stable_fcs
;
5114 level_check(set
<string
>& s
): stable(false), stable_fcs(s
) {};
5116 void visit_block (block
* s
);
5117 void visit_try_block (try_block
*s
);
5118 void visit_if_statement (if_statement
* s
);
5119 void visit_for_loop (for_loop
* s
);
5120 void visit_foreach_loop (foreach_loop
* s
);
5121 void visit_functioncall (functioncall
* s
);
5124 void level_check::visit_block (block
*)
5128 void level_check::visit_try_block (try_block
* s
)
5130 if (s
->catch_error_var
)
5131 s
->catch_error_var
->visit(this);
5134 void level_check::visit_if_statement (if_statement
* s
)
5136 s
->condition
->visit(this);
5139 void level_check::visit_for_loop (for_loop
* s
)
5141 if (s
->init
) s
->init
->visit(this);
5142 s
->cond
->visit(this);
5143 if (s
->incr
) s
->incr
->visit(this);
5146 void level_check::visit_foreach_loop (foreach_loop
* s
)
5148 s
->base
->visit(this);
5150 for (unsigned i
=0; i
<s
->indexes
.size(); i
++)
5151 s
->indexes
[i
]->visit(this);
5154 s
->value
->visit(this);
5157 s
->limit
->visit(this);
5160 void level_check::visit_functioncall (functioncall
* e
)
5162 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
5164 traversing_visitor::visit_functioncall(e
);
5167 struct stable_functioncall_visitor
: public update_visitor
5169 systemtap_session
& session
;
5170 functiondecl
* current_function
;
5171 derived_probe
* current_probe
;
5172 set
<string
>& stable_fcs
;
5173 set
<string
> scope_vars
;
5174 map
<string
,vardecl
*> new_vars
;
5175 vector
<pair
<expr_statement
*,block
*> > new_stmts
;
5176 unsigned loop_depth
;
5179 stable_functioncall_visitor(systemtap_session
& s
, set
<string
>& sfc
):
5180 update_visitor(s
.verbose
),
5181 session(s
), current_function(0), current_probe(0), stable_fcs(sfc
),
5182 loop_depth(0), top_scope(0), curr_scope(0) {};
5184 statement
* convert_stmt(statement
* s
);
5185 void visit_block (block
* s
);
5186 void visit_try_block (try_block
* s
);
5187 void visit_if_statement (if_statement
* s
);
5188 void visit_for_loop (for_loop
* s
);
5189 void visit_foreach_loop (foreach_loop
* s
);
5190 void visit_functioncall (functioncall
* e
);
5193 statement
* stable_functioncall_visitor::convert_stmt (statement
* s
)
5195 if (top_scope
== 0 &&
5196 (dynamic_cast<for_loop
*>(s
) || dynamic_cast<foreach_loop
*>(s
)))
5198 stable_finder
sf(stable_fcs
);
5202 block
* b
= new block
;
5204 b
->statements
.push_back(s
);
5208 else if (top_scope
== 0 && !dynamic_cast<block
*>(s
))
5210 level_check
lc(stable_fcs
);
5214 block
* b
= new block
;
5216 b
->statements
.push_back(s
);
5224 void stable_functioncall_visitor::visit_block (block
* s
)
5226 block
* prev_top_scope
= top_scope
;
5227 block
* prev_scope
= curr_scope
;
5228 if (loop_depth
== 0)
5231 set
<string
> current_vars
= scope_vars
;
5233 update_visitor::visit_block(s
);
5235 if (loop_depth
== 0)
5236 top_scope
= prev_top_scope
;
5237 curr_scope
= prev_scope
;
5238 scope_vars
= current_vars
;
5241 void stable_functioncall_visitor::visit_try_block (try_block
* s
)
5244 s
->try_block
= convert_stmt(s
->try_block
);
5245 replace(s
->try_block
);
5246 replace(s
->catch_error_var
);
5248 s
->catch_block
= convert_stmt(s
->catch_block
);
5249 replace(s
->catch_block
);
5253 void stable_functioncall_visitor::visit_if_statement (if_statement
* s
)
5255 block
* prev_top_scope
= top_scope
;
5257 if (loop_depth
== 0)
5259 replace(s
->condition
);
5260 s
->thenblock
= convert_stmt(s
->thenblock
);
5261 replace(s
->thenblock
);
5262 if (loop_depth
== 0)
5265 s
->elseblock
= convert_stmt(s
->elseblock
);
5266 replace(s
->elseblock
);
5269 top_scope
= prev_top_scope
;
5272 void stable_functioncall_visitor::visit_for_loop (for_loop
* s
)
5278 s
->block
= convert_stmt(s
->block
);
5284 void stable_functioncall_visitor::visit_foreach_loop (foreach_loop
* s
)
5286 for (unsigned i
= 0; i
< s
->indexes
.size(); ++i
)
5287 replace(s
->indexes
[i
]);
5292 s
->block
= convert_stmt(s
->block
);
5298 void stable_functioncall_visitor::visit_functioncall (functioncall
* e
)
5300 for (unsigned i
= 0; i
< e
->args
.size(); ++i
)
5301 replace (e
->args
[i
]);
5303 if (stable_fcs
.find(e
->function
) != stable_fcs
.end())
5305 string
name("__stable_");
5306 name
.append(e
->function
).append("_value");
5308 // Variable potentially not in scope since it is in a sibling block
5309 if (scope_vars
.find(e
->function
) == scope_vars
.end())
5311 if (new_vars
.find(e
->function
) == new_vars
.end())
5313 // New variable declaration to store result of function call
5314 vardecl
* v
= new vardecl
;
5315 v
->unmangled_name
= v
->name
= name
;
5317 v
->set_arity(0, e
->tok
);
5319 if (current_function
)
5320 current_function
->locals
.push_back(v
);
5322 current_probe
->locals
.push_back(v
);
5323 new_vars
[e
->function
] = v
;
5326 symbol
* sym
= new symbol
;
5329 sym
->referent
= new_vars
[e
->function
];
5330 sym
->type
= e
->type
;
5332 functioncall
* fc
= new functioncall
;
5334 fc
->function
= e
->function
;
5335 fc
->referents
= e
->referents
;
5338 assignment
* a
= new assignment
;
5345 expr_statement
* es
= new expr_statement
;
5349 // Store location of the block to put new declaration.
5350 if (loop_depth
!= 0)
5353 new_stmts
.push_back(make_pair(es
,top_scope
));
5358 new_stmts
.push_back(make_pair(es
,curr_scope
));
5361 scope_vars
.insert(e
->function
);
5367 symbol
* sym
= new symbol
;
5370 sym
->referent
= new_vars
[e
->function
];
5371 sym
->type
= e
->type
;
5380 // Cache stable embedded-c functioncall results and replace
5381 // all calls with same name using that value to reduce duplicate
5382 // functioncall overhead. Functioncalls are pulled out of any
5383 // top-level loops and put into if/try blocks.
5384 void semantic_pass_opt7(systemtap_session
& s
)
5386 set
<string
> stable_fcs
;
5387 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5388 it
!= s
.functions
.end(); ++it
)
5390 functiondecl
* fn
= (*it
).second
;
5392 fn
->body
->visit(&sa
);
5393 if (sa
.stable
&& fn
->formal_args
.size() == 0)
5394 stable_fcs
.insert(fn
->name
);
5397 for (vector
<derived_probe
*>::iterator it
= s
.probes
.begin();
5398 it
!= s
.probes
.end(); ++it
)
5400 stable_functioncall_visitor
t(s
, stable_fcs
);
5401 t
.current_probe
= *it
;
5402 (*it
)->body
= t
.convert_stmt((*it
)->body
);
5403 t
.replace((*it
)->body
);
5405 for (vector
<pair
<expr_statement
*,block
*> >::iterator st
= t
.new_stmts
.begin();
5406 st
!= t
.new_stmts
.end(); ++st
)
5407 st
->second
->statements
.insert(st
->second
->statements
.begin(), st
->first
);
5410 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5411 it
!= s
.functions
.end(); ++it
)
5413 functiondecl
* fn
= (*it
).second
;
5414 stable_functioncall_visitor
t(s
, stable_fcs
);
5415 t
.current_function
= fn
;
5416 fn
->body
= t
.convert_stmt(fn
->body
);
5417 t
.replace(fn
->body
);
5419 for (vector
<pair
<expr_statement
*,block
*> >::iterator st
= t
.new_stmts
.begin();
5420 st
!= t
.new_stmts
.end(); ++st
)
5421 st
->second
->statements
.insert(st
->second
->statements
.begin(), st
->first
);
5426 semantic_pass_optimize1 (systemtap_session
& s
)
5428 // In this pass, we attempt to rewrite probe/function bodies to
5429 // eliminate some blatantly unnecessary code. This is run before
5430 // type inference, but after symbol resolution and derived_probe
5431 // creation. We run an outer "relaxation" loop that repeats the
5432 // optimizations until none of them find anything to remove.
5436 // Save the old value of suppress_warnings, as we will be changing
5438 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
5440 bool relaxed_p
= false;
5441 unsigned iterations
= 0;
5444 assert_no_interrupts();
5446 relaxed_p
= true; // until proven otherwise
5448 // If the verbosity is high enough, always print warnings (overrides -w),
5449 // or if not, always suppress warnings for every itteration after the first.
5451 s
.suppress_warnings
= false;
5452 else if (iterations
> 0)
5453 s
.suppress_warnings
= true;
5457 semantic_pass_opt1 (s
, relaxed_p
);
5458 semantic_pass_opt2 (s
, relaxed_p
, iterations
); // produce some warnings only on iteration=0
5459 semantic_pass_opt3 (s
, relaxed_p
);
5460 semantic_pass_opt4 (s
, relaxed_p
);
5461 semantic_pass_opt5 (s
, relaxed_p
);
5464 // For listing mode, we need const-folding regardless of optimization so
5465 // that @defined expressions can be properly resolved. PR11360
5466 // We also want it in case variables are used in if/case expressions,
5467 // so enable always. PR11366
5468 // rc is incremented if there is an error that got reported.
5469 rc
+= semantic_pass_const_fold (s
, relaxed_p
);
5472 semantic_pass_dead_control (s
, relaxed_p
);
5475 semantic_pass_overload (s
, relaxed_p
);
5485 semantic_pass_optimize2 (systemtap_session
& s
)
5487 // This is run after type inference. We run an outer "relaxation"
5488 // loop that repeats the optimizations until none of them find
5489 // anything to remove.
5493 // Save the old value of suppress_warnings, as we will be changing
5495 save_and_restore
<bool> suppress_warnings(& s
.suppress_warnings
);
5497 bool relaxed_p
= false;
5498 unsigned iterations
= 0;
5501 assert_no_interrupts();
5502 relaxed_p
= true; // until proven otherwise
5504 // If the verbosity is high enough, always print warnings (overrides -w),
5505 // or if not, always suppress warnings for every itteration after the first.
5507 s
.suppress_warnings
= false;
5508 else if (iterations
> 0)
5509 s
.suppress_warnings
= true;
5512 semantic_pass_opt6 (s
, relaxed_p
);
5518 semantic_pass_opt7(s
);
5525 // ------------------------------------------------------------------------
5528 struct autocast_expanding_visitor
: public var_expanding_visitor
5530 typeresolution_info
& ti
;
5531 autocast_expanding_visitor (systemtap_session
& s
, typeresolution_info
& ti
):
5532 var_expanding_visitor(s
), ti(ti
) {}
5534 void resolve_functioncall (functioncall
* fc
)
5536 // This is a very limited version of semantic_pass_symbols, but
5537 // we're late in the game at this point (after basic symbol
5538 // resolution already took place). We won't get a chance to
5539 // optimize, but for now the only functions we expect are
5540 // kernel/user_string from pretty-printing, which don't need
5543 systemtap_session
& s
= ti
.session
;
5544 size_t nfiles
= s
.files
.size();
5546 symresolution_info
sym (s
);
5547 sym
.current_function
= ti
.current_function
;
5548 sym
.current_probe
= ti
.current_probe
;
5551 // NB: synthetic functions get tacked onto the origin file, so we won't
5552 // see them growing s.files[]. Traverse it directly.
5553 for (unsigned i
= 0; i
< fc
->referents
.size(); i
++)
5555 functiondecl
* fd
= fc
->referents
[i
];
5556 sym
.current_function
= fd
;
5557 sym
.current_probe
= 0;
5558 fd
->body
->visit (&sym
);
5561 while (nfiles
< s
.files
.size())
5563 stapfile
* dome
= s
.files
[nfiles
++];
5564 for (size_t i
= 0; i
< dome
->functions
.size(); ++i
)
5566 functiondecl
* fd
= dome
->functions
[i
];
5567 sym
.current_function
= fd
;
5568 sym
.current_probe
= 0;
5569 fd
->body
->visit (&sym
);
5570 // NB: not adding to s.functions just yet...
5574 // Add only the direct functions we need.
5575 functioncall_traversing_visitor ftv
;
5577 for (set
<functiondecl
*>::iterator it
= ftv
.seen
.begin();
5578 it
!= ftv
.seen
.end(); ++it
)
5580 functiondecl
* fd
= *it
;
5581 pair
<map
<string
,functiondecl
*>::iterator
,bool> inserted
=
5582 s
.functions
.insert (make_pair (fd
->name
, fd
));
5583 if (!inserted
.second
&& inserted
.first
->second
!= fd
)
5584 throw SEMANTIC_ERROR
5585 (_F("resolved function '%s' conflicts with an existing function",
5586 fd
->unmangled_name
.to_string().c_str()), fc
->tok
);
5590 void visit_autocast_op (autocast_op
* e
)
5592 const bool lvalue
= is_active_lvalue (e
);
5593 const exp_type_ptr
& details
= e
->operand
->type_details
;
5594 if (details
&& !e
->saved_conversion_error
)
5596 functioncall
* fc
= details
->expand (e
, lvalue
);
5599 ti
.num_newly_resolved
++;
5601 resolve_functioncall (fc
);
5602 // NB: at this stage, the functioncall object has one
5603 // argument too few if we're in lvalue context. It will
5604 // be filled in only later (as the
5605 // var_expanding_visitor::visit_assignment bit rolls
5606 // back up). But nevertheless we must resolve the fc,
5607 // otherwise, symresolution_info::visit_functioncall will
5608 // throw a mismatched-arity error. (semok/autocast08.stp)
5611 provide_lvalue_call (fc
);
5617 var_expanding_visitor::visit_autocast_op (e
);
5622 struct initial_typeresolution_info
: public typeresolution_info
5624 initial_typeresolution_info (systemtap_session
& s
): typeresolution_info(s
)
5627 // these expressions are not supposed to make its way to the typeresolution
5628 // pass. they probably get substituted/replaced, but since this is an initial pass
5629 // and not all substitutions are done, replace the functions that throw errors.
5630 void visit_target_symbol (target_symbol
*) {}
5631 void visit_atvar_op (atvar_op
*) {}
5632 void visit_defined_op (defined_op
*) {}
5633 void visit_entry_op (entry_op
*) {}
5634 void visit_cast_op (cast_op
*) {}
5637 static int initial_typeres_pass(systemtap_session
& s
)
5639 // minimal type resolution based off of semantic_pass_types(), without
5640 // checking for complete type resolutions or autocast expanding
5641 initial_typeresolution_info
ti(s
);
5643 // Globals never have detailed types.
5644 // If we null them now, then all remaining vardecls can be detailed.
5645 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
5647 vardecl
* gd
= s
.globals
[j
];
5648 if (!gd
->type_details
)
5649 gd
->type_details
= ti
.null_type
;
5652 ti
.assert_resolvability
= false;
5655 assert_no_interrupts();
5657 ti
.num_newly_resolved
= 0;
5658 ti
.num_still_unresolved
= 0;
5659 ti
.num_available_autocasts
= 0;
5661 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5662 it
!= s
.functions
.end(); it
++)
5664 assert_no_interrupts();
5666 functiondecl
* fd
= it
->second
;
5667 ti
.current_probe
= 0;
5668 ti
.current_function
= fd
;
5670 fd
->body
->visit (& ti
);
5673 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
5675 assert_no_interrupts();
5677 derived_probe
* pn
= s
.probes
[j
];
5678 ti
.current_function
= 0;
5679 ti
.current_probe
= pn
;
5681 pn
->body
->visit (& ti
);
5683 probe_point
* pp
= pn
->sole_location();
5686 ti
.current_function
= 0;
5687 ti
.current_probe
= 0;
5688 ti
.t
= pe_long
; // NB: expected type
5689 pp
->condition
->visit (& ti
);
5692 if (ti
.num_newly_resolved
== 0) // converged
5694 // take into account that if there are mismatches, we'd want to know
5695 // about them incase they get whisked away, later in this process
5696 if (!ti
.assert_resolvability
&& ti
.mismatch_complexity
> 0) // found a mismatch!!
5698 ti
.assert_resolvability
= true; // report errors
5700 ti
.mismatch_complexity
= 1; // print out mismatched but not unresolved type mismatches
5706 ti
.mismatch_complexity
= 0;
5709 return s
.num_errors();
5713 semantic_pass_types (systemtap_session
& s
)
5717 // next pass: type inference
5718 unsigned iterations
= 0;
5719 typeresolution_info
ti (s
);
5721 // Globals never have detailed types.
5722 // If we null them now, then all remaining vardecls can be detailed.
5723 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
5725 vardecl
* gd
= s
.globals
[j
];
5726 if (!gd
->type_details
)
5727 gd
->type_details
= ti
.null_type
;
5730 ti
.assert_resolvability
= false;
5733 assert_no_interrupts();
5736 ti
.num_newly_resolved
= 0;
5737 ti
.num_still_unresolved
= 0;
5738 ti
.num_available_autocasts
= 0;
5740 for (map
<string
,functiondecl
*>::iterator it
= s
.functions
.begin();
5741 it
!= s
.functions
.end(); it
++)
5744 assert_no_interrupts();
5746 functiondecl
* fd
= it
->second
;
5747 ti
.current_probe
= 0;
5748 ti
.current_function
= fd
;
5751 fd
->body
->visit (& ti
);
5752 // NB: we don't have to assert a known type for
5753 // functions here, to permit a "void" function.
5754 // The translator phase will omit the "retvalue".
5756 // if (fd->type == pe_unknown)
5757 // ti.unresolved (fd->tok);
5758 for (unsigned i
=0; i
< fd
->locals
.size(); ++i
)
5759 ti
.check_local (fd
->locals
[i
]);
5761 // Check and run the autocast expanding visitor.
5762 if (ti
.num_available_autocasts
> 0)
5764 autocast_expanding_visitor
aev (s
, ti
);
5765 aev
.replace (fd
->body
);
5767 // PR18079, rerun the const-folder / dead-block-remover
5768 // if autocast evaluation enabled a @defined()
5769 if (! aev
.relaxed())
5771 bool relaxed_p
= true;
5772 const_folder
cf (s
, relaxed_p
);
5773 cf
.replace (fd
->body
);
5774 if (! s
.unoptimized
)
5776 dead_control_remover
dc (s
, relaxed_p
);
5777 fd
->body
->visit (&dc
);
5779 (void) relaxed_p
; // we judge success later by num_still_unresolved, not this flag
5782 ti
.num_available_autocasts
= 0;
5785 catch (const semantic_error
& e
)
5787 throw SEMANTIC_ERROR(_F("while processing function %s",
5788 it
->second
->unmangled_name
.to_string().c_str())).set_chain(e
);
5791 for (unsigned j
=0; j
<s
.probes
.size(); j
++)
5794 assert_no_interrupts();
5796 derived_probe
* pn
= s
.probes
[j
];
5797 ti
.current_function
= 0;
5798 ti
.current_probe
= pn
;
5801 pn
->body
->visit (& ti
);
5802 for (unsigned i
=0; i
< pn
->locals
.size(); ++i
)
5803 ti
.check_local (pn
->locals
[i
]);
5805 // Check and run the autocast expanding visitor.
5806 if (ti
.num_available_autocasts
> 0)
5808 autocast_expanding_visitor
aev (s
, ti
);
5809 var_expand_const_fold_loop (s
, pn
->body
, aev
);
5810 // PR18079, rerun the const-folder / dead-block-remover
5811 // if autocast evaluation enabled a @defined()
5812 if (! s
.unoptimized
)
5815 dead_control_remover
dc (s
, relaxed_p
);
5816 pn
->body
->visit (&dc
);
5817 (void) relaxed_p
; // we judge success later by num_still_unresolved, not this flag
5820 ti
.num_available_autocasts
= 0;
5823 probe_point
* pp
= pn
->sole_location();
5826 ti
.current_function
= 0;
5827 ti
.current_probe
= 0;
5828 ti
.t
= pe_long
; // NB: expected type
5829 pp
->condition
->visit (& ti
);
5832 catch (const semantic_error
& e
)
5834 throw SEMANTIC_ERROR(_F("while processing probe %s",
5835 s
.probes
[j
]->derived_locations(false).c_str())).set_chain(e
);
5838 for (unsigned j
=0; j
<s
.globals
.size(); j
++)
5840 vardecl
* gd
= s
.globals
[j
];
5841 if (gd
->type
== pe_unknown
)
5842 ti
.unresolved (gd
->tok
);
5843 if(gd
->arity
== 0 && gd
->wrap
== true)
5845 throw SEMANTIC_ERROR(_("wrapping not supported for scalars"), gd
->tok
);
5849 if (ti
.num_newly_resolved
== 0) // converged
5851 if (ti
.num_still_unresolved
== 0)
5852 break; // successfully
5853 else if (! ti
.assert_resolvability
)
5855 // PR18079, before we go asserting anything, try to nullify any
5856 // still-unresolved @defined ops.
5857 bool relaxed_p
= true;
5858 const_folder
cf (s
, relaxed_p
, true); // NB: true: collapse remaining @defined's
5860 for (auto it
= s
.probes
.begin(); it
!= s
.probes
.end(); ++it
)
5861 cf
.replace ((*it
)->body
);
5862 for (auto it
= s
.functions
.begin(); it
!= s
.functions
.end(); ++it
)
5863 cf
.replace (it
->second
->body
);
5865 if (! s
.unoptimized
)
5866 semantic_pass_dead_control (s
, relaxed_p
);
5869 ti
.mismatch_complexity
= 0; // reset for next pass
5872 ti
.assert_resolvability
= true; // last pass, with error msgs
5874 ti
.mismatch_complexity
= 0; // print every kind of mismatch
5878 { // unsuccessful conclusion
5884 ti
.mismatch_complexity
= 0; // reset for next pass
5887 return rc
+ s
.num_errors();
5891 struct exp_type_null
: public exp_type_details
5893 uintptr_t id () const { return 0; }
5894 bool expandable() const { return false; }
5895 functioncall
*expand(autocast_op
*, bool) { return NULL
; }
5898 typeresolution_info::typeresolution_info (systemtap_session
& s
):
5899 session(s
), num_newly_resolved(0), num_still_unresolved(0),
5900 num_available_autocasts(0),
5901 assert_resolvability(false), mismatch_complexity(0),
5902 current_function(0), current_probe(0), t(pe_unknown
),
5903 null_type(make_shared
<exp_type_null
>())
5909 typeresolution_info::visit_literal_number (literal_number
* e
)
5911 assert (e
->type
== pe_long
);
5912 if ((t
== e
->type
) || (t
== pe_unknown
))
5915 mismatch (e
->tok
, t
, e
->type
);
5920 typeresolution_info::visit_literal_string (literal_string
* e
)
5922 assert (e
->type
== pe_string
);
5923 if ((t
== e
->type
) || (t
== pe_unknown
))
5926 mismatch (e
->tok
, t
, e
->type
);
5931 typeresolution_info::visit_logical_or_expr (logical_or_expr
*e
)
5933 visit_binary_expression (e
);
5938 typeresolution_info::visit_logical_and_expr (logical_and_expr
*e
)
5940 visit_binary_expression (e
);
5944 typeresolution_info::visit_regex_query (regex_query
*e
)
5946 // NB: result of regex query is an integer!
5947 if (t
== pe_stats
|| t
== pe_string
)
5948 invalid (e
->tok
, t
);
5951 e
->left
->visit (this);
5953 e
->right
->visit (this); // parser ensures this is a literal known at compile time
5955 if (e
->type
== pe_unknown
)
5958 resolved (e
->tok
, e
->type
);
5963 typeresolution_info::visit_compound_expression (compound_expression
* e
)
5965 // Incoming type inference applies to the RHS.
5966 e
->right
->visit(this);
5968 // No incoming data for the LHS.
5970 e
->left
->visit(this);
5975 typeresolution_info::visit_comparison (comparison
*e
)
5977 // NB: result of any comparison is an integer!
5978 if (t
== pe_stats
|| t
== pe_string
)
5979 invalid (e
->tok
, t
);
5981 t
= (e
->right
->type
!= pe_unknown
) ? e
->right
->type
: pe_unknown
;
5982 e
->left
->visit (this);
5983 t
= (e
->left
->type
!= pe_unknown
) ? e
->left
->type
: pe_unknown
;
5984 e
->right
->visit (this);
5986 if (e
->left
->type
!= pe_unknown
&&
5987 e
->right
->type
!= pe_unknown
&&
5988 e
->left
->type
!= e
->right
->type
)
5991 if (e
->type
== pe_unknown
)
5994 resolved (e
->tok
, e
->type
);
6000 typeresolution_info::visit_concatenation (concatenation
*e
)
6002 if (t
!= pe_unknown
&& t
!= pe_string
)
6003 invalid (e
->tok
, t
);
6006 e
->left
->visit (this);
6008 e
->right
->visit (this);
6010 if (e
->type
== pe_unknown
)
6012 e
->type
= pe_string
;
6013 resolved (e
->tok
, e
->type
);
6019 typeresolution_info::visit_assignment (assignment
*e
)
6022 invalid (e
->tok
, t
);
6024 if (e
->op
== "<<<") // stats aggregation
6027 invalid (e
->tok
, t
);
6030 e
->left
->visit (this);
6032 e
->right
->visit (this);
6033 if (e
->type
== pe_unknown
||
6034 e
->type
== pe_stats
)
6037 resolved (e
->tok
, e
->type
);
6041 else if (e
->left
->type
== pe_stats
)
6042 invalid (e
->left
->tok
, e
->left
->type
);
6044 else if (e
->right
->type
== pe_stats
)
6045 invalid (e
->right
->tok
, e
->right
->type
);
6047 else if (e
->op
== "+=" || // numeric only
6059 visit_binary_expression (e
);
6061 else if (e
->op
== ".=" || // string only
6064 if (t
== pe_long
|| t
== pe_stats
)
6065 invalid (e
->tok
, t
);
6068 e
->left
->visit (this);
6070 e
->right
->visit (this);
6071 if (e
->type
== pe_unknown
)
6073 e
->type
= pe_string
;
6074 resolved (e
->tok
, e
->type
);
6077 else if (e
->op
== "=") // overloaded = for string & numeric operands
6079 // logic similar to ternary_expression
6080 exp_type sub_type
= t
;
6082 // Infer types across the l/r values
6083 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
6086 t
= (sub_type
!= pe_unknown
) ? sub_type
:
6087 (e
->right
->type
!= pe_unknown
) ? e
->right
->type
:
6089 e
->left
->visit (this);
6090 t
= (sub_type
!= pe_unknown
) ? sub_type
:
6091 (e
->left
->type
!= pe_unknown
) ? e
->left
->type
:
6093 e
->right
->visit (this);
6095 if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
6098 resolved (e
->tok
, e
->type
);
6100 if ((sub_type
== pe_unknown
) && (e
->left
->type
!= pe_unknown
))
6102 e
->type
= e
->left
->type
;
6103 resolved (e
->tok
, e
->type
);
6106 if (e
->left
->type
!= pe_unknown
&&
6107 e
->right
->type
!= pe_unknown
&&
6108 e
->left
->type
!= e
->right
->type
)
6111 // Propagate type details from the RHS to the assignment
6112 if (e
->type
== e
->right
->type
&&
6113 e
->right
->type_details
&& !e
->type_details
)
6114 resolved_details(e
->right
->type_details
, e
->type_details
);
6116 // Propagate type details from the assignment to the LHS
6117 if (e
->type
== e
->left
->type
&& e
->type_details
)
6119 if (e
->left
->type_details
&&
6120 *e
->left
->type_details
!= *e
->type_details
&&
6121 *e
->left
->type_details
!= *null_type
)
6122 resolved_details(null_type
, e
->left
->type_details
);
6123 else if (!e
->left
->type_details
)
6124 resolved_details(e
->type_details
, e
->left
->type_details
);
6128 throw SEMANTIC_ERROR (_("unsupported assignment operator ") + (string
)e
->op
);
6133 typeresolution_info::visit_embedded_expr (embedded_expr
*e
)
6135 if (e
->type
== pe_unknown
)
6137 if (e
->code
.find ("/* string */") != string::npos
)
6138 e
->type
= pe_string
;
6139 else // if (e->code.find ("/* long */") != string::npos)
6142 resolved (e
->tok
, e
->type
);
6148 typeresolution_info::visit_binary_expression (binary_expression
* e
)
6150 if (t
== pe_stats
|| t
== pe_string
)
6151 invalid (e
->tok
, t
);
6154 e
->left
->visit (this);
6156 e
->right
->visit (this);
6158 if (e
->left
->type
!= pe_unknown
&&
6159 e
->right
->type
!= pe_unknown
&&
6160 e
->left
->type
!= e
->right
->type
)
6163 if (e
->type
== pe_unknown
)
6166 resolved (e
->tok
, e
->type
);
6172 typeresolution_info::visit_pre_crement (pre_crement
*e
)
6174 visit_unary_expression (e
);
6179 typeresolution_info::visit_post_crement (post_crement
*e
)
6181 visit_unary_expression (e
);
6186 typeresolution_info::visit_unary_expression (unary_expression
* e
)
6188 if (t
== pe_stats
|| t
== pe_string
)
6189 invalid (e
->tok
, t
);
6192 e
->operand
->visit (this);
6194 if (e
->type
== pe_unknown
)
6197 resolved (e
->tok
, e
->type
);
6203 typeresolution_info::visit_ternary_expression (ternary_expression
* e
)
6205 exp_type sub_type
= t
;
6208 e
->cond
->visit (this);
6210 // Infer types across the true/false arms of the ternary expression.
6212 if (sub_type
== pe_unknown
&& e
->type
!= pe_unknown
)
6215 e
->truevalue
->visit (this);
6217 e
->falsevalue
->visit (this);
6219 if ((sub_type
== pe_unknown
) && (e
->type
!= pe_unknown
))
6220 ; // already resolved
6221 else if ((sub_type
!= pe_unknown
) && (e
->type
== pe_unknown
))
6224 resolved (e
->tok
, e
->type
);
6226 else if ((sub_type
== pe_unknown
) && (e
->truevalue
->type
!= pe_unknown
))
6228 e
->type
= e
->truevalue
->type
;
6229 resolved (e
->tok
, e
->type
);
6231 else if ((sub_type
== pe_unknown
) && (e
->falsevalue
->type
!= pe_unknown
))
6233 e
->type
= e
->falsevalue
->type
;
6234 resolved (e
->tok
, e
->type
);
6236 else if (e
->type
!= sub_type
)
6237 mismatch (e
->tok
, sub_type
, e
->type
);
6239 // Propagate type details from both true/false branches
6240 if (!e
->type_details
&&
6241 e
->type
== e
->truevalue
->type
&& e
->type
== e
->falsevalue
->type
&&
6242 e
->truevalue
->type_details
&& e
->falsevalue
->type_details
&&
6243 *e
->truevalue
->type_details
== *e
->falsevalue
->type_details
)
6244 resolved_details(e
->truevalue
->type_details
, e
->type_details
);
6248 template <class Referrer
, class Referent
>
6249 void resolve_2types (Referrer
* referrer
, Referent
* referent
,
6250 typeresolution_info
* r
, exp_type t
, bool accept_unknown
= false)
6252 exp_type
& re_type
= referrer
->type
;
6253 const token
* re_tok
= referrer
->tok
;
6254 exp_type
& te_type
= referent
->type
;
6256 if (t
!= pe_unknown
&& re_type
== t
&& re_type
== te_type
)
6257 ; // do nothing: all three e->types in agreement
6258 else if (t
== pe_unknown
&& re_type
!= pe_unknown
&& re_type
== te_type
)
6259 ; // do nothing: two known e->types in agreement
6260 else if (re_type
!= pe_unknown
&& te_type
!= pe_unknown
&& re_type
!= te_type
)
6261 r
->mismatch (re_tok
, re_type
, referent
); // referrer-referent
6262 else if (re_type
!= pe_unknown
&& t
!= pe_unknown
&& re_type
!= t
)
6263 r
->mismatch (re_tok
, t
, referent
); // referrer-t
6264 else if (te_type
!= pe_unknown
&& t
!= pe_unknown
&& te_type
!= t
)
6265 r
->mismatch (re_tok
, t
, referent
); // referent-t
6266 else if (re_type
== pe_unknown
&& t
!= pe_unknown
)
6268 // propagate from upstream
6270 r
->resolved (re_tok
, re_type
);
6271 // catch re_type/te_type mismatch later
6273 else if (re_type
== pe_unknown
&& te_type
!= pe_unknown
)
6275 // propagate from referent
6277 r
->resolved (re_tok
, re_type
);
6278 // catch re_type/t mismatch later
6280 else if (re_type
!= pe_unknown
&& te_type
== pe_unknown
)
6282 // propagate to referent
6284 r
->resolved (re_tok
, re_type
, referent
);
6285 // catch re_type/t mismatch later
6287 else if (! accept_unknown
)
6288 r
->unresolved (re_tok
);
6293 typeresolution_info::visit_symbol (symbol
* e
)
6295 if (e
->referent
== 0)
6296 throw SEMANTIC_ERROR (_F("internal error: unresolved symbol '%s'",
6297 e
->name
.to_string().c_str()), e
->tok
);
6299 resolve_2types (e
, e
->referent
, this, t
);
6301 if (e
->type
== e
->referent
->type
)
6303 // If both have type details, then they either must agree;
6304 // otherwise force them both to null.
6305 if (e
->type_details
&& e
->referent
->type_details
&&
6306 *e
->type_details
!= *e
->referent
->type_details
)
6308 resolved_details(null_type
, e
->type_details
);
6309 resolved_details(null_type
, e
->referent
->type_details
);
6311 else if (e
->type_details
&& !e
->referent
->type_details
)
6312 resolved_details(e
->type_details
, e
->referent
->type_details
);
6313 else if (!e
->type_details
&& e
->referent
->type_details
)
6314 resolved_details(e
->referent
->type_details
, e
->type_details
);
6319 typeresolution_info::visit_target_register (target_register
* e
)
6322 invalid (e
->tok
, t
);
6323 if (e
->type
== pe_unknown
)
6326 resolved (e
->tok
, e
->type
);
6331 typeresolution_info::visit_target_deref (target_deref
* e
)
6333 // Both the target_deref result as well as the address must both be longs.
6335 invalid (e
->tok
, t
);
6336 e
->addr
->visit (this);
6338 if (e
->type
== pe_unknown
)
6341 resolved (e
->tok
, e
->type
);
6346 typeresolution_info::visit_target_bitfield (target_bitfield
*)
6348 // These are all expanded much earlier.
6353 typeresolution_info::visit_target_symbol (target_symbol
* e
)
6355 // This occurs only if a target symbol was not resolved over in
6356 // tapset.cxx land, that error was properly suppressed, and the
6357 // later unused-expression-elimination pass didn't get rid of it
6358 // either. So we have a target symbol that is believed to be of
6359 // genuine use, yet unresolved by the provider.
6361 // PR18079, or it can happen if a $target expression is nested within
6362 // a @defined() test that has not yet been resolved (but can be soon).
6363 if (! assert_resolvability
)
6365 num_still_unresolved
++;
6369 if (session
.verbose
> 2)
6371 clog
<< _("Resolution problem with ");
6372 if (current_function
)
6374 clog
<< "function " << current_function
->name
<< endl
;
6375 current_function
->body
->print (clog
);
6378 else if (current_probe
)
6380 clog
<< "probe " << *current_probe
->sole_location() << endl
;
6381 current_probe
->body
->print (clog
);
6385 //TRANSLATORS: simply saying not an issue with a probe or function
6386 clog
<< _("other") << endl
;
6389 if (e
->saved_conversion_error
)
6390 throw (* (e
->saved_conversion_error
));
6392 throw SEMANTIC_ERROR(_("unresolved target-symbol expression"), e
->tok
);
6397 typeresolution_info::visit_atvar_op (atvar_op
* e
)
6399 // This occurs only if an @var() was not resolved over in
6400 // tapset.cxx land, that error was properly suppressed, and the
6401 // later unused-expression-elimination pass didn't get rid of it
6402 // either. So we have an @var() that is believed to be of
6403 // genuine use, yet unresolved by the provider.
6405 if (session
.verbose
> 2)
6407 clog
<< _("Resolution problem with ");
6408 if (current_function
)
6410 clog
<< "function " << current_function
->name
<< endl
;
6411 current_function
->body
->print (clog
);
6414 else if (current_probe
)
6416 clog
<< "probe " << *current_probe
->sole_location() << endl
;
6417 current_probe
->body
->print (clog
);
6421 //TRANSLATORS: simply saying not an issue with a probe or function
6422 clog
<< _("other") << endl
;
6425 if (e
->saved_conversion_error
)
6426 throw (* (e
->saved_conversion_error
));
6428 throw SEMANTIC_ERROR(_("unresolved @var() expression"), e
->tok
);
6433 typeresolution_info::visit_defined_op (defined_op
* e
)
6435 // PR18079: if a @defined is still around, it may have a parameter that
6436 // wasn't resolvable one way or another earlier. Maybe an autocast_op.
6437 // Let's give it a visit just in case.
6438 e
->operand
->visit(this);
6440 if (assert_resolvability
)
6441 throw SEMANTIC_ERROR(_("unexpected @defined"), e
->tok
);
6443 num_still_unresolved
++;
6448 typeresolution_info::visit_entry_op (entry_op
* e
)
6450 throw SEMANTIC_ERROR(_("@entry is only valid in .return probes"), e
->tok
);
6455 typeresolution_info::visit_cast_op (cast_op
* e
)
6457 // Like target_symbol, a cast_op shouldn't survive this far
6458 // unless it was not resolved and its value is really needed.
6459 if (e
->saved_conversion_error
)
6460 throw (* (e
->saved_conversion_error
));
6462 throw SEMANTIC_ERROR(_F("type definition '%s' not found in '%s'",
6463 e
->type_name
.to_string().c_str(),
6464 e
->module
.to_string().c_str()), e
->tok
);
6469 typeresolution_info::visit_autocast_op (autocast_op
* e
)
6471 // Like cast_op, a implicit autocast_op shouldn't survive this far
6472 // unless it was not resolved and its value is really needed.
6473 if (assert_resolvability
&& e
->saved_conversion_error
)
6474 throw (* (e
->saved_conversion_error
));
6475 else if (assert_resolvability
)
6476 throw SEMANTIC_ERROR(_("unknown type in dereference"), e
->tok
);
6479 e
->operand
->visit (this);
6481 num_still_unresolved
++;
6482 if (e
->operand
->type_details
&&
6483 e
->operand
->type_details
->expandable())
6484 num_available_autocasts
++;
6489 typeresolution_info::visit_perf_op (perf_op
* e
)
6491 // A perf_op should already be resolved
6492 if (t
== pe_stats
|| t
== pe_string
)
6493 invalid (e
->tok
, t
);
6496 // XXX: ... but but but ... ::visit_defined_op interprets this ->type
6497 // as meaning that @defined(@perf("JUNK JUNK JUNK")) is valid.
6498 // The dwarf_var_expanding_visitor::visit_perf_op() code that validates
6499 // the JUNK parameter is not even called in time.
6501 // (There is no real need to visit our operand - by parser
6502 // construction, it's always a string literal, with its type already
6505 e
->operand
->visit (this);
6510 typeresolution_info::visit_arrayindex (arrayindex
* e
)
6513 symbol
*array
= NULL
;
6514 hist_op
*hist
= NULL
;
6515 classify_indexable(e
->base
, array
, hist
);
6517 // Every hist_op has type [int]:int, that is to say, every hist_op
6518 // is a pseudo-one-dimensional integer array type indexed by
6519 // integers (bucket numbers).
6523 if (e
->indexes
.size() != 1)
6524 unresolved (e
->tok
);
6526 e
->indexes
[0]->visit (this);
6527 if (e
->indexes
[0]->type
!= pe_long
)
6528 unresolved (e
->tok
);
6530 if (e
->type
!= pe_long
)
6533 resolved (e
->tok
, e
->type
);
6538 // Now we are left with "normal" map inference and index checking.
6541 assert (array
->referent
!= 0);
6542 resolve_2types (e
, array
->referent
, this, t
);
6544 // now resolve the array indexes
6546 // if (e->referent->index_types.size() == 0)
6547 // // redesignate referent as array
6548 // e->referent->set_arity (e->indexes.size ());
6550 if (e
->indexes
.size() != array
->referent
->index_types
.size())
6551 unresolved (e
->tok
); // symbol resolution should prevent this
6552 else for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
6556 expression
* ee
= e
->indexes
[i
];
6557 exp_type
& ft
= array
->referent
->index_types
[i
];
6560 exp_type at
= ee
->type
;
6562 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
6564 // propagate to formal type
6566 resolved (ee
->tok
, ft
, array
->referent
, i
);
6569 invalid (ee
->tok
, at
);
6571 invalid (ee
->tok
, ft
);
6572 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
6573 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
6574 if (at
== pe_unknown
)
6575 unresolved (ee
->tok
);
6582 typeresolution_info::visit_functioncall (functioncall
* e
)
6584 if (e
->referents
.empty())
6585 throw SEMANTIC_ERROR (_F("internal error: unresolved function call to '%s'",
6586 e
->function
.to_string().c_str()), e
->tok
);
6588 exp_type original
= t
;
6589 for (unsigned fd
= 0; fd
< e
->referents
.size(); fd
++)
6591 t
= original
; // type may be changed by overloaded functions so restore it
6592 functiondecl
* referent
= e
->referents
[fd
];
6593 resolve_2types (e
, referent
, this, t
, true); // accept unknown type
6595 if (e
->type
== pe_stats
)
6596 invalid (e
->tok
, e
->type
);
6598 const exp_type_ptr
& func_type
= referent
->type_details
;
6599 if (func_type
&& referent
->type
== e
->type
6600 && (!e
->type_details
|| *func_type
!= *e
->type_details
))
6601 resolved_details(referent
->type_details
, e
->type_details
);
6603 // now resolve the function parameters
6604 if (e
->args
.size() != referent
->formal_args
.size())
6605 unresolved (e
->tok
); // symbol resolution should prevent this
6606 else for (unsigned i
=0; i
<e
->args
.size(); i
++)
6608 expression
* ee
= e
->args
[i
];
6609 exp_type
& ft
= referent
->formal_args
[i
]->type
;
6610 const token
* fe_tok
= referent
->formal_args
[i
]->tok
;
6613 exp_type at
= ee
->type
;
6615 if (((at
== pe_string
) || (at
== pe_long
)) && ft
== pe_unknown
)
6617 // propagate to formal arg
6619 resolved (ee
->tok
, ft
, referent
->formal_args
[i
], i
);
6622 invalid (ee
->tok
, at
);
6624 invalid (fe_tok
, ft
);
6625 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
6626 mismatch (ee
->tok
, ee
->type
, referent
->formal_args
[i
], i
);
6627 if (at
== pe_unknown
)
6628 unresolved (ee
->tok
);
6635 typeresolution_info::visit_block (block
* e
)
6637 for (unsigned i
=0; i
<e
->statements
.size(); i
++)
6640 e
->statements
[i
]->visit (this);
6646 typeresolution_info::visit_try_block (try_block
* e
)
6649 e
->try_block
->visit (this);
6650 if (e
->catch_error_var
)
6653 e
->catch_error_var
->visit (this);
6656 e
->catch_block
->visit (this);
6661 typeresolution_info::visit_embeddedcode (embeddedcode
* s
)
6663 // PR11573. If we have survived thus far with a piece of embedded
6664 // code that requires uprobes, we need to track this.
6666 // This is an odd place for this check, as opposed
6667 // to a separate 'optimization' pass, or c_unparser::visit_embeddedcode
6668 // over yonder in pass 3. However, we want to do it during pass 2 so
6669 // that cached sessions also get the uprobes treatment.
6670 if (! session
.need_uprobes
6671 && s
->code
.find("/* pragma:uprobes */") != string::npos
)
6673 if (session
.verbose
> 2)
6674 clog
<< _("Activating uprobes support because /* pragma:uprobes */ seen.") << endl
;
6675 session
.need_uprobes
= true;
6678 // PR15065. Likewise, we need to detect /* pragma:tagged_dfa */
6679 // before the gen_dfa_table pass. Again, the typechecking part of
6680 // pass 2 is a good place for this.
6681 if (! session
.need_tagged_dfa
6682 && s
->code
.find("/* pragma:tagged_dfa */") != string::npos
)
6684 if (session
.verbose
> 2)
6685 clog
<< _("Turning on DFA subexpressions because /* pragma:tagged_dfa */ seen") << endl
;
6686 session
.need_tagged_dfa
= true;
6687 // TODOXXX throw SEMANTIC_ERROR (_("Tagged DFA support is not yet available"), s->tok);
6693 typeresolution_info::visit_if_statement (if_statement
* e
)
6696 e
->condition
->visit (this);
6699 e
->thenblock
->visit (this);
6704 e
->elseblock
->visit (this);
6710 typeresolution_info::visit_for_loop (for_loop
* e
)
6713 if (e
->init
) e
->init
->visit (this);
6715 e
->cond
->visit (this);
6717 if (e
->incr
) e
->incr
->visit (this);
6719 e
->block
->visit (this);
6724 typeresolution_info::visit_foreach_loop (foreach_loop
* e
)
6726 // See also visit_arrayindex.
6727 // This is different in that, being a statement, we can't assign
6728 // a type to the outer array, only propagate to/from the indexes
6730 // if (e->referent->index_types.size() == 0)
6731 // // redesignate referent as array
6732 // e->referent->set_arity (e->indexes.size ());
6734 exp_type wanted_value
= pe_unknown
;
6735 symbol
*array
= NULL
;
6736 hist_op
*hist
= NULL
;
6737 classify_indexable(e
->base
, array
, hist
);
6741 if (e
->indexes
.size() != 1)
6742 unresolved (e
->tok
);
6744 e
->indexes
[0]->visit (this);
6745 if (e
->indexes
[0]->type
!= pe_long
)
6746 unresolved (e
->tok
);
6748 wanted_value
= pe_long
;
6753 if (e
->indexes
.size() != array
->referent
->index_types
.size())
6754 unresolved (e
->tok
); // symbol resolution should prevent this
6757 for (unsigned i
=0; i
<e
->indexes
.size(); i
++)
6759 expression
* ee
= e
->indexes
[i
];
6760 exp_type
& ft
= array
->referent
->index_types
[i
];
6763 exp_type at
= ee
->type
;
6765 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
6767 // propagate to formal type
6769 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
6772 invalid (ee
->tok
, at
);
6774 invalid (ee
->tok
, ft
);
6775 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
6776 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
6777 if (at
== pe_unknown
)
6778 unresolved (ee
->tok
);
6780 for (unsigned i
=0; i
<e
->array_slice
.size(); i
++)
6781 if (e
->array_slice
[i
])
6783 expression
* ee
= e
->array_slice
[i
];
6784 exp_type
& ft
= array
->referent
->index_types
[i
];
6787 exp_type at
= ee
->type
;
6789 if ((at
== pe_string
|| at
== pe_long
) && ft
== pe_unknown
)
6791 // propagate to formal type
6793 resolved (ee
->tok
, ee
->type
, array
->referent
, i
);
6796 invalid (ee
->tok
, at
);
6798 invalid (ee
->tok
, ft
);
6799 if (at
!= pe_unknown
&& ft
!= pe_unknown
&& ft
!= at
)
6800 mismatch (ee
->tok
, ee
->type
, array
->referent
, i
);
6801 if (at
== pe_unknown
)
6802 unresolved (ee
->tok
);
6806 array
->visit (this);
6807 wanted_value
= array
->type
;
6812 if (wanted_value
== pe_stats
)
6813 invalid(e
->value
->tok
, wanted_value
);
6814 else if (wanted_value
!= pe_unknown
)
6815 check_arg_type(wanted_value
, e
->value
);
6819 e
->value
->visit (this);
6823 /* Prevent @sum etc. aggregate sorting on non-statistics arrays. */
6824 if (wanted_value
!= pe_unknown
)
6825 if (e
->sort_aggr
!= sc_none
&& wanted_value
!= pe_stats
)
6826 invalid (array
->tok
, wanted_value
);
6831 e
->limit
->visit (this);
6835 e
->block
->visit (this);
6840 typeresolution_info::visit_null_statement (null_statement
*)
6846 typeresolution_info::visit_expr_statement (expr_statement
* e
)
6849 e
->value
->visit (this);
6853 struct delete_statement_typeresolution_info
:
6854 public throwing_visitor
6856 typeresolution_info
*parent
;
6857 delete_statement_typeresolution_info (typeresolution_info
*p
):
6858 throwing_visitor (_("invalid operand of delete expression")),
6862 void visit_arrayindex (arrayindex
* e
)
6864 parent
->visit_arrayindex (e
);
6867 void visit_symbol (symbol
* e
)
6869 exp_type ignored
= pe_unknown
;
6870 assert (e
->referent
!= 0);
6871 resolve_2types (e
, e
->referent
, parent
, ignored
);
6877 typeresolution_info::visit_delete_statement (delete_statement
* e
)
6879 delete_statement_typeresolution_info
di (this);
6881 e
->value
->visit (&di
);
6886 typeresolution_info::visit_next_statement (next_statement
*)
6892 typeresolution_info::visit_break_statement (break_statement
*)
6898 typeresolution_info::visit_continue_statement (continue_statement
*)
6904 typeresolution_info::visit_array_in (array_in
* e
)
6906 // all unary operators only work on numerics
6908 t
= pe_unknown
; // array value can be anything
6909 e
->operand
->visit (this);
6911 if (t1
== pe_unknown
&& e
->type
!= pe_unknown
)
6912 ; // already resolved
6913 else if (t1
== pe_string
|| t1
== pe_stats
)
6914 mismatch (e
->tok
, t1
, pe_long
);
6915 else if (e
->type
== pe_unknown
)
6918 resolved (e
->tok
, e
->type
);
6924 typeresolution_info::visit_return_statement (return_statement
* e
)
6926 // This is like symbol, where the referent is
6927 // the return value of the function.
6929 // translation pass will print error
6930 if (current_function
== 0)
6933 exp_type
& e_type
= current_function
->type
;
6934 t
= current_function
->type
;
6938 if (e_type
!= pe_unknown
)
6939 mismatch (e
->tok
, pe_unknown
, current_function
);
6943 e
->value
->visit (this);
6945 if (e_type
!= pe_unknown
&& e
->value
->type
!= pe_unknown
6946 && e_type
!= e
->value
->type
)
6947 mismatch (e
->value
->tok
, e
->value
->type
, current_function
);
6948 if (e_type
== pe_unknown
&&
6949 (e
->value
->type
== pe_long
|| e
->value
->type
== pe_string
))
6951 // propagate non-statistics from value
6952 e_type
= e
->value
->type
;
6953 resolved (e
->value
->tok
, e_type
, current_function
);
6955 if (e
->value
->type
== pe_stats
)
6956 invalid (e
->value
->tok
, e
->value
->type
);
6958 const exp_type_ptr
& value_type
= e
->value
->type_details
;
6959 if (value_type
&& current_function
->type
== e
->value
->type
)
6961 exp_type_ptr
& func_type
= current_function
->type_details
;
6963 // The function can take on the type details of the return value.
6964 resolved_details(value_type
, func_type
);
6965 else if (*func_type
!= *value_type
&& *func_type
!= *null_type
)
6966 // Conflicting return types? NO TYPE FOR YOU!
6967 resolved_details(null_type
, func_type
);
6972 typeresolution_info::visit_print_format (print_format
* e
)
6974 size_t unresolved_args
= 0;
6978 e
->hist
->visit(this);
6981 else if (e
->print_with_format
)
6983 // If there's a format string, we can do both inference *and*
6986 // First we extract the subsequence of formatting components
6987 // which are conversions (not just literal string components)
6989 unsigned expected_num_args
= 0;
6990 std::vector
<print_format::format_component
> components
;
6991 for (size_t i
= 0; i
< e
->components
.size(); ++i
)
6993 if (e
->components
[i
].type
== print_format::conv_unspecified
)
6994 throw SEMANTIC_ERROR (_("Unspecified conversion in print operator format string"),
6996 else if (e
->components
[i
].type
== print_format::conv_literal
)
6998 components
.push_back(e
->components
[i
]);
6999 ++expected_num_args
;
7000 if (e
->components
[i
].widthtype
== print_format::width_dynamic
)
7001 ++expected_num_args
;
7002 if (e
->components
[i
].prectype
== print_format::prec_dynamic
)
7003 ++expected_num_args
;
7006 // Then we check that the number of conversions and the number
7009 if (expected_num_args
!= e
->args
.size())
7010 throw SEMANTIC_ERROR (_("Wrong number of args to formatted print operator"),
7013 // Then we check that the types of the conversions match the types
7016 for (size_t i
= 0; i
< components
.size(); ++i
)
7018 // Check the dynamic width, if specified
7019 if (components
[i
].widthtype
== print_format::width_dynamic
)
7021 check_arg_type (pe_long
, e
->args
[argno
]);
7025 // Check the dynamic precision, if specified
7026 if (components
[i
].prectype
== print_format::prec_dynamic
)
7028 check_arg_type (pe_long
, e
->args
[argno
]);
7032 exp_type wanted
= pe_unknown
;
7034 switch (components
[i
].type
)
7036 case print_format::conv_unspecified
:
7037 case print_format::conv_literal
:
7041 case print_format::conv_pointer
:
7042 case print_format::conv_number
:
7043 case print_format::conv_binary
:
7044 case print_format::conv_char
:
7045 case print_format::conv_memory
:
7046 case print_format::conv_memory_hex
:
7050 case print_format::conv_string
:
7055 assert (wanted
!= pe_unknown
);
7056 check_arg_type (wanted
, e
->args
[argno
]);
7062 // Without a format string, the best we can do is require that
7063 // each argument resolve to a concrete type.
7064 for (size_t i
= 0; i
< e
->args
.size(); ++i
)
7067 e
->args
[i
]->visit (this);
7068 if (e
->args
[i
]->type
== pe_unknown
)
7070 unresolved (e
->args
[i
]->tok
);
7076 if (unresolved_args
== 0)
7078 if (e
->type
== pe_unknown
)
7080 if (e
->print_to_stream
)
7083 e
->type
= pe_string
;
7084 resolved (e
->tok
, e
->type
);
7089 e
->type
= pe_unknown
;
7090 unresolved (e
->tok
);
7096 typeresolution_info::visit_stat_op (stat_op
* e
)
7099 e
->stat
->visit (this);
7100 if (e
->type
== pe_unknown
)
7103 resolved (e
->tok
, e
->type
);
7105 else if (e
->type
!= pe_long
)
7106 mismatch (e
->tok
, pe_long
, e
->type
);
7110 typeresolution_info::visit_hist_op (hist_op
* e
)
7113 e
->stat
->visit (this);
7118 typeresolution_info::check_arg_type (exp_type wanted
, expression
* arg
)
7123 if (arg
->type
== pe_unknown
)
7126 resolved (arg
->tok
, arg
->type
);
7128 else if (arg
->type
!= wanted
)
7130 mismatch (arg
->tok
, wanted
, arg
->type
);
7136 typeresolution_info::check_local (vardecl
* v
)
7140 num_still_unresolved
++;
7141 if (assert_resolvability
)
7143 (SEMANTIC_ERROR (_("array locals not supported, missing global declaration? "), v
->tok
));
7146 if (v
->type
== pe_unknown
)
7147 unresolved (v
->tok
);
7148 else if (v
->type
== pe_stats
)
7150 num_still_unresolved
++;
7151 if (assert_resolvability
)
7153 (SEMANTIC_ERROR (_("stat locals not supported, missing global declaration? "), v
->tok
));
7155 else if (!(v
->type
== pe_long
|| v
->type
== pe_string
))
7156 invalid (v
->tok
, v
->type
);
7161 typeresolution_info::unresolved (const token
* tok
)
7163 num_still_unresolved
++;
7165 if (assert_resolvability
&& mismatch_complexity
<= 0)
7168 msg
<< _("unresolved type ");
7169 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
7175 typeresolution_info::invalid (const token
* tok
, exp_type pe
)
7177 num_still_unresolved
++;
7179 if (assert_resolvability
)
7182 if (tok
&& tok
->type
== tok_operator
)
7183 msg
<< _("invalid operator");
7185 msg
<< _("invalid type ") << pe
;
7186 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
7191 typeresolution_info::mismatch (const binary_expression
* e
)
7193 num_still_unresolved
++;
7195 if (assert_resolvability
&& mismatch_complexity
<= 1)
7198 msg
<< _F("type mismatch: left and right sides don't agree (%s vs %s)",
7199 lex_cast(e
->left
->type
).c_str(), lex_cast(e
->right
->type
).c_str());
7200 session
.print_error (SEMANTIC_ERROR (msg
.str(), e
->tok
));
7202 else if (!assert_resolvability
)
7203 mismatch_complexity
= max(1, mismatch_complexity
);
7206 /* tok token where mismatch occurred
7207 * t1 type we expected (the 'good' type)
7208 * t2 type we received (the 'bad' type)
7211 typeresolution_info::mismatch (const token
* tok
, exp_type t1
, exp_type t2
)
7213 num_still_unresolved
++;
7215 if (assert_resolvability
&& mismatch_complexity
<= 2)
7218 msg
<< _F("type mismatch: expected %s", lex_cast(t1
).c_str());
7219 if (t2
!= pe_unknown
)
7220 msg
<< _F(" but found %s", lex_cast(t2
).c_str());
7221 session
.print_error (SEMANTIC_ERROR (msg
.str(), tok
));
7223 else if (!assert_resolvability
)
7224 mismatch_complexity
= max(2, mismatch_complexity
);
7227 /* tok token where the mismatch happened
7228 * type type we received (the 'bad' type)
7229 * decl declaration of mismatched symbol
7230 * index if index-based (array index or function arg)
7233 typeresolution_info::mismatch (const token
*tok
, exp_type type
,
7234 const symboldecl
* decl
, int index
)
7236 num_still_unresolved
++;
7238 if (assert_resolvability
&& mismatch_complexity
<= 3)
7240 assert(decl
!= NULL
);
7242 // If mismatch is against a function parameter from within the function
7243 // itself (rather than a function call), then the index will be -1. We
7244 // check here if the decl corresponds to one of the params and if so,
7245 // adjust the index.
7246 if (current_function
!= NULL
&& index
== -1)
7248 vector
<vardecl
*>& args
= current_function
->formal_args
;
7249 for (unsigned i
= 0; i
< args
.size() && index
< 0; i
++)
7250 if (args
[i
] == decl
)
7254 // get the declaration's original type and token
7255 const resolved_type
*original
= NULL
;
7256 for (vector
<resolved_type
>::const_iterator it
= resolved_types
.begin();
7257 it
!= resolved_types
.end() && original
== NULL
; ++it
)
7259 if (it
->decl
== decl
&& it
->index
== index
)
7263 // print basic mismatch msg if we couldn't find the decl (this can happen
7264 // for explicitly typed decls e.g. myvar:long or for fabricated (already
7265 // resolved) decls e.g. __perf_read_*)
7266 if (original
== NULL
)
7268 session
.print_error (SEMANTIC_ERROR (
7269 _F("type mismatch: expected %s but found %s",
7270 lex_cast(type
).c_str(),
7271 lex_cast(decl
->type
).c_str()),
7276 // print where mismatch happened and chain with origin of decl type
7281 msg
<< _F("index %d ", index
);
7282 msg
<< _F("type mismatch (%s)", lex_cast(type
).c_str());
7283 semantic_error
err(ERR_SRC
, msg
.str(), tok
);
7285 stringstream chain_msg
;
7286 chain_msg
<< _("type");
7288 chain_msg
<< _F(" of index %d", index
);
7289 chain_msg
<< _F(" was first inferred here (%s)",
7290 lex_cast(decl
->type
).c_str());
7291 semantic_error
chain(ERR_SRC
, chain_msg
.str(), original
->tok
);
7293 err
.set_chain(chain
);
7294 session
.print_error (err
);
7296 else if (!assert_resolvability
)
7297 mismatch_complexity
= max(3, mismatch_complexity
);
7301 /* tok token where resolution occurred
7302 * type type to which we resolved
7303 * decl declaration of resolved symbol
7304 * index if index-based (array index or function arg)
7307 typeresolution_info::resolved (const token
*tok
, exp_type
,
7308 const symboldecl
* decl
, int index
)
7310 num_newly_resolved
++;
7312 // We only use the resolved_types vector to give better mismatch messages
7313 // involving symbols. So don't bother adding it if we're not given a decl
7316 // As a fail-safe, if the decl & index is already in the vector, then
7317 // modify it instead of adding another one to ensure uniqueness. This
7318 // should never happen since we only call resolved once for each decl &
7319 // index, but better safe than sorry. (IE. if it does happen, better have
7320 // the latest resolution info for better mismatch reporting later).
7321 for (unsigned i
= 0; i
< resolved_types
.size(); i
++)
7323 if (resolved_types
[i
].decl
== decl
7324 && resolved_types
[i
].index
== index
)
7326 resolved_types
[i
].tok
= tok
;
7330 resolved_type
res(tok
, decl
, index
);
7331 resolved_types
.push_back(res
);
7336 typeresolution_info::resolved_details (const exp_type_ptr
& src
,
7339 num_newly_resolved
++;
7343 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */