public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/69300, ICE with self-referential noexcept
@ 2017-06-28 20:02 Jason Merrill
  2017-06-28 21:11 ` Marc Glisse
  0 siblings, 1 reply; 3+ messages in thread
From: Jason Merrill @ 2017-06-28 20:02 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 248 bytes --]

In the testcase we SEGV due to infinite recursion because the
noexcept-specifier of f depends on itself.  Fixed by keeping track of
which functions we're currently trying to instantiate noexcept for.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: 69300.diff --]
[-- Type: text/plain, Size: 1776 bytes --]

commit 7a938fed4c07c7e28008b56e6bac05376b1f99fa
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jun 27 17:25:18 2017 -0400

            PR c++/69300 - ICE with self-referential noexcept
    
            * pt.c (maybe_instantiate_noexcept): Check for recursion.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fa75037..047d3ba 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -22557,8 +22557,20 @@ maybe_instantiate_noexcept (tree fn)
 
   if (TREE_CODE (noex) == DEFERRED_NOEXCEPT)
     {
+      static hash_set<tree>* fns = new hash_set<tree>;
+      bool added = false;
       if (DEFERRED_NOEXCEPT_PATTERN (noex) == NULL_TREE)
 	spec = get_defaulted_eh_spec (fn);
+      else if (!(added = !fns->add (fn)))
+	{
+	  /* If hash_set::add returns true, the element was already there.  */
+	  location_t loc = EXPR_LOC_OR_LOC (DEFERRED_NOEXCEPT_PATTERN (noex),
+					    DECL_SOURCE_LOCATION (fn));
+	  error_at (loc,
+		    "exception specification of %qD depends on itself",
+		    fn);
+	  spec = noexcept_false_spec;
+	}
       else if (push_tinst_level (fn))
 	{
 	  push_access_scope (fn);
@@ -22579,6 +22591,9 @@ maybe_instantiate_noexcept (tree fn)
       else
 	spec = noexcept_false_spec;
 
+      if (added)
+	fns->remove (fn);
+
       TREE_TYPE (fn) = build_exception_variant (fntype, spec);
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept30.C b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C
new file mode 100644
index 0000000..c51e94e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C
@@ -0,0 +1,12 @@
+// PR c++/69300
+// { dg-do compile { target c++11 } }
+
+template<typename A>
+struct F {
+  template<typename B>
+  void f() noexcept(&F::template f<B>) {} // { dg-error "exception specification" }
+};
+
+int main () {
+  F<void>().f<int>();
+}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/69300, ICE with self-referential noexcept
  2017-06-28 20:02 C++ PATCH for c++/69300, ICE with self-referential noexcept Jason Merrill
@ 2017-06-28 21:11 ` Marc Glisse
  2017-06-29 21:55   ` Jason Merrill
  0 siblings, 1 reply; 3+ messages in thread
From: Marc Glisse @ 2017-06-28 21:11 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Wed, 28 Jun 2017, Jason Merrill wrote:

> In the testcase we SEGV due to infinite recursion because the
> noexcept-specifier of f depends on itself.  Fixed by keeping track of
> which functions we're currently trying to instantiate noexcept for.

Hello,

in the testcase, it makes sense that this is an error. In some other 
cases, say for instance

int fact(int n) noexcept(auto) { return (n>1)?n*f(n-1):1; }

(yes, I know we still do not have noexcept(auto))
it would make sense to pretend that the recursive call does not throw for 
the purpose of determining that fact is indeed noexcept. Then we get into 
solving the same thing as IPA already does... And the standard does not 
require implementations to be clever there. Still, it could have been nice 
:-/

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: C++ PATCH for c++/69300, ICE with self-referential noexcept
  2017-06-28 21:11 ` Marc Glisse
@ 2017-06-29 21:55   ` Jason Merrill
  0 siblings, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2017-06-29 21:55 UTC (permalink / raw)
  To: gcc-patches List

On Wed, Jun 28, 2017 at 5:11 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Wed, 28 Jun 2017, Jason Merrill wrote:
>
>> In the testcase we SEGV due to infinite recursion because the
>> noexcept-specifier of f depends on itself.  Fixed by keeping track of
>> which functions we're currently trying to instantiate noexcept for.
>
> in the testcase, it makes sense that this is an error. In some other cases,
> say for instance
>
> int fact(int n) noexcept(auto) { return (n>1)?n*f(n-1):1; }
>
> (yes, I know we still do not have noexcept(auto))
> it would make sense to pretend that the recursive call does not throw for
> the purpose of determining that fact is indeed noexcept.

True; the recursive call can't make the function more throwy.

Jason

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-06-29 21:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-28 20:02 C++ PATCH for c++/69300, ICE with self-referential noexcept Jason Merrill
2017-06-28 21:11 ` Marc Glisse
2017-06-29 21:55   ` 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).