aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-12-21 19:16:01 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-12-21 19:16:01 +0000
commitc0a499af71a7cec55590a74b66c386cfcb11aed6 (patch)
treea9f1fcc47a948a7cf5b20b9c7d843c58e1200a64 /gcc
parentcb4b152d88b9c77f552345917601d401010dc4b3 (diff)
downloadgcc-c0a499af71a7cec55590a74b66c386cfcb11aed6.zip
gcc-c0a499af71a7cec55590a74b66c386cfcb11aed6.tar.gz
gcc-c0a499af71a7cec55590a74b66c386cfcb11aed6.tar.bz2
[PR c++/83406] deducing lambda type
https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01432.html PR c++/83406 * parser.c (cp_parser_lambda_body): Remove obsolete single-return-statement handling. PR c++/83406 * g++.dg/cpp0x/lambda/lambda-ice15.C: Adjust error. * g++.dg/cpp1y/pr83406.C: New. From-SVN: r255950
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c74
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice15.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr83406.C41
5 files changed, 68 insertions, 66 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 92a8ac6..e829550 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-21 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/83406
+ * parser.c (cp_parser_lambda_body): Remove obsolete
+ single-return-statement handling.
+
2017-12-21 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 35f4e36..57467bd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10578,98 +10578,42 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
bool nested = (current_function_decl != NULL_TREE);
bool local_variables_forbidden_p = parser->local_variables_forbidden_p;
bool in_function_body = parser->in_function_body;
+
if (nested)
push_function_context ();
else
/* Still increment function_depth so that we don't GC in the
middle of an expression. */
++function_depth;
+
vec<tree> omp_privatization_save;
save_omp_privatization_clauses (omp_privatization_save);
/* Clear this in case we're in the middle of a default argument. */
parser->local_variables_forbidden_p = false;
parser->in_function_body = true;
- /* Finish the function call operator
- - class_specifier
- + late_parsing_for_member
- + function_definition_after_declarator
- + ctor_initializer_opt_and_function_body */
{
local_specialization_stack s (lss_copy);
-
tree fco = lambda_function (lambda_expr);
tree body = start_lambda_function (fco, lambda_expr);
- bool done = false;
- tree compound_stmt;
-
matching_braces braces;
- if (!braces.require_open (parser))
- goto out;
- compound_stmt = begin_compound_stmt (0);
-
- /* 5.1.1.4 of the standard says:
- If a lambda-expression does not include a trailing-return-type, it
- is as if the trailing-return-type denotes the following type:
- * if the compound-statement is of the form
- { return attribute-specifier [opt] expression ; }
- the type of the returned expression after lvalue-to-rvalue
- conversion (_conv.lval_ 4.1), array-to-pointer conversion
- (_conv.array_ 4.2), and function-to-pointer conversion
- (_conv.func_ 4.3);
- * otherwise, void. */
-
- /* In a lambda that has neither a lambda-return-type-clause
- nor a deducible form, errors should be reported for return statements
- in the body. Since we used void as the placeholder return type, parsing
- the body as usual will give such desired behavior. */
- if (is_auto (TREE_TYPE (TREE_TYPE (fco)))
- && cp_lexer_peek_nth_token (parser->lexer, 1)->keyword == RID_RETURN
- && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SEMICOLON)
+ if (braces.require_open (parser))
{
- tree expr = NULL_TREE;
- cp_id_kind idk = CP_ID_KIND_NONE;
-
- /* Parse tentatively in case there's more after the initial return
- statement. */
- cp_parser_parse_tentatively (parser);
-
- cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN);
-
- expr = cp_parser_expression (parser, &idk);
-
- cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
- braces.require_close (parser);
+ tree compound_stmt = begin_compound_stmt (0);
- if (cp_parser_parse_definitely (parser))
- {
- if (!processing_template_decl)
- {
- tree type = lambda_return_type (expr);
- apply_deduced_return_type (fco, type);
- if (type == error_mark_node)
- expr = error_mark_node;
- }
-
- /* Will get error here if type not deduced yet. */
- finish_return_stmt (expr);
-
- done = true;
- }
- }
+ /* Originally C++11 required us to peek for 'return expr'; and
+ process it specially here to deduce the return type. N3638
+ removed the need for that. */
- if (!done)
- {
while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
cp_parser_label_declaration (parser);
cp_parser_statement_seq_opt (parser, NULL_TREE);
braces.require_close (parser);
- }
- finish_compound_stmt (compound_stmt);
+ finish_compound_stmt (compound_stmt);
+ }
- out:
finish_lambda_function (body);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2696f5e..d6928f0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-21 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/83406
+ * g++.dg/cpp0x/lambda/lambda-ice15.C: Adjust error.
+ * g++.dg/cpp1y/pr83406.C: New.
+
2017-12-21 Uros Bizjak <ubizjak@gmail.com>
PR target/83467
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice15.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice15.C
index 7c4c18d..7a04bb5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice15.C
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice15.C
@@ -5,6 +5,11 @@ class A
{
void foo ()
{
- [=] { return foo; }; // { dg-error "invalid use of member function" }
+ [=] { return foo; }; // { dg-error "cannot convert" }
+ }
+ void bar () const;
+ void bar ()
+ {
+ [=] { return bar; }; // { dg-error "unable to deduce" }
}
};
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr83406.C b/gcc/testsuite/g++.dg/cpp1y/pr83406.C
new file mode 100644
index 0000000..c348968
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr83406.C
@@ -0,0 +1,41 @@
+// { dg-do compile { target c++14 } }
+// PR 83406, lambda late returns are not the same as missing returns
+
+class Bar
+{
+public:
+ const int& getter() const;
+ int& getter();
+};
+
+auto one = [](const Bar& bar) -> decltype(auto)
+{
+ return bar.getter();
+};
+
+auto two = [](const Bar& bar) -> auto
+{
+ return bar.getter();
+};
+
+auto three = [](const Bar& bar)
+{
+ return bar.getter();
+};
+
+template <typename T, typename U> struct X
+{
+ static const bool same = false;
+};
+
+template <typename T> struct X<T,T>
+{
+ static const bool same = true;
+};
+
+void frob (Bar &x)
+{
+ static_assert (X<const int &, decltype (one (x))>::same, "not const int &");
+ static_assert (X<int, decltype (two (x))>::same, "not int");
+ static_assert (X<int, decltype (three (x))>::same, "not int");
+}