This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR3048


This patches fixes PR3048, a regression from GCC 2.95.x.  When creating
a set of overloaded functions, we need to treat multiple declarations
of the same extern "C" function as identical.

Tested on i686-pc-linux-gnu, installed on the mainline and on the
branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2001-11-29  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (ovl_member): Remove.
	* decl2.c (merge_functions): Handle extern "C" functions
	specially.
	* tree.c (ovl_member): Remove.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.572.2.33
diff -c -p -r1.572.2.33 cp-tree.h
*** cp-tree.h	2001/08/07 13:06:43	1.572.2.33
--- cp-tree.h	2001/11/30 01:40:07
*************** extern int is_overloaded_fn			PARAMS ((t
*** 4404,4410 ****
  extern tree get_first_fn			PARAMS ((tree));
  extern int bound_pmf_p				PARAMS ((tree));
  extern tree ovl_cons                            PARAMS ((tree, tree));
- extern int ovl_member                           PARAMS ((tree, tree));
  extern tree build_overload                      PARAMS ((tree, tree));
  extern tree fnaddr_from_vtable_entry		PARAMS ((tree));
  extern tree function_arg_chain			PARAMS ((tree));
--- 4404,4409 ----
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.437.2.28
diff -c -p -r1.437.2.28 decl2.c
*** decl2.c	2001/11/20 04:39:23	1.437.2.28
--- decl2.c	2001/11/30 01:40:11
*************** merge_functions (s1, s2)
*** 4278,4286 ****
  {
    for (; s2; s2 = OVL_NEXT (s2))
      {
!       tree fn = OVL_CURRENT (s2);
!       if (! ovl_member (fn, s1))
! 	s1 = build_overload (fn, s1);
      }
    return s1;
  }
--- 4278,4303 ----
  {
    for (; s2; s2 = OVL_NEXT (s2))
      {
!       tree fn2 = OVL_CURRENT (s2);
!       tree fns1;
!
!       for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
! 	{
! 	  tree fn1 = OVL_CURRENT (fns1);
!
! 	  /* If the function from S2 is already in S1, there is no
! 	     need to add it again.  For `extern "C"' functions, we
! 	     might have two FUNCTION_DECLs for the same function, in
! 	     different namespaces; again, we only need one of them.  */
! 	  if (fn1 == fn2
! 	      || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
! 		  && DECL_NAME (fn1) == DECL_NAME (fn2)))
! 	    break;
! 	}
!
!       /* If we exhausted all of the functions in S1, FN2 is new.  */
!       if (!fns1)
! 	s1 = build_overload (fn2, s1);
      }
    return s1;
  }
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.232.2.9
diff -c -p -r1.232.2.9 tree.c
*** tree.c	2001/05/13 07:10:21	1.232.2.9
--- tree.c	2001/11/30 01:40:12
*************** build_overload (decl, chain)
*** 995,1017 ****
    return ovl_cons (decl, chain);
  }

- /* True if fn is in ovl. */
-
- int
- ovl_member (fn, ovl)
-      tree fn;
-      tree ovl;
- {
-   if (ovl == NULL_TREE)
-     return 0;
-   if (TREE_CODE (ovl) != OVERLOAD)
-     return ovl == fn;
-   for (; ovl; ovl = OVL_CHAIN (ovl))
-     if (OVL_FUNCTION (ovl) == fn)
-       return 1;
-   return 0;
- }
-
  int
  is_aggr_type_2 (t1, t2)
       tree t1, t2;
--- 995,1000 ----
Index: testsuite/g++.old-deja/g++.other/externC5.C
===================================================================
RCS file: externC5.C
diff -N externC5.C
*** /dev/null	Tue May  5 13:32:27 1998
--- externC5.C	Thu Nov 29 17:40:12 2001
***************
*** 0 ****
--- 1,19 ----
+ // Build don't link:
+ // Origin: schmid@snake.iap.physik.tu-darmstadt.de
+
+ extern "C" int rand (void) throw ();
+
+ namespace std
+ {
+ extern "C" int rand(void) throw();
+ template <class T> void f(T a) {}
+ }
+
+ using namespace std;
+
+ int main()
+ {
+   f(rand);
+   f(std::rand);
+   f(::rand);
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]