From: Jason Merrill <jason@redhat.com>
To: gcc-patches@gcc.gnu.org
Subject: [C++ PATCH] PR c++/86205 - ICE with ?: of throw and template-id.
Date: Fri, 18 Jan 2019 03:58:00 -0000 [thread overview]
Message-ID: <20190118035809.18783-1-jason@redhat.com> (raw)
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.
Tested x86_64-pc-linux-gnu, applying to trunk.
* pt.c (resolve_nondeduced_context_or_error): Split out from...
* typeck.c (decay_conversion): ...here.
* call.c (build_conditional_expr_1): Use it.
---
gcc/cp/cp-tree.h | 1 +
gcc/cp/call.c | 13 +++++++++++++
gcc/cp/pt.c | 15 +++++++++++++++
gcc/cp/typeck.c | 8 +-------
gcc/testsuite/g++.dg/cpp0x/cond2.C | 14 ++++++++++++++
gcc/cp/ChangeLog | 5 +++++
6 files changed, 49 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/cond2.C
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/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/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<int> : throw 0;
+}
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 <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.
base-commit: 978cfaf23536dc8eefd4fe79c38f564de931e1af
--
2.20.1
reply other threads:[~2019-01-18 3:58 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190118035809.18783-1-jason@redhat.com \
--to=jason@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).