diff options
author | Jason Merrill <jason@redhat.com> | 2010-06-22 00:36:55 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-06-22 00:36:55 -0400 |
commit | 6d812dd3582299f030ec940c3c513c0653a1a49f (patch) | |
tree | 93a38e3444c2c25ffd26aa4f87c19fd13083885a | |
parent | f94ae9875d386e651defd8f8c802cb41e77a6ba0 (diff) | |
download | gcc-6d812dd3582299f030ec940c3c513c0653a1a49f.tar.gz |
* typeck.c (comp_except_specs): Fix ce_derived with noexcept.
From-SVN: r161130
-rw-r--r-- | gcc/cp/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept08.C | 56 |
4 files changed, 87 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 131030e6a0d..5d36ad3c977 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index beef3881291..4383ef560a7 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -993,35 +993,37 @@ 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) - { - 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; - } + /* First handle noexcept. */ + if (exact < ce_exact) + { + /* 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8443f23a7f7..54d13fd22c5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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> diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept08.C b/gcc/testsuite/g++.dg/cpp0x/noexcept08.C new file mode 100644 index 00000000000..c45033246eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept08.C @@ -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" } +}; |