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>
|
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
|
PR c++/56343
|
||||||
* class.c (check_bases_and_members): Deduce noexcept after
|
* class.c (check_bases_and_members): Deduce noexcept after
|
||||||
checking bases.
|
checking bases.
|
||||||
|
@ -2876,16 +2876,24 @@ baselink_for_fns (tree fns)
|
|||||||
return build_baselink (cl, cl, fns, /*optype=*/NULL_TREE);
|
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. */
|
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
|
static bool
|
||||||
outer_automatic_var_p (tree decl)
|
outer_automatic_var_p (tree decl)
|
||||||
{
|
{
|
||||||
return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
|
return (outer_var_p (decl)
|
||||||
&& DECL_FUNCTION_SCOPE_P (decl)
|
&& !TREE_STATIC (decl));
|
||||||
&& !TREE_STATIC (decl)
|
|
||||||
&& DECL_CONTEXT (decl) != current_function_decl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ID_EXPRESSION is a representation of parsed, but unprocessed,
|
/* 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
|
/* Disallow uses of local variables from containing functions, except
|
||||||
within lambda-expressions. */
|
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. */
|
/* 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 context = DECL_CONTEXT (decl);
|
||||||
tree containing_function = current_function_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