re PR c++/54276 (Lambda in a Template Function Undefined Reference to local static)
PR c++/54276 * semantics.c (finish_id_expression): Also return the identifier for an outer local static. From-SVN: r196091
This commit is contained in:
parent
4791895176
commit
9fd30fece6
@ -1,5 +1,9 @@
|
||||
2013-02-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/54276
|
||||
* semantics.c (finish_id_expression): Also return the identifier
|
||||
for an outer local static.
|
||||
|
||||
PR c++/56343
|
||||
* class.c (check_bases_and_members): Deduce noexcept after
|
||||
checking bases.
|
||||
|
@ -2876,16 +2876,24 @@ baselink_for_fns (tree fns)
|
||||
return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
|
||||
}
|
||||
|
||||
/* Returns true iff DECL is an automatic variable from a function outside
|
||||
/* Returns true iff DECL is a variable from a function outside
|
||||
the current one. */
|
||||
|
||||
static bool
|
||||
outer_var_p (tree decl)
|
||||
{
|
||||
return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
|
||||
&& DECL_FUNCTION_SCOPE_P (decl)
|
||||
&& DECL_CONTEXT (decl) != current_function_decl);
|
||||
}
|
||||
|
||||
/* As above, but also checks that DECL is automatic. */
|
||||
|
||||
static bool
|
||||
outer_automatic_var_p (tree decl)
|
||||
{
|
||||
return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
|
||||
&& DECL_FUNCTION_SCOPE_P (decl)
|
||||
&& !TREE_STATIC (decl)
|
||||
&& DECL_CONTEXT (decl) != current_function_decl);
|
||||
return (outer_var_p (decl)
|
||||
&& !TREE_STATIC (decl));
|
||||
}
|
||||
|
||||
/* ID_EXPRESSION is a representation of parsed, but unprocessed,
|
||||
@ -2994,9 +3002,18 @@ finish_id_expression (tree id_expression,
|
||||
|
||||
/* Disallow uses of local variables from containing functions, except
|
||||
within lambda-expressions. */
|
||||
if (outer_automatic_var_p (decl)
|
||||
if (!outer_var_p (decl)
|
||||
/* It's not a use (3.2) if we're in an unevaluated context. */
|
||||
&& !cp_unevaluated_operand)
|
||||
|| cp_unevaluated_operand)
|
||||
/* OK. */;
|
||||
else if (TREE_STATIC (decl))
|
||||
{
|
||||
if (processing_template_decl)
|
||||
/* For a use of an outer static var, return the identifier so
|
||||
that we'll look it up again in the instantiation. */
|
||||
return id_expression;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree context = DECL_CONTEXT (decl);
|
||||
tree containing_function = current_function_decl;
|
||||
|
15
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template9.C
Normal file
15
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template9.C
Normal file
@ -0,0 +1,15 @@
|
||||
// PR c++/54276
|
||||
// { dg-do link { target c++11 } }
|
||||
|
||||
template <typename T>
|
||||
void foo(T)
|
||||
{
|
||||
static int x = 1;
|
||||
auto f = [] { return x + 1; };
|
||||
f();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
foo(4);
|
||||
}
|
Loading…
Reference in New Issue
Block a user