[C++] Fix extern_decl_map handling (PR c++/3698, PR c++/86208)

Message ID 20180703073555.GX7166@tucnak
State New
Headers show
Series
  • [C++] Fix extern_decl_map handling (PR c++/3698, PR c++/86208)
Related show

Commit Message

Jakub Jelinek July 3, 2018, 7:35 a.m.
Hi!

This testcase got fixed in G++ 3.2, where we used for decision if inline
function body should be kept TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (...)),
but we now use cgraph and the testcase fails again; the particular problem
is that we set TREE_USED only on the local extern decl and don't propagate
it to the decl that extern_decl_map maps it into.

Fixed by the following patch, which propagates it at genericization time.
Bootstrapped/regtested on x86_64-linux and i686-linux.

Another option is:
+  /* If decl is local extern, recurse into corresponding decl.  */
+  if (cfun
+      && cp_function_chain
+      && cp_function_chain->extern_decl_map
+      && VAR_OR_FUNCTION_DECL_P (decl)
+      && DECL_EXTERNAL (decl))
+    {
+      struct cxx_int_tree_map *h, in;
+      in.uid = DECL_UID (decl);
+      h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
+      if (h)
+	TREE_USED (h->to) = 1;
+    }
+
in mark_used, another one:
+  /* If decl is local extern, recurse into corresponding decl.  */
+  if (cfun
+      && cp_function_chain
+      && cp_function_chain->extern_decl_map
+      && VAR_OR_FUNCTION_DECL_P (decl)
+      && DECL_EXTERNAL (decl))
+    {
+      struct cxx_int_tree_map *h, in;
+      in.uid = DECL_UID (decl);
+      h = cp_function_chain->extern_decl_map->find_with_hash (&in, in.uid);
+      if (h && !mark_used (h->to))
+	return false;
+    }
+
in the same spot.
None of these fix the PR82204 though.

2018-07-02  Jakub Jelinek  <jakub@redhat.com>

	PR c++/3698
	PR c++/86208
	* cp-gimplify.c (cp_genericize_r): When using extern_decl_map, or
	in TREE_USED flag from stmt to h->to.

	* g++.dg/opt/pr3698.C: New test.


	Jakub

Patch

--- gcc/cp/cp-gimplify.c.jj	2018-06-20 08:15:28.980857357 +0200
+++ gcc/cp/cp-gimplify.c	2018-07-02 18:03:00.714313555 +0200
@@ -1085,6 +1085,7 @@  cp_genericize_r (tree *stmt_p, int *walk
       if (h)
 	{
 	  *stmt_p = h->to;
+	  TREE_USED (h->to) |= TREE_USED (stmt);
 	  *walk_subtrees = 0;
 	  return NULL;
 	}
--- gcc/testsuite/g++.dg/opt/pr3698.C.jj	2018-07-02 18:05:52.535479087 +0200
+++ gcc/testsuite/g++.dg/opt/pr3698.C	2018-07-02 18:05:44.507471531 +0200
@@ -0,0 +1,21 @@ 
+// PR c++/3698
+// { dg-do link }
+// { dg-options "-O0" }
+
+struct X {
+  int i;
+};
+
+inline const int&
+OHashKey (const X& x)
+{
+  return x.i;
+}
+
+int
+main ()
+{
+ extern const int& OHashKey (const X& x);
+ X x;
+ return OHashKey (x);
+}