C++ PATCH for c++/81359, Unparsed NSDMI error in SFINAE context

Submitted by Jason Merrill on Aug. 10, 2017, 7:56 p.m.

Details

Message ID CADzB+2kE2OTQOerpojc7b0xX9FL-fQWSut4GRf96dS8EgKW_vw@mail.gmail.com
State New
Headers show

Commit Message

Jason Merrill Aug. 10, 2017, 7:56 p.m.
On Thu, Aug 10, 2017 at 12:13 AM, Markus Trippelsdorf
<markus@trippelsdorf.de> wrote:
> On 2017.08.09 at 14:30 -0400, Jason Merrill wrote:
>> The issue here is that we try to determine the EH specification of
>> B::C::C() from within SFINAE context, and we can't determine it yet
>> because the NSDMI for B::C::i hasn't been parsed yet.  This patch
>> allows that determination to fail quietly in SFINAE context; we'll try
>> again the next time it is needed.
>
> Thanks.
>
> Unfortunately it breaks the following testcase:

Fixed thus:
commit 98a57ff77c97446c0477bea2aed831b62a0726a6
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Aug 10 12:23:12 2017 -0700

            Fix regression from 81359 patch.
    
            * method.c (synthesized_method_walk): Don't diagnose lack of
            operator delete.

Patch hide | download patch | download mbox

diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index bff9605..809ebc8 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1693,12 +1693,18 @@  synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
 
       if (check_vdtor && type_has_virtual_destructor (BINFO_TYPE (base_binfo)))
 	{
-	  fn = locate_fn_flags (ctype, cp_operator_id (DELETE_EXPR),
-				ptr_type_node, flags, complain);
 	  /* Unlike for base ctor/op=/dtor, for operator delete it's fine
 	     to have a null fn (no class-specific op delete).  */
-	  if (fn && fn == error_mark_node && deleted_p)
-	    *deleted_p = true;
+	  fn = locate_fn_flags (ctype, cp_operator_id (DELETE_EXPR),
+				ptr_type_node, flags, tf_none);
+	  if (fn && fn == error_mark_node)
+	    {
+	      if (complain & tf_error)
+		locate_fn_flags (ctype, cp_operator_id (DELETE_EXPR),
+				 ptr_type_node, flags, complain);
+	      if (deleted_p)
+		*deleted_p = true;
+	    }
 	  check_vdtor = false;
 	}
     }
diff --git a/gcc/testsuite/g++.dg/inherit/vdtor1.C b/gcc/testsuite/g++.dg/inherit/vdtor1.C
new file mode 100644
index 0000000..caba17f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/inherit/vdtor1.C
@@ -0,0 +1,7 @@ 
+struct A {
+  void operator delete(void *, unsigned long);
+};
+struct B : A {
+  virtual ~B();
+};
+struct C : B {};