From b0f422220aa1a1a98cd89177269ece2f8b2029fd Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 17 Jan 2019 22:58:22 -0500 Subject: [PATCH] PR c++/86205 - ICE with ?: of throw and template-id. 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 | 5 +++++ gcc/cp/call.c | 13 +++++++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/pt.c | 15 +++++++++++++++ gcc/cp/typeck.c | 8 +------- gcc/testsuite/g++.dg/cpp0x/cond2.C | 14 ++++++++++++++ 6 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/cond2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 01a57601f4c..3fb1a895b5a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2019-01-17 Jason Merrill + 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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4f04b610004..c639f5f23e8 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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: diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5cc8f88d522..23d4a0e3c69 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e4f76478f54..48c180cc13b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index fc61991de35..2fff2625bee 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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 index 00000000000..ec82dee10b7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/cond2.C @@ -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 : throw 0; +} -- 2.30.2