aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-06-19 19:11:31 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-06-19 19:11:31 +0000
commit5ec046c03624e39858314bd35eb0c06f8e63bd28 (patch)
tree00c40f39d2e310494370a6fc0d4ec1fa9e4ddfee
parentc72e002cc34657b86bf99ca68f3ba0fdbfc32df6 (diff)
downloadgcc-5ec046c03624e39858314bd35eb0c06f8e63bd28.zip
gcc-5ec046c03624e39858314bd35eb0c06f8e63bd28.tar.gz
gcc-5ec046c03624e39858314bd35eb0c06f8e63bd28.tar.bz2
re PR c++/81124 (internal compiler error: in operator*, at cp/cp-tree.h:726)
PR c++/81124 PR c++/79766 * name-lookup.c (set_decl_namespace): Don't follow using directives and ignore using decls. Only check overly-explicit scope after discovering decl. * g++.dg/lookup/pr79766.C: New. * g++.dg/lookup/pr81124.C: New. * g++.dg/template/explicit6.C: Adjust. * g++.old-deja/g++.other/decl5.C: Adjust. From-SVN: r249385
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/name-lookup.c115
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr79766.C29
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr81124.C11
-rw-r--r--gcc/testsuite/g++.dg/template/explicit6.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/decl5.C4
7 files changed, 118 insertions, 60 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 55ba486..b80d373 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2017-06-19 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/81124
+ PR c++/79766
+ * name-lookup.c (set_decl_namespace): Don't follow using
+ directives and ignore using decls. Only check overly-explicit
+ scope after discovering decl.
+
2017-06-19 Jason Merrill <jason@redhat.com>
PR c++/81073 - constexpr and static var in statement-expression.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index a337942..e91b89c 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4266,8 +4266,6 @@ set_global_binding (tree name, tree val)
void
set_decl_namespace (tree decl, tree scope, bool friendp)
{
- tree old;
-
/* Get rid of namespace aliases. */
scope = ORIGINAL_NAMESPACE (scope);
@@ -4277,41 +4275,49 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
decl, scope);
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
- /* Writing "int N::i" to declare a variable within "N" is invalid. */
- if (scope == current_namespace)
- {
- if (at_namespace_scope_p ())
- error ("explicit qualification in declaration of %qD",
- decl);
- return;
- }
+ /* See whether this has been declared in the namespace or inline
+ children. */
+ tree old = NULL_TREE;
+ {
+ name_lookup lookup (DECL_NAME (decl), LOOKUP_HIDDEN);
+ if (!lookup.search_qualified (scope, /*usings=*/false))
+ /* No old declaration at all. */
+ goto not_found;
+ old = lookup.value;
+ }
- /* See whether this has been declared in the namespace. */
- old = lookup_qualified_name (scope, DECL_NAME (decl), /*type*/false,
- /*complain*/true, /*hidden*/true);
- if (old == error_mark_node)
- /* No old declaration at all. */
- goto complain;
/* If it's a TREE_LIST, the result of the lookup was ambiguous. */
if (TREE_CODE (old) == TREE_LIST)
{
+ ambiguous:
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
error ("reference to %qD is ambiguous", decl);
print_candidates (old);
return;
}
- if (!OVL_P (decl))
+
+ if (!DECL_DECLARES_FUNCTION_P (decl))
{
- /* We might have found OLD in an inline namespace inside SCOPE. */
- if (TREE_CODE (decl) == TREE_CODE (old))
- DECL_CONTEXT (decl) = DECL_CONTEXT (old);
/* Don't compare non-function decls with decls_match here, since
it can't check for the correct constness at this
- point. pushdecl will find those errors later. */
+ point. pushdecl will find those errors later. */
+
+ /* We might have found it in an inline namespace child of SCOPE. */
+ if (TREE_CODE (decl) == TREE_CODE (old))
+ DECL_CONTEXT (decl) = DECL_CONTEXT (old);
+
+ found:
+ /* Writing "N::i" to declare something directly in "N" is invalid. */
+ if (CP_DECL_CONTEXT (decl) == current_namespace
+ && at_namespace_scope_p ())
+ error ("explicit qualification in declaration of %qD", decl);
return;
}
+
/* Since decl is a function, old should contain a function decl. */
if (!OVL_P (old))
- goto complain;
+ goto not_found;
+
/* We handle these in check_explicit_instantiation_namespace. */
if (processing_explicit_instantiation)
return;
@@ -4325,53 +4331,48 @@ set_decl_namespace (tree decl, tree scope, bool friendp)
friends in any namespace. */
if (friendp && DECL_USE_TEMPLATE (decl))
return;
- if (OVL_P (old))
+
+ tree found;
+ found = NULL_TREE;
+
+ for (lkp_iterator iter (old); iter; ++iter)
{
- tree found = NULL_TREE;
+ if (iter.using_p ())
+ continue;
- for (ovl_iterator iter (old); iter; ++iter)
- {
- tree ofn = *iter;
- /* Adjust DECL_CONTEXT first so decls_match will return true
- if DECL will match a declaration in an inline namespace. */
- DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
- if (decls_match (decl, ofn))
- {
- if (found && !decls_match (found, ofn))
- {
- DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
- error ("reference to %qD is ambiguous", decl);
- print_candidates (old);
- return;
- }
- found = ofn;
- }
- }
- if (found)
+ tree ofn = *iter;
+
+ /* Adjust DECL_CONTEXT first so decls_match will return true
+ if DECL will match a declaration in an inline namespace. */
+ DECL_CONTEXT (decl) = DECL_CONTEXT (ofn);
+ if (decls_match (decl, ofn))
{
- if (!is_nested_namespace (scope, CP_DECL_CONTEXT (found), true))
- goto complain;
- if (DECL_HIDDEN_FRIEND_P (found))
+ if (found)
{
- pedwarn (DECL_SOURCE_LOCATION (decl), 0,
- "%qD has not been declared within %qD", decl, scope);
- inform (DECL_SOURCE_LOCATION (found),
- "only here as a %<friend%>");
+ /* We found more than one matching declaration. */
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ goto ambiguous;
}
- DECL_CONTEXT (decl) = DECL_CONTEXT (found);
- return;
+ found = ofn;
}
}
- else
+
+ if (found)
{
- DECL_CONTEXT (decl) = DECL_CONTEXT (old);
- if (decls_match (decl, old))
- return;
+ if (DECL_HIDDEN_FRIEND_P (found))
+ {
+ pedwarn (DECL_SOURCE_LOCATION (decl), 0,
+ "%qD has not been declared within %qD", decl, scope);
+ inform (DECL_SOURCE_LOCATION (found),
+ "only here as a %<friend%>");
+ }
+ DECL_CONTEXT (decl) = DECL_CONTEXT (found);
+ goto found;
}
+ not_found:
/* It didn't work, go back to the explicit scope. */
DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
- complain:
error ("%qD should have been declared inside %qD", decl, scope);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 80ebf57..3c17355 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2017-06-19 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/81124
+ PR c++/79766
+ * g++.dg/lookup/pr79766.C: New.
+ * g++.dg/lookup/pr81124.C: New.
+ * g++.dg/template/explicit6.C: Adjust.
+ * g++.old-deja/g++.other/decl5.C: Adjust.
+
2017-06-19 Christophe Lyon <christophe.lyon@linaro.org>
* g++.old-deja/g++.eh/badalloc1.C: Remove code path for
diff --git a/gcc/testsuite/g++.dg/lookup/pr79766.C b/gcc/testsuite/g++.dg/lookup/pr79766.C
new file mode 100644
index 0000000..de9bbb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/pr79766.C
@@ -0,0 +1,29 @@
+// { dg-do compile { target c++11 } }
+// PR 79766 qualified name to find inline namespace is ok
+
+namespace Y
+{
+ inline namespace X
+ {
+ void Q ();
+ }
+}
+
+void Y::Q () // OK -> Y::X::Q
+{
+}
+
+inline namespace Z
+{
+ void R ();
+}
+
+void ::R () // OK -> Z::R
+{
+}
+
+void S ();
+
+void ::S () // { dg-error "explicit qualification" }
+{
+}
diff --git a/gcc/testsuite/g++.dg/lookup/pr81124.C b/gcc/testsuite/g++.dg/lookup/pr81124.C
new file mode 100644
index 0000000..d80d88a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/pr81124.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+// c++/81124 ICE with inline namespace
+
+namespace std {
+inline namespace {
+int to_string();
+void to_string(int);
+}
+void to_string();
+}
+int std::to_string();
diff --git a/gcc/testsuite/g++.dg/template/explicit6.C b/gcc/testsuite/g++.dg/template/explicit6.C
index a28fd9e..24fa50d 100644
--- a/gcc/testsuite/g++.dg/template/explicit6.C
+++ b/gcc/testsuite/g++.dg/template/explicit6.C
@@ -5,4 +5,4 @@
// Bug 19895: ICE on invalid
struct A;
-template A<>::A(); // { dg-error "(not a template)|(explicit qualification)" }
+template A<>::A(); // { dg-error "(should have been)|(not a template)" }
diff --git a/gcc/testsuite/g++.old-deja/g++.other/decl5.C b/gcc/testsuite/g++.old-deja/g++.other/decl5.C
index 9167061..3ac9137 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/decl5.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/decl5.C
@@ -53,8 +53,8 @@ namespace N {
namespace NMS
{
- void NMS::fn(); // { dg-error "explicit qual" }
- int NMS::i; // { dg-error "explicit qual" }
+ void NMS::fn(); // { dg-error "should have been" }
+ int NMS::i; // { dg-error "should have been" }
struct NMS::D { // { dg-error "does not name a class" }
int i;
};