This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to resolve LWG issue 1265


LWG 2165, submitted by Jonathan, argues that declaring a defaulted constructor noexcept should not be ill-formed if the implicitly- declared constructor would not be noexcept. At the Chicago meeting, CWG agreed. This patch makes it deleted instead.

The second hunk adds %X for printing an exception-specification in diagnostics.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 785cdfa527c1481af08a31fb0f3c2489119b539c
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Oct 22 16:17:31 2013 -0400

    	LWG 2165
    	* method.c (defaulted_late_check): Delete on eh-spec mismatch.
    	(maybe_explain_implicit_delete): Explain it.

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 593a4a6..594a004 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1466,13 +1466,34 @@ maybe_explain_implicit_delete (tree decl)
 	  tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
 	  tree parm_type = TREE_VALUE (parms);
 	  bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+	  tree raises = NULL_TREE;
+	  bool deleted_p = false;
 	  tree scope = push_scope (ctype);
-	  inform (0, "%q+#D is implicitly deleted because the default "
-		 "definition would be ill-formed:", decl);
-	  pop_scope (scope);
+
 	  synthesized_method_walk (ctype, sfk, const_p,
-				   NULL, NULL, NULL, NULL, true,
+				   &raises, NULL, &deleted_p, NULL, false,
 				   DECL_INHERITED_CTOR_BASE (decl), parms);
+	  if (deleted_p)
+	    {
+	      inform (0, "%q+#D is implicitly deleted because the default "
+		      "definition would be ill-formed:", decl);
+	      synthesized_method_walk (ctype, sfk, const_p,
+				       NULL, NULL, NULL, NULL, true,
+				       DECL_INHERITED_CTOR_BASE (decl), parms);
+	    }
+	  else if (!comp_except_specs
+		   (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)),
+		    raises, ce_normal))
+	    inform (DECL_SOURCE_LOCATION (decl), "%q#F is implicitly "
+		    "deleted because its exception-specification does not "
+		    "match the implicit exception-specification %qX",
+		    decl, raises);
+#ifdef ENABLE_CHECKING
+	  else
+	    gcc_unreachable ();
+#endif
+
+	  pop_scope (scope);
 	}
 
       input_location = loc;
@@ -1782,9 +1803,10 @@ defaulted_late_check (tree fn)
 			      eh_spec, ce_normal))
 	{
 	  if (DECL_DEFAULTED_IN_CLASS_P (fn))
-	    error ("function %q+D defaulted on its first declaration "
-		   "with an exception-specification that differs from "
-		   "the implicit declaration %q#D", fn, implicit_fn);
+	    {
+	      DECL_DELETED_FN (fn) = true;
+	      eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
+	    }
 	  else
 	    error ("function %q+D defaulted on its redeclaration "
 		   "with an exception-specification that differs from "
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted23.C b/gcc/testsuite/g++.dg/cpp0x/defaulted23.C
index 319cb39..be2fd2f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted23.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted23.C
@@ -6,22 +6,32 @@ struct A
   A() noexcept = default;
 };
 
+A a;
+
 struct B
 {
-  B() throw (int) = default; // { dg-error "exception-specification that differs from the implicit declaration" }
+  B() throw (int) = default; // { dg-message "exception-specification" }
 };
 
+B b;				// { dg-error "deleted" }
+
 struct C
 {
   C() throw (int) { }
 };
 
+C c;
+
 struct D: C
 {
   D() throw (int) = default;
 };
 
+D d;
+
 struct E
 {
   E() = default;
 };
+
+E e;
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted43.C b/gcc/testsuite/g++.dg/cpp0x/defaulted43.C
index e1c2b72..f2846fe 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted43.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted43.C
@@ -7,6 +7,8 @@ struct T
   ~T() noexcept(false) { }
 };
 
+T t;
+
 struct A
 {
   A() noexcept;
@@ -24,6 +26,8 @@ struct U
   ~U() noexcept(false) { }
 };
 
+U u;
+
 struct B
 {
   B() noexcept(false);
@@ -35,16 +39,22 @@ struct B
 B::B() noexcept(false) = default;
 B::~B() noexcept(false) = default;
 
+B b;
+
 struct V
 {
   V() noexcept(false) { }
   ~V() noexcept(false) { }
 };
 
+V v;
+
 struct C
 {
-  C() noexcept = default;     // { dg-error "defaulted" }
-  ~C() noexcept = default;    // { dg-error "defaulted" }
+  C() noexcept = default;	// { dg-message "exception-specification" }
+  ~C() noexcept = default;	// { dg-message "exception-specification" }
 
   V v;
 };
+
+C c;				// { dg-error "deleted" }

commit cc95ba6f007d4b15a40b2da5d9e7ee65a276b738
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Oct 22 16:15:32 2013 -0400

    c-family/
    	* c-format.c (gcc_cxxdiag_char_table): Add %X.
    cp/
    	* error.c (eh_spec_to_string): New.
    	(cp_printer): Use it for %X.

diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index c11d93a..f0371d3 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -721,7 +721,7 @@ static const format_char_info gcc_cxxdiag_char_table[] =
   /* Custom conversion specifiers.  */
 
   /* These will require a "tree" at runtime.  */
-  { "ADEFKSTV",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "",   NULL },
+  { "ADEFKSTVX",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "",   NULL },
 
   { "v", 0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 3f6f594..5f997c3 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2998,6 +2998,15 @@ cv_to_string (tree p, int v)
   return pp_ggc_formatted_text (cxx_pp);
 }
 
+static const char *
+eh_spec_to_string (tree p, int /*v*/)
+{
+  int flags = 0;
+  reinit_cxx_pp ();
+  dump_exception_spec (cxx_pp, p, flags);
+  return pp_ggc_formatted_text (cxx_pp);
+}
+
 /* Langhook for print_error_function.  */
 void
 cxx_print_error_function (diagnostic_context *context, const char *file,
@@ -3379,8 +3388,10 @@ maybe_print_constexpr_context (diagnostic_context *context)
    %O	binary operator.
    %P   function parameter whose position is indicated by an integer.
    %Q	assignment operator.
+   %S   substitution (template + args)
    %T   type.
-   %V   cv-qualifier.  */
+   %V   cv-qualifier.
+   %X   exception-specification.  */
 static bool
 cp_printer (pretty_printer *pp, text_info *text, const char *spec,
 	    int precision, bool wide, bool set_locus, bool verbose)
@@ -3427,6 +3438,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
     case 'S': result = subst_to_string (next_tree);		break;
     case 'T': result = type_to_string (next_tree, verbose);	break;
     case 'V': result = cv_to_string (next_tree, verbose);	break;
+    case 'X': result = eh_spec_to_string (next_tree, verbose);  break;
 
     case 'K':
       percent_K_format (text);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]