This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH to fix a part of c++/70513 (ICE-on-invalid with enums)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Wed, 20 Apr 2016 12:13:12 +0200
- Subject: Re: C++ PATCH to fix a part of c++/70513 (ICE-on-invalid with enums)
- Authentication-results: sourceware.org; auth=none
- References: <20160408115102 dot GI28445 at redhat dot com>
Ping.
On Fri, Apr 08, 2016 at 01:51:02PM +0200, Marek Polacek wrote:
> This is my attempt to fix at least a part of this PR. I haven't been able to
> come up with a fix that fixes the other part involving templates.
>
> We were ICEing on code such as
>
> struct S
> {
> enum E : int;
> enum S::E : int { foo } e;
> };
>
> Clang rejects this with "extra qualification" error. When I modified the test
> to use structs rather than enums...
>
> struct T
> {
> struct U;
> struct T::U {};
> };
>
> ...I found out that we reject this with "extra qualification not allowed". So
> I think the enum case is missing a similar check that this patch adds.
>
> By the template part of this PR I mean that we ICE on
>
> template <typename T>
> class D
> {
> enum D::A { foo } c;
> };
>
> where clang++ says
> error: template specialization or definition requires a template parameter list
> corresponding to the nested type 'D<T>'
> which I guess means that a valid code would have "<T>" after "D". I thought
> num_template_headers_for_class and cp_parser_check_template_parameters would
> do the job here, but apparently something else needs to be used for this case.
> But I'm at my wits' end here.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2016-04-08 Marek Polacek <polacek@redhat.com>
>
> PR c++/70513
> * parser.c (cp_parser_enum_specifier): Check for extra qualification.
>
> * g++.dg/cpp0x/forw_enum12.C: New test.
>
> diff --git gcc/cp/parser.c gcc/cp/parser.c
> index 28e01af..dc0d1c8 100644
> --- gcc/cp/parser.c
> +++ gcc/cp/parser.c
> @@ -17231,6 +17231,15 @@ cp_parser_enum_specifier (cp_parser* parser)
> type, prev_scope, nested_name_specifier);
> type = error_mark_node;
> }
> + /* If that scope is the scope where the declaration is being placed
> + the program is invalid. */
> + else if (nested_name_specifier == prev_scope)
> + {
> + permerror (type_start_token->location,
> + "extra qualification not allowed");
> + type = error_mark_node;
> + nested_name_specifier = NULL_TREE;
> + }
> }
>
> if (scoped_enum_p)
> diff --git gcc/testsuite/g++.dg/cpp0x/forw_enum12.C gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
> index e69de29..906ba68 100644
> --- gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
> +++ gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
> @@ -0,0 +1,29 @@
> +// PR c++/70513
> +// { dg-do compile { target c++11 } }
> +
> +struct S1
> +{
> + enum E : int;
> + enum S1::E : int { X } e; // { dg-error "extra qualification not allowed" }
> +};
> +
> +struct S2
> +{
> + enum class E : int;
> + enum class S2::E : int { X } e; // { dg-error "extra qualification not allowed" }
> +};
> +
> +struct S3
> +{
> + enum struct E : int;
> + enum struct S3::E : int { X } e; // { dg-error "extra qualification not allowed" }
> +};
> +
> +struct S4
> +{
> + struct S5
> + {
> + enum E : char;
> + enum S4::S5::E : char { X } e; // { dg-error "extra qualification not allowed" }
> + };
> +};
>
> Marek
Marek