From d348f172601e946ada34175d77cbccd671d37f18 Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Wed, 27 Mar 2013 14:21:12 -0400
Subject: [PATCH] re PR c++/56749 (weird interaction between scoped enum used
 as non-type template parameter and template lookup)

	PR c++/56749
	* semantics.c (finish_qualified_id_expr): Return early
	for enum scope.

From-SVN: r197166
---
 gcc/cp/ChangeLog                    |  6 +++
 gcc/cp/semantics.c                  |  4 ++
 gcc/testsuite/g++.dg/cpp0x/enum24.C | 57 +++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum24.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5a1cac411244..714522e5fd7f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2013-03-27  Jason Merrill  <jason@redhat.com>
+
+	PR c++/56749
+	* semantics.c (finish_qualified_id_expr): Return early
+	for enum scope.
+
 2013-03-26  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
 	* call.c (build_new_method_call_1): Use INDIRECT_REF_P.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fd77725c254e..72b884ef2e49 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1762,6 +1762,10 @@ finish_qualified_id_expr (tree qualifying_class,
       return expr;
     }
 
+  /* No need to check access within an enum.  */
+  if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE)
+    return expr;
+
   /* Within the scope of a class, turn references to non-static
      members into expression of the form "this->...".  */
   if (template_arg_p)
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum24.C b/gcc/testsuite/g++.dg/cpp0x/enum24.C
new file mode 100644
index 000000000000..60996563f499
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum24.C
@@ -0,0 +1,57 @@
+// PR c++/56749
+// { dg-require-effective-target c++11 }
+
+enum normal_enum
+{
+    not_scoped1,
+    not_scoped2
+};
+
+enum class scoped_enum
+{
+    scoped1,
+    scoped2
+};
+
+template <normal_enum N=not_scoped1>
+class A
+{
+public:
+    template <typename T>
+        void fun ()
+        {
+        }
+};
+
+template <scoped_enum N=scoped_enum::scoped1>
+class B
+{
+public:
+    template <typename T>
+        void fun ()
+        {
+        }
+};
+
+
+template <typename T>
+void tfun ()
+{
+    A<> a;
+    a.fun<char>(); //<------------ THIS IS FINE
+
+    B<> b_defaulted;
+    B<scoped_enum::scoped1> b_explicited;
+
+    b_defaulted.fun<char>();          //<------------ UNEXPECTED: THIS FAILS 
+    b_defaulted.template fun<char>(); //<------------ THIS IS FINE
+
+    b_explicited.fun<char>();         //<------------ UNEXPECTED: THIS FAILS 
+    b_explicited.template fun<char>();//<------------ THIS IS FINE
+}
+
+int main(int argc, char const *argv[])
+{
+    tfun<int>();
+    return 0;
+}
-- 
GitLab