]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/gcc-tumbl.git/commitdiff
PR c++/54276
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Feb 2013 02:07:55 +0000 (02:07 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Feb 2013 02:07:55 +0000 (02:07 +0000)
* semantics.c (finish_id_expression): Also return the identifier
for an outer local static.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@196101 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template9.C [new file with mode: 0644]

index 78bf5647e657b278c9de8beba1a9cc785d4cf3f1..3a6f02fdb6b5dca92113f932993c5ca5b7d788f5 100644 (file)
@@ -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++/52026
        * semantics.c (finish_id_expression): In a template, return
        the identifier for a constant variable.
index cdc51902cd5979f372a4dda7a35aa9c830a68608..0ad32a085180a7a1d0fcdcc9ceba16f1fce92211 100644 (file)
@@ -2822,18 +2822,26 @@ 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_automatic_var_p (tree decl)
+outer_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);
 }
 
+/* As above, but also checks that DECL is automatic.  */
+
+static bool
+outer_automatic_var_p (tree decl)
+{
+  return (outer_var_p (decl)
+         && !TREE_STATIC (decl));
+}
+
 /* ID_EXPRESSION is a representation of parsed, but unprocessed,
    id-expression.  (See cp_parser_id_expression for details.)  SCOPE,
    if non-NULL, is the type or namespace used to explicitly qualify
@@ -2940,9 +2948,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;
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template9.C
new file mode 100644 (file)
index 0000000..c1d010b
--- /dev/null
@@ -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);
+}