NULL, true);
}
+/* Returns TRUE iff THIS is a descendant of N in the clone tree. */
+
+bool
+cgraph_node::is_clone_of (cgraph_node *n) const
+{
+ for (cgraph_node *walker = clone_of; walker; walker = walker->clone_of)
+ if (walker == n)
+ return true;
+ return false;
+}
/* Collect all callers of NODE. Worker for collect_callers_of_node. */
it is not used in any other non-standard way. */
bool only_called_directly_p (void);
+ /* Returns TRUE iff THIS is a descendant of N in the clone tree. */
+ bool is_clone_of (cgraph_node *n) const;
+
/* Turn profile to global0. Walk into inlined functions. */
void make_profile_local ();
addr = get_base_address (addr);
if (TREE_CODE (addr) == FUNCTION_DECL)
{
+ cgraph_node *caller = (cgraph_node *) data;
cgraph_node *node = cgraph_node::get_create (addr);
+ /* If NODE was cloned and the caller is a callback-dispatching function,
+ the gimple call might not be updated yet. Check whether that's the
+ case and if so, replace NODE with the correct callee. */
+ cgraph_edge *e = caller->get_edge (stmt);
+ if (e && e->has_callback)
+ {
+ for (cgraph_edge *cbe = e->first_callback_edge ();
+ cbe;
+ cbe = cbe->next_callback_edge ())
+ {
+ if (cbe->callee->is_clone_of (node))
+ {
+ node = cbe->callee;
+ break;
+ }
+ }
+ }
node->mark_address_taken ();
- ((symtab_node *)data)->create_reference (node, IPA_REF_ADDR, stmt);
+ caller->create_reference (node, IPA_REF_ADDR, stmt);
}
else if (addr && VAR_P (addr)
&& (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a (int);
+struct b
+{
+ b ();
+ b (b &);
+ ~b ();
+};
+template <typename c> b d (c);
+int ab;
+void ae (int);
+struct e
+{
+ b g;
+ template <typename c> e operator<< (c h)
+ {
+ d (h);
+ return *this;
+ }
+ b f;
+};
+template <int = 0> struct i
+{
+ long ah;
+ int j ()
+ {
+ e () << "" << aj << 1 << "" << ah << "" << ak << "";
+ return ah;
+ }
+ char aj;
+ int ak;
+};
+i<> k;
+template <typename>
+int
+ao (bool h)
+{
+#pragma omp parallel
+ {
+ int as;
+ for (; as;)
+ {
+ int au = k.j ();
+ ae (au);
+ if (h)
+ b ();
+ }
+ }
+ return a (ab);
+}
+int l = ao<short> (true);
+void
+az ()
+{
+ ao<short> (true);
+ __builtin_unreachable ();
+}
+template int ao<short> (bool);