This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR3048
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Nov 2001 19:06:36 -0800
- Subject: 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);
+ }