* C++0x PATCH to comparison of noexcept specifications
@ 2010-06-22 7:08 Jason Merrill
0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2010-06-22 7:08 UTC (permalink / raw)
To: gcc-patches List
[-- Attachment #1: Type: text/plain, Size: 335 bytes --]
While working on implicit move constructors, I've been running the
testsuite with -std=gnu++0x, which turned up a bug whereby overriding a
base method which can throw any exception with a derived method which is
noexcept was giving an error about a looser exception spec. Fixed thus.
Tested x86_64-pc-linux-gnu, applied to trunk.
[-- Attachment #2: comp-noexcept.patch --]
[-- Type: text/x-patch, Size: 3919 bytes --]
commit cc07b6735584fe5ee4f692c05d7a0a6abe1a4dbd
Author: Jason Merrill <jason@redhat.com>
Date: Mon Jun 21 22:04:14 2010 -0400
* typeck.c (comp_except_specs): Fix ce_derived with noexcept.
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index beef388..4383ef5 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/g++.dg/cpp0x/noexcept08.C b/gcc/testsuite/g++.dg/cpp0x/noexcept08.C
new file mode 100644
index 0000000..c450332
--- /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" }
+};
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-06-22 4:27 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-22 7:08 C++0x PATCH to comparison of noexcept specifications Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).