Patchwork C++ PATCH for c++/56749 (wrongly treating scoped enums as dependent)

login
register
mail settings
Submitter Jason Merrill
Date March 27, 2013, 2:41 p.m.
Message ID <51530532.7040707@redhat.com>
Download mbox | patch
Permalink /patch/231722/
State New
Headers show

Comments

Jason Merrill - March 27, 2013, 2:41 p.m.
My change to treat SCOPE_REFs in a template as instantiation-dependent 
due to access issues incorrectly affected scoped enums; we don't need to 
worry about access for them, since there are no access-specifiers in an 
enum.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.8.

Patch

commit 279da5952b411af833810a644ed650a566515a5e
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 27 09:35:35 2013 -0400

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

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index fd77725..72b884e 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 0000000..6099656
--- /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;
+}