public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ Patch] PR 57734
@ 2013-11-12  4:41 Paolo Carlini
  2013-11-12  7:14 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Paolo Carlini @ 2013-11-12  4:41 UTC (permalink / raw)
  To: gcc-patches, Jason Merrill

[-- Attachment #1: Type: text/plain, Size: 669 bytes --]

Hi,

this issue points out that we aren't handling correctly alias template 
declarations of enums. The core problem in lookup_template_class_1 is 
easy to spot: we check for (and handle) TREE_CODE (template_type) == 
ENUMERAL_TYPE *before* DECL_ALIAS_TEMPLATE_P (gen_tmpl). Besides this 
more or less straightforward change, in the patchlet I also have to 
avoid calling tsubst_enum (otherwise we immediately have duplicate 
declarations for the enumerators of unscoped enums, and all sorts of 
troubles: I tried to cover in the extended testcase some of the weird 
things I was seeing earlier today ;) Tested x86_64-linux.

Thanks!
Paolo.

//////////////////////////

[-- Attachment #2: CL_57734 --]
[-- Type: text/plain, Size: 289 bytes --]

/cp
2013-11-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57734
	* pt.c (lookup_template_class_1): Handle alias template declarations
	of enumeration types.

/testsuite
2013-11-12  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/57734
	* g++.dg/cpp0x/alias-decl-enum-1.C: New.

[-- Attachment #3: patch_57734 --]
[-- Type: text/plain, Size: 4701 bytes --]

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 204674)
+++ cp/pt.c	(working copy)
@@ -7458,31 +7458,8 @@ lookup_template_class_1 (tree d1, tree arglist, tr
 	context = global_namespace;
 
       /* Create the type.  */
-      if (TREE_CODE (template_type) == ENUMERAL_TYPE)
+      if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
 	{
-	  if (!is_dependent_type)
-	    {
-	      set_current_access_from_decl (TYPE_NAME (template_type));
-	      t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE,
-			      tsubst (ENUM_UNDERLYING_TYPE (template_type),
-				      arglist, complain, in_decl),
-			      SCOPED_ENUM_P (template_type), NULL);
-	    }
-	  else
-            {
-              /* We don't want to call start_enum for this type, since
-                 the values for the enumeration constants may involve
-                 template parameters.  And, no one should be interested
-                 in the enumeration constants for such a type.  */
-              t = cxx_make_type (ENUMERAL_TYPE);
-              SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
-            }
-          SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type));
-	  ENUM_FIXED_UNDERLYING_TYPE_P (t)
-	    = ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
-	}
-      else if (DECL_ALIAS_TEMPLATE_P (gen_tmpl))
-	{
 	  /* The user referred to a specialization of an alias
 	    template represented by GEN_TMPL.
 
@@ -7505,6 +7482,29 @@ lookup_template_class_1 (tree d1, tree arglist, tr
 	  if (t == error_mark_node)
 	    return t;
 	}
+      else if (TREE_CODE (template_type) == ENUMERAL_TYPE)
+	{
+	  if (!is_dependent_type)
+	    {
+	      set_current_access_from_decl (TYPE_NAME (template_type));
+	      t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE,
+			      tsubst (ENUM_UNDERLYING_TYPE (template_type),
+				      arglist, complain, in_decl),
+			      SCOPED_ENUM_P (template_type), NULL);
+	    }
+	  else
+            {
+              /* We don't want to call start_enum for this type, since
+                 the values for the enumeration constants may involve
+                 template parameters.  And, no one should be interested
+                 in the enumeration constants for such a type.  */
+              t = cxx_make_type (ENUMERAL_TYPE);
+              SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type));
+            }
+          SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type));
+	  ENUM_FIXED_UNDERLYING_TYPE_P (t)
+	    = ENUM_FIXED_UNDERLYING_TYPE_P (template_type);
+	}
       else if (CLASS_TYPE_P (template_type))
 	{
 	  t = make_class_type (TREE_CODE (template_type));
@@ -7661,7 +7661,8 @@ lookup_template_class_1 (tree d1, tree arglist, tr
 	= tree_cons (arglist, t,
 		     DECL_TEMPLATE_INSTANTIATIONS (templ));
 
-      if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type)
+      if (TREE_CODE (template_type) == ENUMERAL_TYPE && !is_dependent_type
+	  && !DECL_ALIAS_TEMPLATE_P (gen_tmpl))
 	/* Now that the type has been registered on the instantiations
 	   list, we set up the enumerators.  Because the enumeration
 	   constants may involve the enumeration type itself, we make
Index: testsuite/g++.dg/cpp0x/alias-decl-enum-1.C
===================================================================
--- testsuite/g++.dg/cpp0x/alias-decl-enum-1.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/alias-decl-enum-1.C	(working copy)
@@ -0,0 +1,47 @@
+// PR c++/57734
+// { dg-do compile { target c++11 } }
+
+template<typename T, typename U>
+struct same_type { static const bool value = false; };
+
+template<typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+enum e { zero };
+enum class eclass { one };
+
+template<typename T>
+using enum_alias = e;
+
+template<typename T>
+using eclass_alias = eclass;
+
+typedef enum_alias<void> etest0;
+typedef enum_alias<void> etest0;
+typedef enum_alias<int>  etest0;
+typedef enum_alias<int>  etest1;
+
+static_assert (same_type<etest0, etest1>::value, "");
+
+typedef eclass_alias<void> ectest0;
+typedef eclass_alias<void> ectest0;
+typedef eclass_alias<int>  ectest0;
+typedef eclass_alias<int>  ectest1;
+
+static_assert (same_type<ectest0, ectest1>::value, "");
+
+template<typename T>
+enum_alias<T> efoo(T f) { return enum_alias<T>::zero; }
+
+template<typename T>
+constexpr enum_alias<T> cefoo(T f) { return enum_alias<T>::zero; }
+
+static_assert ( cefoo(1) == e::zero, "");
+
+template<typename T>
+eclass_alias<T> ecfoo(T f) { return eclass_alias<T>::one; }
+
+template<typename T>
+constexpr eclass_alias<T> cecfoo(T f) { return eclass_alias<T>::one; }
+
+static_assert ( cecfoo(1) == eclass::one, "");

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [C++ Patch] PR 57734
  2013-11-12  4:41 [C++ Patch] PR 57734 Paolo Carlini
@ 2013-11-12  7:14 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2013-11-12  7:14 UTC (permalink / raw)
  To: Paolo Carlini, gcc-patches

OK.

Jason

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-11-12  1:52 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-12  4:41 [C++ Patch] PR 57734 Paolo Carlini
2013-11-12  7:14 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).