C++ PATCH to fix a part of c++/70513 (ICE-on-invalid with enums)

Jason Merrill jason@redhat.com
Wed Apr 20 15:34:00 GMT 2016


On 04/08/2016 07:51 AM, 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".

No, this is misleading; adding the template args wouldn't make the extra 
qualification valid.  We should just give the extra qualification error 
in this case, too.

It might help to move your added check to before we push_scope.

> 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
>



More information about the Gcc-patches mailing list