public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-1067] c++: Fix reference NTTP binding to noexcept fn [PR97420]
@ 2021-05-26 13:08 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-05-26 13:08 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:b4329e3dd6fb7c78948fcf9d2f5b9d873deec284

commit r12-1067-gb4329e3dd6fb7c78948fcf9d2f5b9d873deec284
Author: Patrick Palka <ppalka@redhat.com>
Date:   Wed May 26 08:35:31 2021 -0400

    c++: Fix reference NTTP binding to noexcept fn [PR97420]
    
    Here, in C++17 mode, convert_nontype_argument_function is rejecting
    binding a non-noexcept function reference template parameter to a
    noexcept function (encoded as the template argument '*(int (&) (int)) &f').
    
    The first roadblock to making this work is that the argument is wrapped
    an an implicit INDIRECT_REF, so we need to unwrap it before calling
    strip_fnptr_conv.
    
    The second roadblock is that the NOP_EXPR cast converts from a function
    pointer type to a reference type while simultaneously removing the
    noexcept qualification, and fnptr_conv_p doesn't consider this cast to
    be a function pointer conversion.  This patch fixes this by making
    fnptr_conv_p treat REFERENCE_TYPEs and POINTER_TYPEs interchangeably.
    
    Finally, in passing, this patch also simplifies noexcept_conv_p by
    removing a bunch of redundant checks already performed by its only
    caller fnptr_conv_p.
    
            PR c++/97420
    
    gcc/cp/ChangeLog:
    
            * cvt.c (noexcept_conv_p): Remove redundant checks and simplify.
            (fnptr_conv_p): Don't call non_reference.  Use INDIRECT_TYPE_P
            instead of TYPE_PTR_P.
            * pt.c (convert_nontype_argument_function): Look through
            implicit INDIRECT_REFs before calling strip_fnptr_conv.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/noexcept68.C: New test.

Diff:
---
 gcc/cp/cvt.c                            | 36 ++++++++++-----------------------
 gcc/cp/pt.c                             |  5 ++++-
 gcc/testsuite/g++.dg/cpp0x/noexcept68.C |  8 ++++++++
 3 files changed, 23 insertions(+), 26 deletions(-)

diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 7fa6e8df52b..330d65854b4 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -2081,7 +2081,8 @@ can_convert_tx_safety (tree to, tree from)
 	  && same_type_p (to, tx_unsafe_fn_variant (from)));
 }
 
-/* Return true iff FROM can convert to TO by dropping noexcept.  */
+/* Return true iff FROM can convert to TO by dropping noexcept.
+   This is just a subroutine of of fnptr_conv_p.  */
 
 static bool
 noexcept_conv_p (tree to, tree from)
@@ -2089,30 +2090,15 @@ noexcept_conv_p (tree to, tree from)
   if (!flag_noexcept_type)
     return false;
 
-  tree t = non_reference (to);
-  tree f = from;
-  if (TYPE_PTRMEMFUNC_P (t)
-      && TYPE_PTRMEMFUNC_P (f))
-    {
-      t = TYPE_PTRMEMFUNC_FN_TYPE (t);
-      f = TYPE_PTRMEMFUNC_FN_TYPE (f);
-    }
-  if (TYPE_PTR_P (t)
-      && TYPE_PTR_P (f))
-    {
-      t = TREE_TYPE (t);
-      f = TREE_TYPE (f);
-    }
-  tree_code code = TREE_CODE (f);
-  if (TREE_CODE (t) != code)
+  if (TREE_CODE (to) != TREE_CODE (from))
     return false;
-  if (code != FUNCTION_TYPE && code != METHOD_TYPE)
+  if (!FUNC_OR_METHOD_TYPE_P (from))
     return false;
-  if (!type_throw_all_p (t)
-      || type_throw_all_p (f))
+  if (!type_throw_all_p (to)
+      || type_throw_all_p (from))
     return false;
-  tree v = build_exception_variant (f, NULL_TREE);
-  return same_type_p (t, v);
+  tree v = build_exception_variant (from, NULL_TREE);
+  return same_type_p (to, v);
 }
 
 /* Return true iff FROM can convert to TO by a function pointer conversion.  */
@@ -2120,7 +2106,7 @@ noexcept_conv_p (tree to, tree from)
 bool
 fnptr_conv_p (tree to, tree from)
 {
-  tree t = non_reference (to);
+  tree t = to;
   tree f = from;
   if (TYPE_PTRMEMFUNC_P (t)
       && TYPE_PTRMEMFUNC_P (f))
@@ -2128,8 +2114,8 @@ fnptr_conv_p (tree to, tree from)
       t = TYPE_PTRMEMFUNC_FN_TYPE (t);
       f = TYPE_PTRMEMFUNC_FN_TYPE (f);
     }
-  if (TYPE_PTR_P (t)
-      && TYPE_PTR_P (f))
+  if (INDIRECT_TYPE_P (t)
+      && INDIRECT_TYPE_P (f))
     {
       t = TREE_TYPE (t);
       f = TREE_TYPE (f);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 99a9ee5ade2..f3fa9c192ad 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6622,7 +6622,10 @@ convert_nontype_argument_function (tree type, tree expr,
   if (value_dependent_expression_p (fn))
     goto accept;
 
-  fn_no_ptr = strip_fnptr_conv (fn);
+  fn_no_ptr = fn;
+  if (REFERENCE_REF_P (fn_no_ptr))
+    fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
+  fn_no_ptr = strip_fnptr_conv (fn_no_ptr);
   if (TREE_CODE (fn_no_ptr) == ADDR_EXPR)
     fn_no_ptr = TREE_OPERAND (fn_no_ptr, 0);
   if (BASELINK_P (fn_no_ptr))
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept68.C b/gcc/testsuite/g++.dg/cpp0x/noexcept68.C
new file mode 100644
index 00000000000..086899a4a19
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept68.C
@@ -0,0 +1,8 @@
+// PR c++/97420
+// { dg-do compile { target c++11 } }
+
+int f(int) noexcept;
+template<int (&)(int)> void A();
+int main() {
+  A<f>();
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-05-26 13:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-26 13:08 [gcc r12-1067] c++: Fix reference NTTP binding to noexcept fn [PR97420] Patrick Palka

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).