On 03/08/2013 10:54 AM, Jason Merrill wrote:
My initial proposal for allowing general return type deduction allowed deduction of std::initializer_list, which is not permitted by C++11. But this doesn't make sense, because the underlying array will immediately leak, so we should just give an error even in C++1y.
As pointed out in the PR, this approach was wrong because it's possible to have an expression with std::initializer_list type; the thing returned might not have itself been a brace-enclosed init list. So let's catch that earlier.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 3d3cc430920cbb17be4e85742c34d51b94537a37 Author: Jason Merrill <ja...@redhat.com> Date: Mon Mar 11 12:03:31 2013 -0400 PR c++/56567 * typeck.c (check_return_expr): Disallow returning init list here. * semantics.c (apply_deduced_return_type): Not here. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 233765a..e909b98 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -9061,12 +9061,6 @@ apply_deduced_return_type (tree fco, tree return_type) if (return_type == error_mark_node) return; - if (is_std_init_list (return_type)) - { - error ("returning %qT", return_type); - return_type = void_type_node; - } - if (LAMBDA_FUNCTION_P (fco)) { tree lambda = CLASSTYPE_LAMBDA_EXPR (current_class_type); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 58295d7..58ebcc0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8136,6 +8136,11 @@ check_return_expr (tree retval, bool *no_warning) "deduced to %<void%>"); type = error_mark_node; } + else if (retval && BRACE_ENCLOSED_INITIALIZER_P (retval)) + { + error ("returning initializer list"); + type = error_mark_node; + } else { if (!retval) diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist3.C index 029287b..f7b82ef 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist3.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-initlist3.C @@ -5,7 +5,7 @@ int main() { - []{ return { 1, 2 }; }(); // { dg-error "initializer_list" } + []{ return { 1, 2 }; }(); // { dg-error "initializer.list" } } // { dg-prune-output "return-statement with a value" }