* typeck.c (comp_except_specs): Fix ce_derived with noexcept.
From-SVN: r161130
This commit is contained in:
parent
f94ae9875d
commit
6d812dd358
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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" }
|
||||
};
|
Loading…
Reference in New Issue