diff options
author | Jason Merrill <jason@redhat.com> | 2019-03-27 14:39:20 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-03-27 14:39:20 -0400 |
commit | 03bed1538f8c71f06dd0afa68713de019595e71e (patch) | |
tree | d96fdda8e7b4e3ad5ac5f60f34e802ca241c70c1 /gcc | |
parent | bbf1efe1b46737304cde7b35a95b30d21157e54d (diff) | |
download | gcc-03bed1538f8c71f06dd0afa68713de019595e71e.zip gcc-03bed1538f8c71f06dd0afa68713de019595e71e.tar.gz gcc-03bed1538f8c71f06dd0afa68713de019595e71e.tar.bz2 |
PR c++/89241 - ICE with lambda in template parameter list.
We were getting confused by a lambda in template definition context that
isn't actually in the scope of any templated entity. Fixed by telling
type_dependent_expression_p that such a lambda is type-dependent even if we
can't tell that from its closure type. I've also restored the error for
defining a non-lambda class in a default template argument, and for a lambda
befor C++20.
* parser.c (cp_parser_lambda_expression): Also reject a lambda in a
template parameter list before C++20.
* pt.c (type_dependent_expression_p): True for LAMBDA_EXPR.
* semantics.c (begin_class_definition): Restore error about defining
non-lambda class in template parm list.
From-SVN: r269972
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/lambda-uneval10.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/complit16.C | 5 |
6 files changed, 39 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bce9b10..4807194 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2019-03-27 Jason Merrill <jason@redhat.com> + + PR c++/89241 - ICE with lambda in template parameter list. + * parser.c (cp_parser_lambda_expression): Also reject a lambda in a + template parameter list before C++20. + * pt.c (type_dependent_expression_p): True for LAMBDA_EXPR. + * semantics.c (begin_class_definition): Restore error about defining + non-lambda class in template parm list. + 2019-03-26 Jason Merrill <jason@redhat.com> PR c++/86932 - missed SFINAE with empty pack. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4119d2a..348e4ac 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10397,7 +10397,7 @@ cp_parser_lambda_expression (cp_parser* parser) } ok = false; } - else if (parser->in_template_argument_list_p) + else if (parser->in_template_argument_list_p || processing_template_parmlist) { if (!token->error_reported) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dc982f3..229b34a 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -25692,6 +25692,12 @@ type_dependent_expression_p (tree expression) || TREE_CODE (expression) == WILDCARD_DECL) return true; + /* A lambda-expression in template context is dependent. dependent_type_p is + true for a lambda in the scope of a class or function template, but that + doesn't cover all template contexts, like a default template argument. */ + if (TREE_CODE (expression) == LAMBDA_EXPR) + return true; + /* A fold expression is type-dependent. */ if (TREE_CODE (expression) == UNARY_LEFT_FOLD_EXPR || TREE_CODE (expression) == UNARY_RIGHT_FOLD_EXPR diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index d7e97e0..fea2696 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3043,6 +3043,12 @@ begin_class_definition (tree t) if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t))) return error_mark_node; + if (processing_template_parmlist && !LAMBDA_TYPE_P (t)) + { + error ("definition of %q#T inside template parameter list", t); + return error_mark_node; + } + /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733 are passed the same as decimal scalar types. */ if (TREE_CODE (t) == RECORD_TYPE diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval10.C b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval10.C new file mode 100644 index 0000000..86065eb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval10.C @@ -0,0 +1,12 @@ +// PR c++/89421 + +template <int I = []{return 1;}()> // { dg-message "lambda" "" { target c++17_down } } +struct B +{ + static const int i = I; +}; + +#if __cplusplus > 201703L +B<> b; +static_assert (b.i == 1); +#endif diff --git a/gcc/testsuite/g++.dg/ext/complit16.C b/gcc/testsuite/g++.dg/ext/complit16.C new file mode 100644 index 0000000..5625ced --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit16.C @@ -0,0 +1,5 @@ +// { dg-options "" } + +template <int = (struct A{int i;}){42}.i> struct B{}; // { dg-error "" } + +B<0> b; |