From 0186f68450af9e0841f9e998609d351a5434a5b0 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 21 Mar 2018 22:08:34 +0000 Subject: [PATCH] [PR c++/71965] silence multi-dim array init sorry without tf_error We shouldn't substitute templates into short-circuited-out concepts constraints, but we do, and to add insult to injury, we issue a sorry() error when a concept that shouldn't even have been substituted attempts to perform a multi-dimensional array initialization with a new{} expression. Although fixing the requirements short-circuiting is probably too risky at this point, we can get closer to the intended effect by silencing that sorry just as we silence other errors. for gcc/cp/ChangeLog PR c++/71965 * init.c (build_vec_init): Silence error, former sorry, without tf_error. for gcc/testsuite/ChangeLog PR c++/71965 * g++.dg/concepts/pr71965.C: New. From-SVN: r258749 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/init.c | 19 ++++++++++------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/concepts/pr71965.C | 27 +++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/concepts/pr71965.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 233b57e2620..1271e5dca21 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-03-21 Alexandre Oliva + PR c++/71965 + * init.c (build_vec_init): Silence error, former sorry, + without tf_error. + PR c++/84610 PR c++/84642 * parser.c (abort_fully_implicit_template_p): New. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 15cee17c780..3215c238554 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -4384,12 +4384,17 @@ build_vec_init (tree base, tree maxindex, tree init, else if (TREE_CODE (type) == ARRAY_TYPE) { if (init && !BRACE_ENCLOSED_INITIALIZER_P (init)) - sorry - ("cannot initialize multi-dimensional array with initializer"); - elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), - 0, init, - explicit_value_init_p, - 0, complain); + { + if ((complain & tf_error)) + error_at (loc, "array must be initialized " + "with a brace-enclosed initializer"); + elt_init = error_mark_node; + } + else + elt_init = build_vec_init (build1 (INDIRECT_REF, type, base), + 0, init, + explicit_value_init_p, + 0, complain); } else if (explicit_value_init_p) { @@ -4449,7 +4454,7 @@ build_vec_init (tree base, tree maxindex, tree init, } current_stmt_tree ()->stmts_are_full_exprs_p = 1; - if (elt_init) + if (elt_init && !errors) finish_expr_stmt (elt_init); current_stmt_tree ()->stmts_are_full_exprs_p = 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 45705c0eacb..ea5437a7a17 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-03-21 Alexandre Oliva + PR c++/71965 + * g++.dg/concepts/pr71965.C: New. + PR c++/84610 PR c++/84642 * g++.dg/cpp0x/pr84610.C: New. diff --git a/gcc/testsuite/g++.dg/concepts/pr71965.C b/gcc/testsuite/g++.dg/concepts/pr71965.C new file mode 100644 index 00000000000..6bfaef19211 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr71965.C @@ -0,0 +1,27 @@ +// { dg-do compile { target c++14 } } +// { dg-options "-fconcepts" } + +template +concept bool Destructible() { + return false; +} + +template +concept bool ConstructibleObject = + // Concept evaluation should short-circuit even the template + // substitution, so we shouldn't even substitute into the requires + // constraint and the unimplemented multi-dimensional new T{...} + // initialization. ATM we do, but as long as we don't output the + // sorry() message we used to for such constructs when asked not + // to issue errors, this shouldn't be a problem for this and + // similar cases. + Destructible() && requires (Args&&...args) { + new T{ (Args&&)args... }; + }; + +int main() { + using T = int[2][2]; + // GCC has not implemented initialization of multi-dimensional + // arrays with new{} expressions. + static_assert(!ConstructibleObject); +}