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

2017-08-10 Thread Jason Merrill
On Thu, Aug 10, 2017 at 12:13 AM, Markus Trippelsdorf
 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 
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.

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 000..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 {};


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

2017-08-10 Thread Markus Trippelsdorf
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:

 ~ % cat asm-js.ii
struct A {
  void operator delete(void *, unsigned long);
};
struct B : A {
  virtual ~B();
};
struct C : B {};

 ~ % g++ -c asm-js.ii
asm-js.ii:7:8: error: no matching function for call to ‘C::operator 
delete(void*)’
 struct C : B {};
^
asm-js.ii:2:8: note: candidate: ‘static void A::operator delete(void*, long 
unsigned int)’
   void operator delete(void *, unsigned long);
^~~~
asm-js.ii:2:8: note:   candidate expects 2 arguments, 1 provided


-- 
Markus


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

2017-08-09 Thread Jason Merrill
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.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 616193fb149d17e8a671a46c03dca98aecbcc752
Author: Jason Merrill 
Date:   Tue Aug 8 12:49:42 2017 -0400

PR c++/81359 - Unparsed NSDMI error from SFINAE context.

* init.c (get_nsdmi): Add complain parm.
* typeck2.c (digest_nsdmi_init): Add complain parm.
(process_init_constructor_record): Pass complain to get_nsdmi.
* pt.c (maybe_instantiate_noexcept): Add complain parm, return bool.
* method.c (get_defaulted_eh_spec): Add complain parm.  Pass it into
synthesized_method_walk.
(synthesized_method_walk): Adjust.
(walk_field_subobs): Pass complain to get_nsdmi.
(defaulted_late_check): Skip other checks if deleted.
* decl2.c (mark_used): Pass complain to maybe_instantiate_noexcept.
* call.c (build_aggr_conv): Pass complain to get_nsdmi.
* parser.c (defarg_location): New.
* error.c (location_of): Use it.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index fdd3731..4903119 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -916,7 +916,7 @@ build_aggr_conv (tree type, tree ctor, int flags, 
tsubst_flags_t complain)
   if (i < CONSTRUCTOR_NELTS (ctor))
val = CONSTRUCTOR_ELT (ctor, i)->value;
   else if (DECL_INITIAL (field))
-   val = get_nsdmi (field, /*ctor*/false);
+   val = get_nsdmi (field, /*ctor*/false, complain);
   else if (TREE_CODE (ftype) == REFERENCE_TYPE)
/* Value-initialization of reference is ill-formed.  */
return NULL;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 508570b..94738bd 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -8093,8 +8093,9 @@ resolve_address_of_overloaded_function (tree target_type,
  continue;
 
/* In C++17 we need the noexcept-qualifier to compare types.  */
-   if (flag_noexcept_type)
- maybe_instantiate_noexcept (fn);
+   if (flag_noexcept_type
+   && !maybe_instantiate_noexcept (fn, complain))
+ continue;
 
/* See if there's a match.  */
tree fntype = static_fn_type (fn);
@@ -8176,7 +8177,7 @@ resolve_address_of_overloaded_function (tree target_type,
 
  /* In C++17 we need the noexcept-qualifier to compare types.  */
  if (flag_noexcept_type)
-   maybe_instantiate_noexcept (instantiation);
+   maybe_instantiate_noexcept (instantiation, complain);
 
  /* See if there's a match.  */
  tree fntype = static_fn_type (instantiation);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 115cdaf..3a0bd16 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6297,7 +6297,7 @@ extern tree get_type_value(tree);
 extern tree build_zero_init(tree, tree, bool);
 extern tree build_value_init   (tree, tsubst_flags_t);
 extern tree build_value_init_noctor(tree, tsubst_flags_t);
-extern tree get_nsdmi  (tree, bool);
+extern tree get_nsdmi  (tree, bool, tsubst_flags_t);
 extern tree build_offset_ref   (tree, tree, bool,
 tsubst_flags_t);
 extern tree throw_bad_array_new_length (void);
@@ -6355,7 +6355,7 @@ extern bool trivial_fn_p  (tree);
 extern tree forward_parm   (tree);
 extern bool is_trivially_xible (enum tree_code, tree, tree);
 extern bool is_xible   (enum tree_code, tree, tree);
-extern tree get_defaulted_eh_spec  (tree);
+extern tree get_defaulted_eh_spec  (tree, tsubst_flags_t = 
tf_warning_or_error);
 extern void after_nsdmi_defaulted_late_checks   (tree);
 extern bool maybe_explain_implicit_delete  (tree);
 extern void explain_implicit_non_constexpr (tree);
@@ -6385,6 +6385,7 @@ extern tree cp_convert_range_for (tree, tree, tree, tree, 
unsigned int, bool);
 extern bool parsing_nsdmi (void);
 extern bool parsing_default_capturing_generic_lambda_in_template (void);
 extern void inject_this_parameter (tree, cp_cv_quals);
+extern location_t defarg_location (tree);
 
 /* in pt.c */
 extern bool check_template_shadow  (tree);
@@ -6448,7 +6449,7 @@ extern int more_specialized_fn(tree, 
tree, int);
 extern void do_decl_instantiation  (tree, tree);
 extern void do_type_instantiation  (tree, tree, tsubst_flags_t);
 extern bool always_instantiate_p   (tree);
-extern void maybe_instantiate_noexcept (tree);
+extern bool maybe_instan