public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-7632] c++: ICE with bad conversion shortcutting [PR104622]
@ 2022-03-12 20:02 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2022-03-12 20:02 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:03c83cf7aa1110e427beb00ea95767dfaf50d694

commit r12-7632-g03c83cf7aa1110e427beb00ea95767dfaf50d694
Author: Patrick Palka <ppalka@redhat.com>
Date:   Sat Mar 12 15:00:49 2022 -0500

    c++: ICE with bad conversion shortcutting [PR104622]
    
    When shortcutting bad argument conversions during overload resolution,
    we assume conversions get computed in sequential order and that therefore
    the conversion array is incomplete iff the last conversion is missing.
    But this assumption turns out to be wrong for templates, because during
    deduction check_non_deducible_conversion can compute an argument
    conversion out of order.
    
    So in the testcase below, at the end of add_template_candidate the
    conversion array looks like {bad_conv, NULL, good_conv} where the last
    conversion was computed during deduction and the first one later from
    add_function_candidate.  We need to add this candidate to bad_fns since
    not all of its argument conversions were computed, but we don't do so
    because the last conversion isn't missing.
    
    This patch fixes this by checking for a missing conversion exhaustively
    instead.  In passing, this cleans up check_non_deducible_conversion given
    that the only values of 'strict' we expect to see here the enumerators
    of unification_kind_t.
    
            PR c++/104622
    
    gcc/cp/ChangeLog:
    
            * call.cc (missing_conversion_p): Define.
            (add_candidates): Use it.
            * pt.cc (check_non_deducible_conversion): Change type of strict
            parameter to unification_kind_t and directly test for DEDUCE_CALL.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/conv18.C: New test.

Diff:
---
 gcc/cp/call.cc                         | 13 ++++++++++++-
 gcc/cp/pt.cc                           |  6 +++---
 gcc/testsuite/g++.dg/template/conv18.C | 14 ++++++++++++++
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index d6eed5ed835..8fe8ef306ea 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -6023,6 +6023,17 @@ perfect_candidate_p (z_candidate *cand)
   return true;
 }
 
+/* True iff one of CAND's argument conversions is NULL.  */
+
+static bool
+missing_conversion_p (const z_candidate *cand)
+{
+  for (unsigned i = 0; i < cand->num_convs; ++i)
+    if (!cand->convs[i])
+      return true;
+  return false;
+}
+
 /* Add each of the viable functions in FNS (a FUNCTION_DECL or
    OVERLOAD) to the CANDIDATES, returning an updated list of
    CANDIDATES.  The ARGS are the arguments provided to the call;
@@ -6200,7 +6211,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
 
       if (cand->viable == -1
 	  && shortcut_bad_convs
-	  && !cand->convs[cand->reversed () ? 0 : cand->num_convs - 1])
+	  && missing_conversion_p (cand))
 	{
 	  /* This candidate has been tentatively marked non-strictly viable,
 	     and we didn't compute all argument conversions for it (having
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f7ee33a6dfd..67a49c7c67b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -152,7 +152,7 @@ static tree coerce_innermost_template_parms (tree, tree, tree, tsubst_flags_t,
 					      bool, bool);
 static void tsubst_enum	(tree, tree, tree);
 static bool check_instantiated_args (tree, tree, tsubst_flags_t);
-static int check_non_deducible_conversion (tree, tree, int, int,
+static int check_non_deducible_conversion (tree, tree, unification_kind_t, int,
 					   struct conversion **, bool);
 static int maybe_adjust_types_for_deduction (tree, unification_kind_t,
 					     tree*, tree*, tree);
@@ -22287,7 +22287,7 @@ maybe_adjust_types_for_deduction (tree tparms,
    unify_one_argument.  */
 
 static int
-check_non_deducible_conversion (tree parm, tree arg, int strict,
+check_non_deducible_conversion (tree parm, tree arg, unification_kind_t strict,
 				int flags, struct conversion **conv_p,
 				bool explain_p)
 {
@@ -22307,7 +22307,7 @@ check_non_deducible_conversion (tree parm, tree arg, int strict,
       if (can_convert_arg (type, parm, NULL_TREE, flags, complain))
 	return unify_success (explain_p);
     }
-  else if (strict != DEDUCE_EXACT)
+  else if (strict == DEDUCE_CALL)
     {
       bool ok = false;
       tree conv_arg = TYPE_P (arg) ? NULL_TREE : arg;
diff --git a/gcc/testsuite/g++.dg/template/conv18.C b/gcc/testsuite/g++.dg/template/conv18.C
new file mode 100644
index 00000000000..f59f6fda77c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/conv18.C
@@ -0,0 +1,14 @@
+// PR c++/104622
+// { dg-additional-options "-fpermissive" }
+
+template<class T>
+struct type_identity {
+  typedef T type;
+};
+
+template<class T> void f(typename type_identity<T>::type*, T, int*);
+
+int main() {
+  const int p = 0;
+  f(&p, 0, 0); // { dg-warning "invalid conversion" }
+}


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

only message in thread, other threads:[~2022-03-12 20:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-12 20:02 [gcc r12-7632] c++: ICE with bad conversion shortcutting [PR104622] 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).