aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2001-11-30 03:14:56 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2001-11-30 03:14:56 +0000
commit998979e6dc20eb1b72f6f9a1a818ae28d07d8721 (patch)
tree00ba049e16648fa9a3aa0326b1882987e7088f80 /gcc
parentfc6e87b33f1c961ded126986990048eb7120557a (diff)
downloadgcc-998979e6dc20eb1b72f6f9a1a818ae28d07d8721.zip
gcc-998979e6dc20eb1b72f6f9a1a818ae28d07d8721.tar.gz
gcc-998979e6dc20eb1b72f6f9a1a818ae28d07d8721.tar.bz2
re PR c++/3048 (Lookup problem (gcc 2.95 regression))
2001-11-29 Mark Mitchell <mark@codesourcery.com> PR c++/3048 * cp-tree.h (ovl_member): Remove. * decl2.c (merge_functions): Handle extern "C" functions specially. * tree.c (ovl_member): Remove. From-SVN: r47474
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl2.c23
-rw-r--r--gcc/cp/tree.c17
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/externC5.C19
5 files changed, 47 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0177bc9..be25153 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
2001-11-29 Mark Mitchell <mark@codesourcery.com>
+ PR c++/3048
+ * cp-tree.h (ovl_member): Remove.
+ * decl2.c (merge_functions): Handle extern "C" functions
+ specially.
+ * tree.c (ovl_member): Remove.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
PR c++/4842
* class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
FUNCTION_DECL, as input.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b7cfa70..4b6dd33 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4194,7 +4194,6 @@ extern int is_overloaded_fn PARAMS ((tree));
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 function_arg_chain PARAMS ((tree));
extern int promotes_to_aggr_type PARAMS ((tree, enum tree_code));
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c316da0..737d295 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4146,9 +4146,26 @@ merge_functions (s1, s2)
{
for (; s2; s2 = OVL_NEXT (s2))
{
- tree fn = OVL_CURRENT (s2);
- if (! ovl_member (fn, s1))
- s1 = build_overload (fn, s1);
+ 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;
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 99d2eab..600c6e3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -981,23 +981,6 @@ build_overload (decl, chain)
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;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/externC5.C b/gcc/testsuite/g++.old-deja/g++.other/externC5.C
new file mode 100644
index 0000000..aadbc5a
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/externC5.C
@@ -0,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);
+}