Patchwork C++ PATCH for some NSDMI bugs

login
register
mail settings
Submitter Jason Merrill
Date Oct. 2, 2011, 9:41 p.m.
Message ID <4E88DA9D.4060203@redhat.com>
Download mbox | patch
Permalink /patch/117380/
State New
Headers show

Comments

Jason Merrill - Oct. 2, 2011, 9:41 p.m.
The template and non-template versions of this test run into different 
bugs: the template version crashes in noexcept checking because the 
initializer hasn't been instantiated, and the non-template version 
crashes in fixed_type_or_null because current_function_decl is null.

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

Patch

commit 990d1177f59f12fbf8bf73a215b6e43bf4b27583
Author: Jason Merrill <jason@redhat.com>
Date:   Sun Oct 2 17:02:44 2011 -0400

    	* class.c (fixed_type_or_null): Handle NSDMI.
    	* method.c (walk_field_subobs): Disable NSDMI noexcept checking
    	for now.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index a7d8218..2df9177 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6062,10 +6062,13 @@  fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
 	  if (nonnull)
 	    *nonnull = 1;
 
-	  /* if we're in a ctor or dtor, we know our type.  */
-	  if (DECL_LANG_SPECIFIC (current_function_decl)
-	      && (DECL_CONSTRUCTOR_P (current_function_decl)
-		  || DECL_DESTRUCTOR_P (current_function_decl)))
+	  /* if we're in a ctor or dtor, we know our type.  If
+	     current_class_ptr is set but we aren't in a function, we're in
+	     an NSDMI (and therefore a constructor).  */
+	  if (current_scope () != current_function_decl
+	      || (DECL_LANG_SPECIFIC (current_function_decl)
+		  && (DECL_CONSTRUCTOR_P (current_function_decl)
+		      || DECL_DESTRUCTOR_P (current_function_decl))))
 	    {
 	      if (cdtorp)
 		*cdtorp = 1;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 1316dfb..f4a3ea6 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1042,12 +1042,16 @@  walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
 		inform (0, "initializer for %q+#D is invalid", field);
 	      if (trivial_p)
 		*trivial_p = false;
+#if 0
 	      /* Core 1351: If the field has an NSDMI that could throw, the
 		 default constructor is noexcept(false).  FIXME this is
-	         broken by deferred parsing and 1360 saying we can't
-		 lazily declare a non-trivial default constructor.  */
+		 broken by deferred parsing and 1360 saying we can't lazily
+		 declare a non-trivial default constructor.  Also this
+		 needs to do deferred instantiation.  Disable until the
+		 conflict between 1351 and 1360 is resolved.  */
 	      if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain))
 		*spec_p = noexcept_false_spec;
+#endif
 
 	      /* Don't do the normal processing.  */
 	      continue;
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi5.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi5.C
new file mode 100644
index 0000000..62803b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi5.C
@@ -0,0 +1,20 @@ 
+// { dg-options -std=c++0x }
+
+struct X
+{
+  int x = 5;
+  int f() { return x; }
+};
+struct Y : X
+{
+  int y = this->x;
+};
+template <class T> struct Z : T
+{
+  int y = this->f();
+};
+int main()
+{
+  Y foo;
+  Z<X> bar;
+}