PR c++/86205 - ICE with ?: of throw and template-id.
authorJason Merrill <jason@redhat.com>
Fri, 18 Jan 2019 03:58:22 +0000 (22:58 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 18 Jan 2019 03:58:22 +0000 (22:58 -0500)
My patch for 64372 removed a bogus lvalue-rvalue conversion for one arm of a
?: expression where the other arm is a throw.  But we still need to require
any overload to be resolved, even though we aren't getting that from
decay_conversion anymore.

* pt.c (resolve_nondeduced_context_or_error): Split out from...
* typeck.c (decay_conversion): ...here.
* call.c (build_conditional_expr_1): Use it.

From-SVN: r268058

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp0x/cond2.C [new file with mode: 0644]

index 01a57601f4c9cf4293a1dbcbe7823b8fc8138c02..3fb1a895b5ac9f18102a8cebb8bd47a84cf19a04 100644 (file)
@@ -1,5 +1,10 @@
 2019-01-17  Jason Merrill  <jason@redhat.com>
 
+       PR c++/86205 - ICE with ?: of throw and template-id.
+       * pt.c (resolve_nondeduced_context_or_error): Split out from...
+       * typeck.c (decay_conversion): ...here.
+       * call.c (build_conditional_expr_1): Use it.
+
        PR c++/86740, ICE with constexpr if and nested generic lambdas.
        * tree.c (cp_walk_subtrees): Handle LAMBDA_EXPR.
 
index 4f04b61000438e87b66597b48c885356b43b9ba1..c639f5f23e86ea4d35eb0f0179559690048e1c45 100644 (file)
@@ -5067,6 +5067,19 @@ build_conditional_expr_1 (const op_location_t &loc,
   arg3_type = unlowered_expr_type (arg3);
   if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
     {
+      /* 'void' won't help in resolving an overloaded expression on the
+        other side, so require it to resolve by itself.  */
+      if (arg2_type == unknown_type_node)
+       {
+         arg2 = resolve_nondeduced_context_or_error (arg2, complain);
+         arg2_type = TREE_TYPE (arg2);
+       }
+      if (arg3_type == unknown_type_node)
+       {
+         arg3 = resolve_nondeduced_context_or_error (arg3, complain);
+         arg3_type = TREE_TYPE (arg3);
+       }
+
       /* [expr.cond]
 
         One of the following shall hold:
index 5cc8f88d52228ae57f0b7fe8f6e5f1d08f52bf6a..23d4a0e3c690e7c4b376316a26028fcd6049be0e 100644 (file)
@@ -6831,6 +6831,7 @@ extern tree get_template_innermost_arguments      (const_tree);
 extern tree get_template_argument_pack_elems   (const_tree);
 extern tree get_function_template_decl         (const_tree);
 extern tree resolve_nondeduced_context         (tree, tsubst_flags_t);
+extern tree resolve_nondeduced_context_or_error        (tree, tsubst_flags_t);
 extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val);
 extern tree coerce_template_parms               (tree, tree, tree);
 extern tree coerce_template_parms               (tree, tree, tree, tsubst_flags_t);
index e4f76478f543c4987063512f6934cdddf35102d3..48c180cc13b3b6cde66b75d1a0b23a856e3e643e 100644 (file)
@@ -21147,6 +21147,21 @@ resolve_nondeduced_context (tree orig_expr, tsubst_flags_t complain)
   return orig_expr;
 }
 
+/* As above, but error out if the expression remains overloaded.  */
+
+tree
+resolve_nondeduced_context_or_error (tree exp, tsubst_flags_t complain)
+{
+  exp = resolve_nondeduced_context (exp, complain);
+  if (type_unknown_p (exp))
+    {
+      if (complain & tf_error)
+       cxx_incomplete_type_error (exp, TREE_TYPE (exp));
+      return error_mark_node;
+    }
+  return exp;
+}
+
 /* Subroutine of resolve_overloaded_unification; does deduction for a single
    overload.  Fills TARGS with any deduced arguments, or error_mark_node if
    different overloads deduce different arguments for a given parm.
index fc61991de350b88307fe6790f08df39504b3aaae..2fff2625bee1c3da5929f76bbe6acf2fb6a256b8 100644 (file)
@@ -2009,13 +2009,7 @@ decay_conversion (tree exp,
   if (type == error_mark_node)
     return error_mark_node;
 
-  exp = resolve_nondeduced_context (exp, complain);
-  if (type_unknown_p (exp))
-    {
-      if (complain & tf_error)
-       cxx_incomplete_type_error (exp, TREE_TYPE (exp));
-      return error_mark_node;
-    }
+  exp = resolve_nondeduced_context_or_error (exp, complain);
 
   code = TREE_CODE (type);
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/cond2.C b/gcc/testsuite/g++.dg/cpp0x/cond2.C
new file mode 100644 (file)
index 0000000..ec82dee
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/86205
+// { dg-do compile { target c++11 } }
+
+bool b;
+
+template < class T > int f ()
+{
+  return 0;
+}
+
+template < class T > auto g () -> decltype (b ? f < int > : throw 0)
+{
+  return b ? f<int> : throw 0;
+}