]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/25369 (use of inline function in template class leads to undefined reference)
authorMark Mitchell <mark@codesourcery.com>
Fri, 23 Dec 2005 07:40:04 +0000 (07:40 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 23 Dec 2005 07:40:04 +0000 (07:40 +0000)
PR c++/25369
* g++.dg/template/ptrmem16.C: New test.
PR c++/25369
* tree.c (really_overloaded_fn): Tweak comment.
* pt.c (tsubst_call_declarator_parms): Remove.
(tsubst_copy): Call mark_used on the member referenced by an
OFFSET_REF.
* semantics.c (finish_qualified_id_expr): Simplify.
* decl2.c (mark_used): Accept BASELINKs.

From-SVN: r109010

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/ptrmem16.C [new file with mode: 0644]

index 705edbb57576b893931f0233518ffb679b4568be..5d906193e733d28b06116c4ad17984c7d3d7b9af 100644 (file)
@@ -1,5 +1,13 @@
 2005-12-22  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/25369
+       * tree.c (really_overloaded_fn): Tweak comment.
+       * pt.c (tsubst_call_declarator_parms): Remove.
+       (tsubst_copy): Call mark_used on the member referenced by an
+       OFFSET_REF.
+       * semantics.c (finish_qualified_id_expr): Simplify.
+       * decl2.c (mark_used): Accept BASELINKs.
+
        PR c++/25364
        * typeck.c (build_unary_op): Pass DECLs not names to
        build_offset_refs.
index 8c65d946a97206c4f48769c9cb0408ebf4ca52b8..10296a708a1945e126cc656b372c830c203998b1 100644 (file)
@@ -3233,14 +3233,27 @@ check_default_args (tree x)
     }
 }
 
-/* Mark DECL as "used" in the program.  If DECL is a specialization or
-   implicitly declared class member, generate the actual definition.  */
+/* Mark DECL (eithet a _DECL or a BASELINK) as "used" in the program.
+   If DECL is a specialization or implicitly declared class member,
+   generate the actual definition.  */
 
 void
 mark_used (tree decl)
 {
   HOST_WIDE_INT saved_processing_template_decl = 0;
 
+  /* If DECL is a BASELINK for a single function, then treat it just
+     like the DECL for the function.  Otherwise, if the BASELINK is
+     for an overloaded function, we don't know which function was
+     actually used until after overload resolution.  */
+  if (TREE_CODE (decl) == BASELINK)
+    {
+      decl = BASELINK_FUNCTIONS (decl);
+      if (really_overloaded_fn (decl))
+       return;
+      decl = OVL_CURRENT (decl);
+    }
+
   TREE_USED (decl) = 1;
   /* If we don't need a value, then we don't need to synthesize DECL.  */ 
   if (skip_evaluation)
index 9e610bf047c1ef9fe0bab33e51527b44f43c5569..93dad098689546e4ece0ca306a66f29ccbea26d6 100644 (file)
@@ -144,7 +144,6 @@ static void check_specialization_scope (void);
 static tree process_partial_specialization (tree);
 static void set_current_access_from_decl (tree);
 static void check_default_tmpl_args (tree, tree, int, int);
-static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
 static tree get_template_base (tree, tree, tree, tree);
 static int verify_class_unification (tree, tree, tree);
 static tree try_class_unification (tree, tree, tree, tree);
@@ -6946,39 +6945,6 @@ tsubst_exception_specification (tree fntype,
   return new_specs;
 }
 
-/* Substitute into the PARMS of a call-declarator.  */
-
-static tree
-tsubst_call_declarator_parms (tree parms,
-                             tree args,
-                             tsubst_flags_t complain,
-                             tree in_decl)
-{
-  tree new_parms;
-  tree type;
-  tree defarg;
-
-  if (!parms || parms == void_list_node)
-    return parms;
-
-  new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms),
-                                           args, complain, in_decl);
-
-  /* Figure out the type of this parameter.  */
-  type = tsubst (TREE_VALUE (parms), args, complain, in_decl);
-
-  /* Figure out the default argument as well.  Note that we use
-     tsubst_expr since the default argument is really an expression.  */
-  defarg = tsubst_expr (TREE_PURPOSE (parms), args, complain, in_decl);
-
-  /* Chain this parameter on to the front of those we have already
-     processed.  We don't use hash_tree_cons because that function
-     doesn't check TREE_PARMLIST.  */
-  new_parms = tree_cons (defarg, type, new_parms);
-
-  return new_parms;
-}
-
 /* Take the tree structure T and replace template parameters used
    therein with the argument vector ARGS.  IN_DECL is an associated
    decl for diagnostics.  If an error occurs, returns ERROR_MARK_NODE.
@@ -8111,6 +8077,10 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
         in response to the saved STMT_IS_FULL_EXPR_P setting.  */
       gcc_unreachable ();
 
+    case OFFSET_REF:
+      mark_used (TREE_OPERAND (t, 1));
+      return t;
+
     default:
       return t;
     }
index a200bf4eae0afa2e3a0843460475e596ce9d86aa..6912e002d8c52aea2f9c75a864855fbe89d6a48f 100644 (file)
@@ -1513,12 +1513,8 @@ finish_qualified_id_expr (tree qualifying_class,
   if (error_operand_p (expr))
     return error_mark_node;
 
-  if (DECL_P (expr))
+  if (DECL_P (expr) || BASELINK_P (expr))
     mark_used (expr);
-  else if (BASELINK_P (expr)
-          && TREE_CODE (BASELINK_FUNCTIONS (expr)) != TEMPLATE_ID_EXPR
-          && !really_overloaded_fn (BASELINK_FUNCTIONS (expr)))
-    mark_used (OVL_CURRENT (BASELINK_FUNCTIONS (expr)));
 
   if (template_p)
     check_template_keyword (expr);
index 4340c69e1d372fb1b95064ad57c8651b443e6740..9575c49d33420a12f361c2689108d6d2516cec94 100644 (file)
@@ -843,9 +843,9 @@ is_overloaded_fn (tree x)
 int
 really_overloaded_fn (tree x)
 {
-  /* A baselink is also considered an overloaded function.  */
   if (TREE_CODE (x) == OFFSET_REF)
     x = TREE_OPERAND (x, 1);
+  /* A baselink is also considered an overloaded function.  */
   if (BASELINK_P (x))
     x = BASELINK_FUNCTIONS (x);
 
index 9c8789a0e6bf2e2a666cc4dee5dea41b82421ca9..87557d863a7a0d448942c7d8f767d256aa999d02 100644 (file)
@@ -1,3 +1,8 @@
+2005-12-22  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25369
+       * g++.dg/template/ptrmem16.C: New test.
+
 2005-12-23  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/25029
diff --git a/gcc/testsuite/g++.dg/template/ptrmem16.C b/gcc/testsuite/g++.dg/template/ptrmem16.C
new file mode 100644 (file)
index 0000000..770581d
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/25369
+// { dg-do link }
+
+template <typename> struct A 
+{
+  void foo() {}
+};
+
+void bar(void (A<int>::*)()) {}
+
+template <int> void baz()
+{
+  bar(&A<int>::foo);
+}
+
+int main()
+{
+  baz<0>();
+  return 0;
+}