[sorry, I'm resending this because inadvertently I had some html and the message got rejected]


thus, I have been working on c++/50043, which boils down to this:


My basic idea so far is very simple:

--- class.c (revision 185792)
+++ class.c (working copy)
@@ -1001,6 +1001,10 @@ add_method (tree type, tree method, tree using_dec
+ else if (cxx_dialect >= cxx0x
+ TREE_TYPE (method) = build_exception_variant (TREE_TYPE (method),
+ noexcept_true_spec);

thus, right before actually adding the method we check whether nothing has been deduced about it and we enforce the default noexcept. It's already enough to cover the testcase provided in c++/50043, which includes a good range of positive and negative tests. Does the idea make sense? As is, the patchlet leads to a few regressions, largely benign as far as I can see:

FAIL: g++.dg/cpp0x/noexcept01.C (test for excess errors)
FAIL: g++.dg/eh/ctor1.C -std=c++11 execution test
FAIL: g++.dg/eh/init-temp1.C -std=c++11 execution test
FAIL: g++.dg/tree-ssa/ehcleanup-1.C -std=gnu++11 scan-tree-dump-times ehcleanup1 "Removing unreachable" 4
FAIL: g++.old-deja/g++.eh/cleanup1.C -std=c++11 execution test

(the idea would changing the tests to be c++98 only and then adding c++11 counterparts)

Something the patchlet does not cover is:

struct B
{ ~B(); };

B::~B() { }

indeed the "as an implicit declaration" bits of the new wording in C++11 doesn't guide so much about this, I guess it means something like:

--- decl.c (revision 185792)
+++ decl.c (working copy)
@@ -1144,7 +1144,10 @@ check_redeclaration_exception_specification (tree
if ((pedantic || ! DECL_IN_SYSTEM_HEADER (old_decl))
&& ! DECL_IS_BUILTIN (old_decl)
&& flag_exceptions
- && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
+ && !comp_except_specs (new_exceptions, old_exceptions, ce_normal)
+ && !(DECL_DESTRUCTOR_P (new_decl)
+ && cxx_dialect >= cxx0x
+ && !new_exceptions && TYPE_NOEXCEPT_P (old_type)))
error ("declaration of %qF has a different exception specifier",

does it make sense?

Another case which makes me nervous is when we add to the testcase in c++/50043 also a case for a virtual base class destructor, thus something like

struct True2 { virtual ~True2(); };
struct False { ~False() noexcept(false); };

template <typename Base, typename Member>
struct C : Base
Member mem;

SA(!noexcept(C<True2, False>()));

it doesn't compile at all because:

noexcept_PR50043.C:21:8: error: looser throw specifier for ‘virtual C<True2, False>::~C() noexcept (false)’ noexcept_PR50043.C:5:24: error: overriding ‘virtual True2::~True2() noexcept (true)’

is this expected? Maybe, but I'm not sure.

Thanks in advance for any tips!

Reply via email to