Commit 5e3f417f by Jason Merrill Committed by Jason Merrill

DR 1073 PR c++/49082

	DR 1073
	PR c++/49082
	* typeck.c (comp_except_specs): noexcept(false) is not compatible
	with throw(type-list).
	* typeck2.c (merge_exception_specifiers): noexcept(false)
	beats any more limited specification.

From-SVN: r173981
parent bce33ab2
2011-05-20 Jason Merrill <jason@redhat.com> 2011-05-20 Jason Merrill <jason@redhat.com>
DR 1073
PR c++/49082
* typeck.c (comp_except_specs): noexcept(false) is not compatible
with throw(type-list).
* typeck2.c (merge_exception_specifiers): noexcept(false)
beats any more limited specification.
PR c++/24163 PR c++/24163
PR c++/29131 PR c++/29131
* pt.c (tsubst_copy_and_build) [CALL_EXPR]: Avoid repeating * pt.c (tsubst_copy_and_build) [CALL_EXPR]: Avoid repeating
......
...@@ -986,14 +986,14 @@ comp_except_specs (const_tree t1, const_tree t2, int exact) ...@@ -986,14 +986,14 @@ comp_except_specs (const_tree t1, const_tree t2, int exact)
/* First handle noexcept. */ /* First handle noexcept. */
if (exact < ce_exact) if (exact < ce_exact)
{ {
/* noexcept(false) is compatible with any throwing dynamic-exc-spec /* noexcept(false) is compatible with no exception-specification,
and stricter than any spec. */ and stricter than any spec. */
if (t1 == noexcept_false_spec) if (t1 == noexcept_false_spec)
return !nothrow_spec_p (t2) || exact == ce_derived; return t2 == NULL_TREE || exact == ce_derived;
/* Even a derived noexcept(false) is compatible with a throwing /* Even a derived noexcept(false) is compatible with no
dynamic spec. */ exception-specification. */
if (t2 == noexcept_false_spec) if (t2 == noexcept_false_spec)
return !nothrow_spec_p (t1); return t1 == NULL_TREE;
/* Otherwise, if we aren't looking for an exact match, noexcept is /* Otherwise, if we aren't looking for an exact match, noexcept is
equivalent to throw(). */ equivalent to throw(). */
......
...@@ -1756,10 +1756,13 @@ add_exception_specifier (tree list, tree spec, int complain) ...@@ -1756,10 +1756,13 @@ add_exception_specifier (tree list, tree spec, int complain)
tree tree
merge_exception_specifiers (tree list, tree add) merge_exception_specifiers (tree list, tree add)
{ {
if (!list || !add) /* No exception-specifier or noexcept(false) are less strict than
return NULL_TREE; anything else. Prefer the newer variant (LIST). */
if (!list || list == noexcept_false_spec)
return list;
else if (!add || add == noexcept_false_spec)
return add;
/* For merging noexcept(true) and throw(), take the more recent one (LIST). /* For merging noexcept(true) and throw(), take the more recent one (LIST).
A throw(type-list) spec takes precedence over a noexcept(false) spec.
Any other noexcept-spec should only be merged with an equivalent one. Any other noexcept-spec should only be merged with an equivalent one.
So the !TREE_VALUE code below is correct for all cases. */ So the !TREE_VALUE code below is correct for all cases. */
else if (!TREE_VALUE (add)) else if (!TREE_VALUE (add))
......
2011-05-20 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/noexcept02.C: Fix.
* g++.dg/cpp0x/noexcept03.C: Fix.
* g++.dg/cpp0x/noexcept08.C: Fix.
* g++.dg/cpp0x/noexcept10.C: New.
2011-05-20 Janus Weil <janus@gcc.gnu.org> 2011-05-20 Janus Weil <janus@gcc.gnu.org>
PR fortran/48706 PR fortran/48706
......
...@@ -10,9 +10,9 @@ void f(); ...@@ -10,9 +10,9 @@ void f();
SA(!noexcept(f())); SA(!noexcept(f()));
void g() throw (int); void g() throw (int); // { dg-error "previous declaration" }
void g() noexcept(false); // { dg-error "previous declaration" } void g() noexcept(false); // { dg-error "different exception" }
void g(); // { dg-error "different exception" } void g();
void h() throw(); void h() throw();
void h() noexcept; void h() noexcept;
......
...@@ -36,19 +36,6 @@ void f2(T a) noexcept (noexcept (f (a))) ...@@ -36,19 +36,6 @@ void f2(T a) noexcept (noexcept (f (a)))
struct A { A() { } }; // { dg-warning "does not throw" } struct A { A() { } }; // { dg-warning "does not throw" }
// throw(int) overrides noexcept(false) in either order.
void h() throw (int, std::bad_exception);
void h() noexcept (false)
{
throw 1.0;
}
void i() noexcept (false);
void i() throw (int, std::bad_exception)
{
throw 1.0;
}
int main() int main()
{ {
// noexcept(false) allows throw. // noexcept(false) allows throw.
...@@ -57,10 +44,6 @@ int main() ...@@ -57,10 +44,6 @@ int main()
try { f(A()); } catch (int) { } try { f(A()); } catch (int) { }
try { f2(A()); } catch (int) { } try { f2(A()); } catch (int) { }
std::set_unexpected (my_unexpected);
try { h(); } catch (std::bad_exception) { }
try { i(); } catch (std::bad_exception) { }
std::set_terminate (my_terminate); std::set_terminate (my_terminate);
// noexcept(noexcept(int())) == noexcept(true). // noexcept(noexcept(int())) == noexcept(true).
try { f2(1); } catch (...) { } try { f2(1); } catch (...) { }
......
...@@ -34,7 +34,7 @@ struct D: A ...@@ -34,7 +34,7 @@ struct D: A
void g() noexcept(false); // { dg-error "looser" } void g() noexcept(false); // { dg-error "looser" }
void h() noexcept(false); // { dg-error "looser" } void h() noexcept(false); // { dg-error "looser" }
void i() noexcept(false); void i() noexcept(false);
void j() noexcept(false); // compatible; treated as throw(int) void j() noexcept(false); // { dg-error "looser" }
}; };
struct E: A struct E: A
......
// PR c++/49082
// { dg-options -std=c++0x }
namespace std { template <class T> T&& declval() noexcept; }
struct Base
{
Base(const Base&) noexcept(false);
Base(Base&&) noexcept(false);
~Base() noexcept(false);
};
struct Derived
: Base
{
// Derived(const Derived&) = default;
// Derived(Derived&&) = default;
};
static_assert(!noexcept(Base(std::declval<const Base&>())), "Error");
static_assert(!noexcept(Derived(std::declval<const Derived&>())), "Error"); // Error
static_assert(!noexcept(Base(std::declval<Base&&>())), "Error");
static_assert(!noexcept(Derived(std::declval<Derived&&>())), "Error"); // Error
static_assert(!noexcept(std::declval<Base&>().~Base()), "Error"); // OK
static_assert(!noexcept(std::declval<Derived&>().~Derived()), "Error"); // Error
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment