aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOllie Wild <aaw@google.com>2007-08-17 21:42:38 +0000
committerOllie Wild <aaw@gcc.gnu.org>2007-08-17 21:42:38 +0000
commit44fd0e80635189f48f24654cb1e9620c39d5314b (patch)
treea410ca7db354fe2d0df4c2e7bd1f54cb516b92c9 /gcc
parent9ab78e532da9b7786956514de5319fc6f9f6450a (diff)
downloadgcc-44fd0e80635189f48f24654cb1e9620c39d5314b.zip
gcc-44fd0e80635189f48f24654cb1e9620c39d5314b.tar.gz
gcc-44fd0e80635189f48f24654cb1e9620c39d5314b.tar.bz2
re PR c++/31749 (ICE with invalid redeclaration of builtin)
PR c++/31749 gcc/cp/ * name-lookup.c (do_nonmember_using_decl): Shift implicit type declarations into appropriate slots for comparison. Fix type comparison. gcc/testsuite/ * g++.dg/lookup/builtin3.C: New test. * g++.dg/lookup/builtin4.C: New test. * g++.dg/lookup/using19.C: New test. From-SVN: r127600
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/name-lookup.c163
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/lookup/builtin3.C15
-rw-r--r--gcc/testsuite/g++.dg/lookup/builtin4.C15
-rw-r--r--gcc/testsuite/g++.dg/lookup/using19.C21
6 files changed, 157 insertions, 71 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f01075d..9556496 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2007-08-17 Ollie Wild <aaw@google.com>
+
+ PR c++/31749
+ * name-lookup.c (do_nonmember_using_decl): Shift implicit type
+ declarations into appropriate slots for comparison. Fix type
+ comparison.
+
2007-08-17 Paolo Carlini <pcarlini@suse.de>
PR c++/32112
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 48b387a..5f7e718 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2099,6 +2099,20 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
return;
}
+ /* Shift the old and new bindings around so we're comparing class and
+ enumeration names to each other. */
+ if (oldval && DECL_IMPLICIT_TYPEDEF_P (oldval))
+ {
+ oldtype = oldval;
+ oldval = NULL_TREE;
+ }
+
+ if (decls.value && DECL_IMPLICIT_TYPEDEF_P (decls.value))
+ {
+ decls.type = decls.value;
+ decls.value = NULL_TREE;
+ }
+
/* It is impossible to overload a built-in function; any explicit
declaration eliminates the built-in declaration. So, if OLDVAL
is a built-in, then we can just pretend it isn't there. */
@@ -2108,87 +2122,91 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
&& !DECL_HIDDEN_FRIEND_P (oldval))
oldval = NULL_TREE;
- /* Check for using functions. */
- if (decls.value && is_overloaded_fn (decls.value))
+ if (decls.value)
{
- tree tmp, tmp1;
-
- if (oldval && !is_overloaded_fn (oldval))
- {
- if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
- error ("%qD is already declared in this scope", name);
- oldval = NULL_TREE;
- }
-
- *newval = oldval;
- for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
+ /* Check for using functions. */
+ if (is_overloaded_fn (decls.value))
{
- tree new_fn = OVL_CURRENT (tmp);
+ tree tmp, tmp1;
- /* [namespace.udecl]
+ if (oldval && !is_overloaded_fn (oldval))
+ {
+ error ("%qD is already declared in this scope", name);
+ oldval = NULL_TREE;
+ }
- If a function declaration in namespace scope or block
- scope has the same name and the same parameter types as a
- function introduced by a using declaration the program is
- ill-formed. */
- for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+ *newval = oldval;
+ for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
{
- tree old_fn = OVL_CURRENT (tmp1);
-
- if (new_fn == old_fn)
- /* The function already exists in the current namespace. */
- break;
- else if (OVL_USED (tmp1))
- continue; /* this is a using decl */
- else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ tree new_fn = OVL_CURRENT (tmp);
+
+ /* [namespace.udecl]
+
+ If a function declaration in namespace scope or block
+ scope has the same name and the same parameter types as a
+ function introduced by a using declaration the program is
+ ill-formed. */
+ for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
{
- gcc_assert (!DECL_ANTICIPATED (old_fn)
- || DECL_HIDDEN_FRIEND_P (old_fn));
+ tree old_fn = OVL_CURRENT (tmp1);
- /* There was already a non-using declaration in
- this scope with the same parameter types. If both
- are the same extern "C" functions, that's ok. */
- if (decls_match (new_fn, old_fn))
+ if (new_fn == old_fn)
+ /* The function already exists in the current namespace. */
break;
- else
+ else if (OVL_USED (tmp1))
+ continue; /* this is a using decl */
+ else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
{
- error ("%qD is already declared in this scope", name);
- break;
+ gcc_assert (!DECL_ANTICIPATED (old_fn)
+ || DECL_HIDDEN_FRIEND_P (old_fn));
+
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. If both
+ are the same extern "C" functions, that's ok. */
+ if (decls_match (new_fn, old_fn))
+ break;
+ else
+ {
+ error ("%qD is already declared in this scope", name);
+ break;
+ }
}
}
- }
-
- /* If we broke out of the loop, there's no reason to add
- this function to the using declarations for this
- scope. */
- if (tmp1)
- continue;
- /* If we are adding to an existing OVERLOAD, then we no
- longer know the type of the set of functions. */
- if (*newval && TREE_CODE (*newval) == OVERLOAD)
- TREE_TYPE (*newval) = unknown_type_node;
- /* Add this new function to the set. */
- *newval = build_overload (OVL_CURRENT (tmp), *newval);
- /* If there is only one function, then we use its type. (A
- using-declaration naming a single function can be used in
- contexts where overload resolution cannot be
- performed.) */
- if (TREE_CODE (*newval) != OVERLOAD)
- {
- *newval = ovl_cons (*newval, NULL_TREE);
- TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+ /* If we broke out of the loop, there's no reason to add
+ this function to the using declarations for this
+ scope. */
+ if (tmp1)
+ continue;
+
+ /* If we are adding to an existing OVERLOAD, then we no
+ longer know the type of the set of functions. */
+ if (*newval && TREE_CODE (*newval) == OVERLOAD)
+ TREE_TYPE (*newval) = unknown_type_node;
+ /* Add this new function to the set. */
+ *newval = build_overload (OVL_CURRENT (tmp), *newval);
+ /* If there is only one function, then we use its type. (A
+ using-declaration naming a single function can be used in
+ contexts where overload resolution cannot be
+ performed.) */
+ if (TREE_CODE (*newval) != OVERLOAD)
+ {
+ *newval = ovl_cons (*newval, NULL_TREE);
+ TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+ }
+ OVL_USED (*newval) = 1;
}
- OVL_USED (*newval) = 1;
+ }
+ else
+ {
+ *newval = decls.value;
+ if (oldval && !decls_match (*newval, oldval))
+ error ("%qD is already declared in this scope", name);
}
}
else
- {
- *newval = decls.value;
- if (oldval && !decls_match (*newval, oldval))
- error ("%qD is already declared in this scope", name);
- }
+ *newval = oldval;
if (decls.type && TREE_CODE (decls.type) == TREE_LIST)
{
@@ -2198,13 +2216,16 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
else
{
*newtype = decls.type;
- if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
- {
- error ("using declaration %qD introduced ambiguous type %qT",
- name, oldtype);
- return;
- }
+ if (oldtype && *newtype && !decls_match (oldtype, *newtype))
+ error ("%qD is already declared in this scope", name);
}
+
+ /* If *newval is empty, shift any class or enumeration name down. */
+ if (!*newval)
+ {
+ *newval = *newtype;
+ *newtype = NULL_TREE;
+ }
}
/* Process a using-declaration at function scope. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e08a327..2a637d5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2007-08-17 Ollie Wild <aaw@google.com>
+
+ PR c++/31749
+ * g++.dg/lookup/builtin3.C: New test.
+ * g++.dg/lookup/builtin4.C: New test.
+ * g++.dg/lookup/using19.C: New test.
+
2007-08-17 Paolo Carlini <pcarlini@suse.de>
PR c++/32190
diff --git a/gcc/testsuite/g++.dg/lookup/builtin3.C b/gcc/testsuite/g++.dg/lookup/builtin3.C
new file mode 100644
index 0000000..3a29d87
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/builtin3.C
@@ -0,0 +1,15 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+// { dg-do compile }
+
+// PR 31749: ICE with redeclaration of builtin
+
+namespace std
+{
+ union abort;
+}
+
+void abort();
+
+using std::abort;
diff --git a/gcc/testsuite/g++.dg/lookup/builtin4.C b/gcc/testsuite/g++.dg/lookup/builtin4.C
new file mode 100644
index 0000000..b1785dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/builtin4.C
@@ -0,0 +1,15 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+// { dg-do compile }
+
+// PR 31749: ICE with redeclaration of builtin
+
+namespace std
+{
+ union abort;
+}
+
+union abort;
+
+using std::abort; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/lookup/using19.C b/gcc/testsuite/g++.dg/lookup/using19.C
new file mode 100644
index 0000000..973998b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/using19.C
@@ -0,0 +1,21 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+
+// C++ Standard, 7.3.3, clause 10:
+// "Since a using-declaration is a declaration, the restrictions on
+// declarations of the same name in the same declarative region (3.3) also
+// apply to using-declarations."
+
+namespace M
+{
+ union A;
+ void B();
+}
+
+void A();
+union B;
+
+using M::A;
+using M::B;