Patchwork C++ PATCH for c++/53848 (ICE with enum in class in extern "C")

login
register
mail settings
Submitter Jason Merrill
Date July 4, 2012, 9:31 p.m.
Message ID <4FF4B638.6070403@redhat.com>
Download mbox | patch
Permalink /patch/169049/
State New
Headers show

Comments

Jason Merrill - July 4, 2012, 9:31 p.m.
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.

Patch

commit 8db4cb20608874c36ba4112fb30d718a09e425ff
Author: Jason Merrill <jason@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;
+  };
+}