* typeck.c (comp_except_specs): Fix ce_derived with noexcept.

From-SVN: r161130
This commit is contained in:
Jason Merrill 2010-06-22 00:36:55 -04:00 committed by Jason Merrill
parent f94ae9875d
commit 6d812dd358
4 changed files with 85 additions and 23 deletions

View File

@ -1,5 +1,7 @@
2010-06-21 Jason Merrill <jason@redhat.com>
* typeck.c (comp_except_specs): Fix ce_derived with noexcept.
* semantics.c (check_trait_type): Check COMPLETE_TYPE_P for array
element type.

View File

@ -993,36 +993,38 @@ comp_except_specs (const_tree t1, const_tree t2, int exact)
const_tree probe;
const_tree base;
int length = 0;
const_tree noexcept_spec = NULL_TREE;
const_tree other_spec;
if (t1 == t2)
return true;
/* First test noexcept compatibility. */
if (t1 && TREE_PURPOSE (t1))
noexcept_spec = t1, other_spec = t2;
else if (t2 && TREE_PURPOSE (t2))
noexcept_spec = t2, other_spec = t1;
if (noexcept_spec)
/* First handle noexcept. */
if (exact < ce_exact)
{
tree p = TREE_PURPOSE (noexcept_spec);
/* Two noexcept-specs are equivalent iff their exprs are. */
if (other_spec && TREE_PURPOSE (other_spec))
return cp_tree_equal (p, TREE_PURPOSE (other_spec));
/* noexcept(true) is compatible with throw(). */
else if (exact < ce_exact && p == boolean_true_node)
return nothrow_spec_p (other_spec);
/* noexcept(false) is compatible with any throwing
dynamic-exception-spec. */
else if (exact < ce_exact && p == boolean_false_node)
return !nothrow_spec_p (other_spec);
/* A dependent noexcept-spec is not compatible with any
dynamic-exception-spec. */
else
return false;
/* noexcept(false) is compatible with any throwing dynamic-exc-spec
and stricter than any spec. */
if (t1 == noexcept_false_spec)
return !nothrow_spec_p (t2) || exact == ce_derived;
/* Even a derived noexcept(false) is compatible with a throwing
dynamic spec. */
if (t2 == noexcept_false_spec)
return !nothrow_spec_p (t1);
/* Otherwise, if we aren't looking for an exact match, noexcept is
equivalent to throw(). */
if (t1 == noexcept_true_spec)
t1 = empty_except_spec;
if (t2 == noexcept_true_spec)
t2 = empty_except_spec;
}
/* If any noexcept is left, it is only comparable to itself;
either we're looking for an exact match or we're redeclaring a
template with dependent noexcept. */
if ((t1 && TREE_PURPOSE (t1))
|| (t2 && TREE_PURPOSE (t2)))
return (t1 && t2
&& cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)));
if (t1 == NULL_TREE) /* T1 is ... */
return t2 == NULL_TREE || exact == ce_derived;
if (!TREE_VALUE (t1)) /* t1 is EMPTY */

View File

@ -1,5 +1,7 @@
2010-06-21 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/noexcept08.C: New.
* g++.dg/ext/unary_trait_incomplete.C: Adjust.
2010-06-21 H.J. Lu <hongjiu.lu@intel.com>

View File

@ -0,0 +1,56 @@
// { dg-options "-std=c++0x" }
// { dg-prune-output "overriding" }
struct A
{
virtual void f();
virtual void g() throw();
virtual void h() noexcept;
virtual void i() noexcept(false);
virtual void j() throw(int);
};
struct B: A
{
void f() noexcept;
void g() noexcept;
void h() noexcept;
void i() noexcept;
void j() noexcept;
};
struct C: A
{
void f() throw();
void g() throw();
void h() throw();
void i() throw();
void j() throw();
};
struct D: A
{
void f() noexcept(false);
void g() noexcept(false); // { dg-error "looser" }
void h() noexcept(false); // { dg-error "looser" }
void i() noexcept(false);
void j() noexcept(false); // compatible; treated as throw(int)
};
struct E: A
{
void f() throw(int);
void g() throw(int); // { dg-error "looser" }
void h() throw(int); // { dg-error "looser" }
void i() throw(int);
void j() throw(int);
};
struct F: A
{
void f();
void g(); // { dg-error "looser" }
void h(); // { dg-error "looser" }
void i();
void j(); // { dg-error "looser" }
};