Patchwork [C++] PR 57645

login
register
mail settings
Submitter Paolo Carlini
Date June 28, 2013, 10:41 p.m.
Message ID <51CE1129.1060801@oracle.com>
Download mbox | patch
Permalink /patch/255690/
State New
Headers show

Comments

Paolo Carlini - June 28, 2013, 10:41 p.m.
Hi,

On 06/28/2013 08:58 PM, Jason Merrill wrote:
> On 06/28/2013 12:58 PM, Paolo Carlini wrote:
>> If you like, this is the rationale behind my last patch: save its
>> current value, set it only to force a thorough
>> deduce_noexcept_on_destructor on everything (admittedly, I don't
>> understand all the details of this), and then restore it, don't fiddle
>> at this stage with the code we have got setting it to its final value.
>> Did I explain this well enough?
>
> Yeah, I guess your recent patch is OK; untangling the 
> interdependencies would be tricky.  Just add a comment that you're 
> setting the flag to avoid early exit from synthesized_method_walk.
Agreed, then. I'm going to commit the below after final testing. It's a 
regression, thus in a few days I mean to commit it to the branch too.

Thanks a lot!
Paolo.

/////////////////////////////

Patch

Index: cp/class.c
===================================================================
--- cp/class.c	(revision 200550)
+++ cp/class.c	(working copy)
@@ -4593,15 +4593,20 @@  deduce_noexcept_on_destructor (tree dtor)
 static void
 deduce_noexcept_on_destructors (tree t)
 {
-  tree fns;
-
   /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail
      out now.  */
   if (!CLASSTYPE_METHOD_VEC (t))
     return;
 
-  for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+  bool saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
+
+  /* Avoid early exit from synthesized_method_walk (c++/57645).  */
+  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true;
+
+  for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
     deduce_noexcept_on_destructor (OVL_CURRENT (fns));
+
+  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = saved_nontrivial_dtor;
 }
 
 /* Subroutine of set_one_vmethod_tm_attributes.  Search base classes
Index: testsuite/g++.dg/cpp0x/noexcept21.C
===================================================================
--- testsuite/g++.dg/cpp0x/noexcept21.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/noexcept21.C	(working copy)
@@ -0,0 +1,174 @@ 
+// PR c++/57645
+// { dg-do compile { target c++11 } }
+
+struct Thrower
+{
+  ~Thrower() noexcept(false) { throw 1; }
+};
+
+struct ExplicitA
+{
+  ~ExplicitA() {}
+
+  Thrower t;
+};
+
+struct ExplicitB
+{
+  ~ExplicitB();
+
+  Thrower t;
+};
+
+ExplicitB::~ExplicitB() {}
+
+struct ExplicitC
+{
+  ~ExplicitC() = default;
+
+  Thrower t;
+};
+
+struct ExplicitD
+{
+  ~ExplicitD();
+
+  Thrower t;
+};
+
+ExplicitD::~ExplicitD() = default;
+
+struct NoThrower
+{
+  ~NoThrower() noexcept(true) {}
+};
+
+struct ExplicitE
+{
+  ~ExplicitE() {}
+
+  NoThrower t;
+};
+
+struct ExplicitF
+{
+  ~ExplicitF();
+
+  NoThrower t;
+};
+
+ExplicitF::~ExplicitF() {}
+
+struct ExplicitG
+{
+  ~ExplicitG() = default;
+
+  NoThrower t;
+};
+
+struct ExplicitH
+{
+  ~ExplicitH();
+
+  NoThrower t;
+};
+
+ExplicitH::~ExplicitH() = default;
+
+#define SA(X) static_assert(X, #X)
+
+SA( !noexcept(ExplicitA()) );
+SA( !noexcept(ExplicitB()) );
+SA( !noexcept(ExplicitC()) );
+SA( !noexcept(ExplicitD()) );
+SA( noexcept(ExplicitE()) );
+SA( noexcept(ExplicitF()) );
+SA( noexcept(ExplicitG()) );
+SA( noexcept(ExplicitH()) );
+// PR c++/57645
+// { dg-do compile { target c++11 } }
+
+struct Thrower
+{
+  ~Thrower() noexcept(false) { throw 1; }
+};
+
+struct ExplicitA
+{
+  ~ExplicitA() {}
+
+  Thrower t;
+};
+
+struct ExplicitB
+{
+  ~ExplicitB();
+
+  Thrower t;
+};
+
+ExplicitB::~ExplicitB() {}
+
+struct ExplicitC
+{
+  ~ExplicitC() = default;
+
+  Thrower t;
+};
+
+struct ExplicitD
+{
+  ~ExplicitD();
+
+  Thrower t;
+};
+
+ExplicitD::~ExplicitD() = default;
+
+struct NoThrower
+{
+  ~NoThrower() noexcept(true) {}
+};
+
+struct ExplicitE
+{
+  ~ExplicitE() {}
+
+  NoThrower t;
+};
+
+struct ExplicitF
+{
+  ~ExplicitF();
+
+  NoThrower t;
+};
+
+ExplicitF::~ExplicitF() {}
+
+struct ExplicitG
+{
+  ~ExplicitG() = default;
+
+  NoThrower t;
+};
+
+struct ExplicitH
+{
+  ~ExplicitH();
+
+  NoThrower t;
+};
+
+ExplicitH::~ExplicitH() = default;
+
+#define SA(X) static_assert(X, #X)
+
+SA( !noexcept(ExplicitA()) );
+SA( !noexcept(ExplicitB()) );
+SA( !noexcept(ExplicitC()) );
+SA( !noexcept(ExplicitD()) );
+SA( noexcept(ExplicitE()) );
+SA( noexcept(ExplicitF()) );
+SA( noexcept(ExplicitG()) );
+SA( noexcept(ExplicitH()) );