c++: Fix ICE with invalid using enum [PR96462]

Here we ICE in finish_nonmember_using_decl -> lookup_using_decl ->
... -> find_namespace_slot because "name" is not an IDENTIFIER_NODE.
It is a BIT_NOT_EXPR because this broken test uses

  using E::~E; // SCOPE::NAME

A using-decl can't refer to a destructor, and lookup_using_decl already
checks that in the class member case.  But in C++17, we do the "enum
scope is the enclosing scope" block, and so scope gets set to ::, and
we go into the NAMESPACE_DECL block.  In C++20 we don't do it, we go
to the ENUMERAL_TYPE block.

I resorted to hoisting the check along with a diagnostic tweak: we
don't want to print "::::~E names destructor".

gcc/cp/ChangeLog:

	PR c++/96462
	* name-lookup.c (lookup_using_decl): Hoist the destructor check.

gcc/testsuite/ChangeLog:

	PR c++/96462
	* g++.dg/cpp2a/using-enum-8.C: New test.
This commit is contained in:
Marek Polacek 2021-02-04 12:53:59 -05:00
parent 6606b852bf
commit 1cbc10d894
2 changed files with 13 additions and 7 deletions

View File

@ -5700,6 +5700,14 @@ lookup_using_decl (tree scope, name_lookup &lookup)
scope = ctx;
}
/* You cannot using-decl a destructor. */
if (TREE_CODE (lookup.name) == BIT_NOT_EXPR)
{
error ("%<%T%s%D%> names destructor", scope,
&"::"[scope == global_namespace ? 2 : 0], lookup.name);
return NULL_TREE;
}
if (TREE_CODE (scope) == NAMESPACE_DECL)
{
/* Naming a namespace member. */
@ -5739,13 +5747,6 @@ lookup_using_decl (tree scope, name_lookup &lookup)
return NULL_TREE;
}
/* You cannot using-decl a destructor. */
if (TREE_CODE (lookup.name) == BIT_NOT_EXPR)
{
error ("%<%T::%D%> names destructor", scope, lookup.name);
return NULL_TREE;
}
/* Using T::T declares inheriting ctors, even if T is a typedef. */
if (lookup.name == TYPE_IDENTIFIER (npscope)
|| constructor_name_p (lookup.name, npscope))

View File

@ -0,0 +1,5 @@
// PR c++/96462
// { dg-do compile { target c++11 } }
enum E {};
using E::~E; // { dg-error "names destructor" }