Patchwork C++ PATCH for c++/56793 (scoped enum in class)

login
register
mail settings
Submitter Jason Merrill
Date April 1, 2013, 9:14 p.m.
Message ID <5159F8CA.4060202@redhat.com>
Download mbox | patch
Permalink /patch/232809/
State New
Headers show

Comments

Jason Merrill - April 1, 2013, 9:14 p.m.
Here, when we saw a.B::Y we got confused because B is not a class.  But 
this seems to me like a reasonable thing to say.

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

Patch

commit 2ea3a64073bdfe37cfd812e5b297fa9831d10e71
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Apr 1 16:16:49 2013 -0400

    	PR c++/56793
    	* typeck.c (finish_class_member_access_expr): Handle enum scope.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 763fc0b..043d52f 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2684,6 +2684,23 @@  finish_class_member_access_expr (tree object, tree name, bool template_p,
 	      return error_mark_node;
 	    }
 
+	  if (TREE_CODE (scope) == ENUMERAL_TYPE)
+	    {
+	      /* Looking up a member enumerator (c++/56793).  */
+	      if (!TYPE_CLASS_SCOPE_P (scope)
+		  || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type))
+		{
+		  if (complain & tf_error)
+		    error ("%<%D::%D%> is not a member of %qT",
+			   scope, name, object_type);
+		  return error_mark_node;
+		}
+	      tree val = lookup_enumerator (scope, name);
+	      if (TREE_SIDE_EFFECTS (object))
+		val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val);
+	      return val;
+	    }
+
 	  gcc_assert (CLASS_TYPE_P (scope));
 	  gcc_assert (identifier_p (name) || TREE_CODE (name) == BIT_NOT_EXPR);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum25.C b/gcc/testsuite/g++.dg/cpp0x/enum25.C
new file mode 100644
index 0000000..cb2cf8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum25.C
@@ -0,0 +1,18 @@ 
+// PR c++/56793
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+  enum struct B {X, Y} b;
+} a;
+
+enum struct D {X,Y};
+struct C { } c;
+
+int main ()
+{
+  if (a.b == a.B::Y)
+    a.b = A::B::X;
+
+  c.D::Y;			// { dg-error "not a member" }
+}