[LTO][PATCH] Fix another undefined reference problem.

Doug Kwan (關振德) dougkwan@google.com
Fri Dec 12 08:52:00 GMT 2008


Hi,

    This patch fixes another problem where DECLs of unemitted
functions are written as exportable in the IL.  The previous code used
gimple_body to check for availability of function bodies and that was
wrong.  When we are resetting lang-specifics, all emitted functions
should have been lowered and have CFGs.  So we should check for the
presence of CFGs instead.

Tested on i686-unknown-linux-gnu.

-Doug

2008-12-11  Doug Kwan  <dougkwan@google.com>

cp/ChangeLog.lto:
	* tree.c (cp_fix_function_decl_p): New.
	(cp_reset_lang_specifics): Move the logic for determining what
	FUNCTION_DECLs to fix to (cp_fix_function_decl_p).

testsuite/ChangeLog.lto:
	* g++.dg/lto/20081211-1.h: New.
	* g++.dg/lto/20081211-1_0.C: New.
	* g++.dg/lto/20081211-1_1.C: New.
-------------- next part --------------
Index: gcc/gcc/testsuite/g++.dg/lto/20081211-1.h
===================================================================
--- gcc/gcc/testsuite/g++.dg/lto/20081211-1.h	(revision 0)
+++ gcc/gcc/testsuite/g++.dg/lto/20081211-1.h	(revision 0)
@@ -0,0 +1,6 @@
+class foo {
+ public:
+  foo () {}
+  virtual ~foo () {}
+  virtual void key_method (void);
+};
Index: gcc/gcc/testsuite/g++.dg/lto/20081211-1_0.C
===================================================================
--- gcc/gcc/testsuite/g++.dg/lto/20081211-1_0.C	(revision 0)
+++ gcc/gcc/testsuite/g++.dg/lto/20081211-1_0.C	(revision 0)
@@ -0,0 +1,19 @@
+#include "20081211-1.h"
+
+foo *
+create_foo (void)
+{
+  return new foo;
+}
+
+void
+destroy_foo (foo *p)
+{
+  delete p;
+}
+
+int
+main ()
+{
+  return 0;
+}
Index: gcc/gcc/testsuite/g++.dg/lto/20081211-1_1.C
===================================================================
--- gcc/gcc/testsuite/g++.dg/lto/20081211-1_1.C	(revision 0)
+++ gcc/gcc/testsuite/g++.dg/lto/20081211-1_1.C	(revision 0)
@@ -0,0 +1,6 @@
+#include "20081211-1.h"
+
+void
+foo::key_method (void)
+{
+}
Index: gcc/gcc/cp/tree.c
===================================================================
--- gcc/gcc/cp/tree.c	(revision 142691)
+++ gcc/gcc/cp/tree.c	(working copy)
@@ -2797,6 +2797,27 @@ cast_valid_in_integral_constant_expressi
 	  || type == error_mark_node);
 }
 
+/* Return true if we need to fix linkage information of DECL.  */
+
+static bool
+cp_fix_function_decl_p (tree decl)
+{
+  /* Skip if DECL is not externally.  */
+  if (!TREE_PUBLIC (decl))
+    return false;
+
+  /* We need to fix DECL if it a appears to be exported but with no
+     function body.  Thunks do not have CFGs and we may need to
+     handle them specially later.   */
+  if ((!DECL_STRUCT_FUNCTION (decl)
+       || !DECL_STRUCT_FUNCTION (decl)->cfg)
+      && !DECL_THUNK_P (decl)
+      && !DECL_EXTERNAL (decl))
+    return true;
+
+  return false;
+}
+
 /* Clean the C++ specific parts of the tree T. */
 
 void
@@ -2821,22 +2842,9 @@ cp_reset_lang_specifics (tree t)
       if (mangle_decl_is_template_id (t, &template_info))
         DECL_CONTEXT (TREE_PURPOSE (template_info)) = NULL_TREE;
     }
-  /* Fix up DECLs for inlines and implicitly instantiated functions.
-     We trust the C++ FE that we skip any DECLs with DECL_INTERFACE_KNOWN
-     set.  */
   else if (TREE_CODE (t) == FUNCTION_DECL
-	   && !gimple_body (t)
-	   && !DECL_EXTERNAL (t)
-	   && TREE_PUBLIC (t)
-	   && !DECL_INTERFACE_KNOWN (t))
+	   && cp_fix_function_decl_p (t))
     {
-      /* This should only happen for inlines or implicit instanitations
-	 which are not emitted.  When we reach here,  we should have read
-	 the EOF and expanded all needed functions.  */
-      gcc_assert ((DECL_DECLARED_INLINE_P (t)
-		   || DECL_IMPLICIT_INSTANTIATION (t))
-		  && at_eof);
-
       /* If T is used in this translation unit at all,  the definition
 	 must exist somewhere else since we have decided to not emit it
 	 in this TU.  So make it an external reference.  */


More information about the Gcc-patches mailing list