diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2018-03-21 22:08:34 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2018-03-21 22:08:34 +0000 |
commit | 0186f68450af9e0841f9e998609d351a5434a5b0 (patch) | |
tree | f60a71035f6cc6f57530183d8c5f038998863e36 /gcc | |
parent | 7446b353b56739bbba9a3e7852ebce8ffd19779b (diff) | |
download | gcc-0186f68450af9e0841f9e998609d351a5434a5b0.zip gcc-0186f68450af9e0841f9e998609d351a5434a5b0.tar.gz gcc-0186f68450af9e0841f9e998609d351a5434a5b0.tar.bz2 |
[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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/pr71965.C | 27 |
4 files changed, 46 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 233b57e..1271e5d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-03-21 Alexandre Oliva <aoliva@redhat.com> + 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 15cee17..3215c23 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 45705c0..ea5437a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-03-21 Alexandre Oliva <aoliva@redhat.com> + 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 0000000..6bfaef1 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr71965.C @@ -0,0 +1,27 @@ +// { dg-do compile { target c++14 } } +// { dg-options "-fconcepts" } + +template <class T> +concept bool Destructible() { + return false; +} + +template <class T, class...Args> +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<T>() && 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<T, T>); +} |