retrofit_lang_decl now wants to look at the DECL_CONTEXT of an enumerator, but we were calling it before setting the context. The comment before the call to build_lang_decl_loc mentions DECL_CLASS_CONTEXT, but that macro doesn't use DECL_LANG_SPECIFIC anymore, so I decided to check whether we really need DECL_LANG_SPECIFIC for enumerators anymore. Regression testing suggests that we don't.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 8db4cb20608874c36ba4112fb30d718a09e425ff
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Jul 4 15:57:36 2012 -0400

    	PR c++/53848
    	* decl.c (build_enumerator): Don't use build_lang_decl_loc.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 18beaa9..b8dcd03 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -12561,20 +12561,20 @@ incremented enumerator value is too large for %<long%>");
     course, if we're processing a template, there may be no value.  */
   type = value ? TREE_TYPE (value) : NULL_TREE;
 
-  if (context && context == current_class_type)
-    /* This enum declaration is local to the class.  We need the full
-       lang_decl so that we can record DECL_CLASS_CONTEXT, for example.  */
-    decl = build_lang_decl_loc (loc, CONST_DECL, name, type);
-  else
-    /* It's a global enum, or it's local to a function.  (Note local to
-       a function could mean local to a class method.  */
-    decl = build_decl (loc, CONST_DECL, name, type);
+  decl = build_decl (loc, CONST_DECL, name, type);
   
   DECL_CONTEXT (decl) = enumtype;
   TREE_CONSTANT (decl) = 1;
   TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
 
+#if 0
+  if (context && context == current_class_type)
+    /* This enum declaration is local to the class.  We need the full
+       lang_decl so that we can record DECL_CLASS_CONTEXT, for example.  */
+    retrofit_lang_decl (decl);
+#endif
+
   if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
     /* In something like `struct S { enum E { i = 7 }; };' we put `i'
        on the TYPE_FIELDS list for `S'.  (That's so that you can say
diff --git a/gcc/testsuite/g++.dg/other/enum3.C b/gcc/testsuite/g++.dg/other/enum3.C
new file mode 100644
index 0000000..23d6c83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/enum3.C
@@ -0,0 +1,10 @@
+// PR c++/53848
+
+extern "C"
+{
+  struct s {
+    enum {
+      e = 0
+    } f;
+  };
+}

Reply via email to