diff options
author | Jason Merrill <jason@redhat.com> | 2015-12-20 13:38:37 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-12-20 13:38:37 -0500 |
commit | 72013ec51a97b6a709ac96845a247119e4602254 (patch) | |
tree | 59fd6f52890fff5dd866d968ff4681528d076072 /gcc/cp/semantics.c | |
parent | b6b990219342543d804a269a5409091a93e6d2ea (diff) | |
download | gcc-72013ec51a97b6a709ac96845a247119e4602254.zip gcc-72013ec51a97b6a709ac96845a247119e4602254.tar.gz gcc-72013ec51a97b6a709ac96845a247119e4602254.tar.bz2 |
re PR c++/67411 (internal compiler error: in tsubst_copy, at cp/pt.c:13473)
PR c++/67411
* lambda.c (generic_lambda_fn_p): Split out from...
(maybe_add_lambda_conv_op): ...here.
* semantics.c (process_outer_var_ref): Don't defer maybe-constant
variables in a generic lambda.
* pt.c (instantiate_non_dependent_or_null): New.
* init.c (constant_value_1): Use it.
* cp-tree.h: Declare it and generic_lambda_fn_p.
From-SVN: r231863
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r-- | gcc/cp/semantics.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b8f4e8f..ab9989a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3231,27 +3231,7 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) if (!mark_used (decl, complain) && !(complain & tf_error)) return error_mark_node; - /* Core issue 696: "[At the July 2009 meeting] the CWG expressed - support for an approach in which a reference to a local - [constant] automatic variable in a nested class or lambda body - would enter the expression as an rvalue, which would reduce - the complexity of the problem" - - FIXME update for final resolution of core issue 696. */ - if (decl_maybe_constant_var_p (decl)) - { - if (processing_template_decl) - /* In a template, the constant value may not be in a usable - form, so wait until instantiation time. */ - return decl; - else if (decl_constant_var_p (decl)) - { - tree t = maybe_constant_value (convert_from_reference (decl)); - if (TREE_CONSTANT (t)) - return t; - } - } - + bool saw_generic_lambda = false; if (parsing_nsdmi ()) containing_function = NULL_TREE; else @@ -3265,6 +3245,9 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) tree closure = DECL_CONTEXT (containing_function); lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure); + if (generic_lambda_fn_p (containing_function)) + saw_generic_lambda = true; + if (TYPE_CLASS_SCOPE_P (closure)) /* A lambda in an NSDMI (c++/64496). */ break; @@ -3281,6 +3264,35 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) = decl_function_context (containing_function); } + /* Core issue 696: "[At the July 2009 meeting] the CWG expressed + support for an approach in which a reference to a local + [constant] automatic variable in a nested class or lambda body + would enter the expression as an rvalue, which would reduce + the complexity of the problem" + + FIXME update for final resolution of core issue 696. */ + if (decl_maybe_constant_var_p (decl)) + { + if (processing_template_decl && !saw_generic_lambda) + /* In a non-generic lambda within a template, wait until instantiation + time to decide whether to capture. For a generic lambda, we can't + wait until we instantiate the op() because the closure class is + already defined at that point. FIXME to get the semantics exactly + right we need to partially-instantiate the lambda body so the only + dependencies left are on the generic parameters themselves. This + probably means moving away from our current model of lambdas in + templates (instantiating the closure type) to one based on creating + the closure type when instantiating the lambda context. That is + probably also the way to handle lambdas within pack expansions. */ + return decl; + else if (decl_constant_var_p (decl)) + { + tree t = maybe_constant_value (convert_from_reference (decl)); + if (TREE_CONSTANT (t)) + return t; + } + } + if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl)) { |