aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/name-lookup.c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2021-01-14 22:14:38 -0500
committerMarek Polacek <polacek@redhat.com>2021-01-19 17:13:00 -0500
commitd89b00c095e99cd5cb6d3e05f30d3a61fa592000 (patch)
tree88c70d0ec39f9ee8978aea8ff133a4deed603301 /gcc/cp/name-lookup.c
parent9693e255ee2536c6823640eba5d0163c2b401161 (diff)
downloadgcc-d89b00c095e99cd5cb6d3e05f30d3a61fa592000.zip
gcc-d89b00c095e99cd5cb6d3e05f30d3a61fa592000.tar.gz
gcc-d89b00c095e99cd5cb6d3e05f30d3a61fa592000.tar.bz2
c++: ICE with USING_DECL redeclaration [PR98687]
My recent patch that introduced push_using_decl_bindings didn't handle USING_DECL redeclaration, therefore things broke. This patch amends that by breaking out a part of finish_nonmember_using_decl out to a separate function, push_using_decl_bindings, and calling it. It needs an overload, because name_lookup is only available inside of name-lookup.c. gcc/cp/ChangeLog: PR c++/98687 * name-lookup.c (push_using_decl_bindings): New, broken out of... (finish_nonmember_using_decl): ...here. * name-lookup.h (push_using_decl_bindings): Update declaration. * pt.c (tsubst_expr): Update the call to push_using_decl_bindings. gcc/testsuite/ChangeLog: PR c++/98687 * g++.dg/lookup/using64.C: New test. * g++.dg/lookup/using65.C: New test.
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r--gcc/cp/name-lookup.c103
1 files changed, 56 insertions, 47 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index b4b6c0b..843e5f3 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6279,6 +6279,61 @@ pushdecl_namespace_level (tree x, bool hiding)
return t;
}
+/* Wrapper around push_local_binding to push the bindings for
+ a non-member USING_DECL with NAME and VALUE. LOOKUP, if non-null,
+ is the result of name lookup during template parsing. */
+
+static void
+push_using_decl_bindings (name_lookup *lookup, tree name, tree value)
+{
+ tree type = NULL_TREE;
+
+ cxx_binding *binding = find_local_binding (current_binding_level, name);
+ if (binding)
+ {
+ value = binding->value;
+ type = binding->type;
+ }
+
+ /* DR 36 questions why using-decls at function scope may not be
+ duplicates. Disallow it, as C++11 claimed and PR 20420
+ implemented. */
+ if (lookup)
+ do_nonmember_using_decl (*lookup, true, true, &value, &type);
+
+ if (!value)
+ ;
+ else if (binding && value == binding->value)
+ /* Redeclaration of this USING_DECL. */;
+ else if (binding && binding->value && TREE_CODE (value) == OVERLOAD)
+ {
+ /* We already have this binding, so replace it. */
+ update_local_overload (IDENTIFIER_BINDING (name), value);
+ IDENTIFIER_BINDING (name)->value = value;
+ }
+ else
+ /* Install the new binding. */
+ push_local_binding (name, value, /*using=*/true);
+
+ if (!type)
+ ;
+ else if (binding && type == binding->type)
+ ;
+ else
+ {
+ push_local_binding (name, type, /*using=*/true);
+ set_identifier_type_value (name, type);
+ }
+}
+
+/* Overload for push_using_decl_bindings that doesn't take a name_lookup. */
+
+void
+push_using_decl_bindings (tree name, tree value)
+{
+ push_using_decl_bindings (nullptr, name, value);
+}
+
/* Process a using declaration in non-class scope. */
void
@@ -6395,43 +6450,7 @@ finish_nonmember_using_decl (tree scope, tree name)
else
{
add_decl_expr (using_decl);
-
- cxx_binding *binding = find_local_binding (current_binding_level, name);
- tree value = NULL;
- tree type = NULL;
- if (binding)
- {
- value = binding->value;
- type = binding->type;
- }
-
- /* DR 36 questions why using-decls at function scope may not be
- duplicates. Disallow it, as C++11 claimed and PR 20420
- implemented. */
- do_nonmember_using_decl (lookup, true, true, &value, &type);
-
- if (!value)
- ;
- else if (binding && value == binding->value)
- ;
- else if (binding && binding->value && TREE_CODE (value) == OVERLOAD)
- {
- update_local_overload (IDENTIFIER_BINDING (name), value);
- IDENTIFIER_BINDING (name)->value = value;
- }
- else
- /* Install the new binding. */
- push_local_binding (name, value, true);
-
- if (!type)
- ;
- else if (binding && type == binding->type)
- ;
- else
- {
- push_local_binding (name, type, true);
- set_identifier_type_value (name, type);
- }
+ push_using_decl_bindings (&lookup, name, NULL_TREE);
}
}
@@ -9279,14 +9298,4 @@ push_operator_bindings ()
}
}
-/* Wrapper around push_local_binding to push the bindings for
- a non-member USING_DECL DECL that was found during template parsing. */
-
-void
-push_using_decl_bindings (tree decl)
-{
- push_local_binding (DECL_NAME (decl), USING_DECL_DECLS (decl),
- /*using*/true);
-}
-
#include "gt-cp-name-lookup.h"