* decl.c (start_enum): Do compare dependent underlying type.
authorJason Merrill <jason@redhat.com>
Fri, 15 Jun 2018 20:22:55 +0000 (16:22 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 15 Jun 2018 20:22:55 +0000 (16:22 -0400)
From-SVN: r261655

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/name-lookup.h
gcc/testsuite/g++.dg/cpp0x/forw_enum10.C
gcc/testsuite/g++.dg/cpp0x/forw_enum7.C
gcc/testsuite/g++.dg/cpp0x/forw_enum8.C

index f6c69087ce28a6e71f2a5573398ab6ee02535dd6..d8ce66eb22c401187b60e0f4339867575c4c287d 100644 (file)
@@ -1,5 +1,7 @@
 2018-06-15  Jason Merrill  <jason@redhat.com>
 
+       * decl.c (start_enum): Do compare dependent underlying type.
+
        PR c++/82882 - ICE with lambda in template default argument.
        * lambda.c (record_null_lambda_scope): New.
        * pt.c (tsubst_lambda_expr): Use it.
index 98dea9b766fc80defbe48db31d81129aba6628b0..d7df01289db4dc5c2667b0f5e0ff7dc48dac8b72 100644 (file)
@@ -14131,8 +14131,6 @@ start_enum (tree name, tree enumtype, tree underlying_type,
          enumtype = error_mark_node;
        }
       else if (underlying_type && ENUM_UNDERLYING_TYPE (enumtype)
-              && !dependent_type_p (underlying_type)
-              && !dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))
               && !same_type_p (underlying_type,
                                ENUM_UNDERLYING_TYPE (enumtype)))
        {
@@ -14157,7 +14155,7 @@ start_enum (tree name, tree enumtype, tree underlying_type,
 
       /* enumtype may be an ENUMERAL_TYPE if this is a redefinition
          of an opaque enum, or an opaque enum of an already defined
-        enumeration (C++0x only).
+        enumeration (C++11).
         In any other case, it'll be NULL_TREE. */
       if (!enumtype)
        {
@@ -14166,14 +14164,9 @@ start_enum (tree name, tree enumtype, tree underlying_type,
        }
       prevtype = enumtype;
 
-      /* Do not push the decl more than once, unless we need to
-        compare underlying types at instantiation time */
+      /* Do not push the decl more than once.  */
       if (!enumtype
-         || TREE_CODE (enumtype) != ENUMERAL_TYPE
-         || (underlying_type
-             && dependent_type_p (underlying_type))
-         || (ENUM_UNDERLYING_TYPE (enumtype)
-             && dependent_type_p (ENUM_UNDERLYING_TYPE (enumtype))))
+         || TREE_CODE (enumtype) != ENUMERAL_TYPE)
        {
          enumtype = cxx_make_type (ENUMERAL_TYPE);
          enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
index ae225db3ba5499c25c4c9bc5b629c0477da30277..2bda0f11d1d96a31923fcd3b9c31b2585e4e0633 100644 (file)
@@ -112,7 +112,7 @@ enum scope_kind {
                        of an if or switch statement.  */
   sk_function_parms, /* The scope containing function parameters.  */
   sk_class,         /* The scope containing the members of a class.  */
-  sk_scoped_enum,    /* The scope containing the enumertors of a C++0x
+  sk_scoped_enum,    /* The scope containing the enumerators of a C++11
                         scoped enumeration.  */
   sk_namespace,             /* The scope containing the members of a
                        namespace, including the global scope.  */
index 3c4c3de6d6615746e89b31586930f3a351e4c7f9..e5d8e49537c23cafcd4750bad30177b21c643279 100644 (file)
@@ -6,7 +6,7 @@ template<typename T> struct S1
     enum E : T;   // { dg-message "previous definition" }
     enum E : int;     // { dg-error "different underlying type" }
 };
-template struct S1<short>; // { dg-message "required from here" }
+template struct S1<short>;
 
 template<typename T> struct S2
 {
@@ -17,8 +17,8 @@ template struct S2<short>;
 
 template<typename T1, typename T2> struct S3
 {
-    enum E : T1;
-    enum E : T2;
+    enum E : T1;               // { dg-message "previous definition" }
+    enum E : T2;               // { dg-error "different underlying type" }
 };
 template struct S3<short,short>;
 
@@ -27,4 +27,4 @@ template<typename T1, typename T2> struct S4
     enum E : T1; // { dg-message "previous definition" }
     enum E : T2; // { dg-error "different underlying type" }
 };
-template struct S4<short,char>; // { dg-message "required from here" }
+template struct S4<short,char>;
index 3c67f547057c06d5c3923f157ab7c5b8edcd4cc9..d43bbc1caf2c09d954756946de64f7c270fa21ba 100644 (file)
@@ -4,8 +4,6 @@
 template<typename T> struct S1
 {
     enum E1 : int;
-    enum E1 : T;
-    enum class E2 : int;
     enum class E2 : T;
 };
 
index b84a759c6de55cf0978ee67e991a4f78fac189fb..3f06cd4bd670bcca53d263a99892291fd8c1451a 100644 (file)
@@ -1,22 +1,19 @@
 // { dg-do compile { target c++11 } }
 
-//This instatiation is ok
 template<typename T> struct S1
 {
-    enum E : int;
-    enum E : T;
+    enum E : int;   // { dg-message "previous definition" }
+    enum E : T;     // { dg-error "different underlying type" }
 };
 template struct S1<int>; //ok
 
-//This error is diagnosed at instantiation time
 template<typename T> struct S2
 {
     enum E : int;   // { dg-message "previous definition" }
     enum E : T;     // { dg-error "different underlying type" }
 };
-template struct S2<short>; // { dg-message "required from here" }
+template struct S2<short>;
 
-//This error is diagnosed at compilation time
 template<typename T> struct S3
 {
     enum E : int;   // { dg-message "previous definition" }