Hi,

a related/duplicate issue went into Bugzilla today, thus I decided to return to the RFC/Patch which I posted back in December (http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01593.html): as far as I can see my analysis still stands and, to be clear, I'm proposing this kind of patch for post-4.7.0, at this point. The below, compared to the old draft proposal is a bit tidier, but should still do the right thing, it fixes the new more involved testcase too.

Tested x86_64-linux.

Thanks,
Paolo.

////////////////////
/cp
2012-02-09  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/51494
        PR c++/52183
        * tree.c (maybe_dummy_object): Add a bool parameter.
        * cp-tree.h (maybe_dummy_object): Update.
        * semantics.c (finish_call_expr): Adjust call, pass
        non_static_member_function_p (fn) as boolean argument.
        (finish_non_static_data_member, finish_qualified_id_expr,
        finish_id_expression): Adjust calls.
        * typeck.c (convert_member_func_to_ptr): Likewise.
        * init.c (build_offset_ref): Likewise.

/testsuite
2012-02-09  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/51494
        PR c++/52183
        * g++.dg/cpp0x/lambda/lambda-51494.C: New.

Index: testsuite/g++.dg/cpp0x/lambda/lambda-51494.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-51494.C        (revision 0)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-51494.C        (revision 0)
@@ -0,0 +1,12 @@
+// PR c++/51494
+// { dg-options -std=c++0x }
+
+struct A
+{
+  static void f() {}
+
+  void foo()
+  {
+    [] () { f(); };
+  }
+};
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 184041)
+++ cp/typeck.c (working copy)
@@ -6112,7 +6112,7 @@ convert_member_func_to_ptr (tree type, tree expr)
     expr = build_address (PTRMEM_CST_MEMBER (expr));
   else
     {
-      decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0);
+      decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype), 0, true);
       decl = build_address (decl);
       expr = get_member_function_from_ptrfunc (&decl, expr);
     }
Index: cp/init.c
===================================================================
--- cp/init.c   (revision 184041)
+++ cp/init.c   (working copy)
@@ -1,7 +1,7 @@
 /* Handle initialization things in C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011 Free Software Foundation, Inc.
+   2011, 2012 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiem...@cygnus.com)
 
 This file is part of GCC.
@@ -1847,7 +1847,7 @@ build_offset_ref (tree type, tree member, bool add
     }
 
   /* Set up BASEBINFO for member lookup.  */
-  decl = maybe_dummy_object (type, &basebinfo);
+  decl = maybe_dummy_object (type, &basebinfo, true);
 
   /* A lot of this logic is now handled in lookup_member.  */
   if (BASELINK_P (member))
Index: cp/tree.c
===================================================================
--- cp/tree.c   (revision 184041)
+++ cp/tree.c   (working copy)
@@ -1,6 +1,7 @@
 /* Language-dependent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011,
+   2012
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiem...@cygnus.com)
 
@@ -2553,10 +2554,11 @@ build_dummy_object (tree type)
 
 /* We've gotten a reference to a member of TYPE.  Return *this if appropriate,
    or a dummy object otherwise.  If BINFOP is non-0, it is filled with the
-   binfo path from current_class_type to TYPE, or 0.  */
+   binfo path from current_class_type to TYPE, or 0.  If MAYBE_CAPTURE_THIS
+   is false, in a lambda we don't want to capture 'this'.  */
 
 tree
-maybe_dummy_object (tree type, tree* binfop)
+maybe_dummy_object (tree type, tree* binfop, bool maybe_capture_this)
 {
   tree decl, context;
   tree binfo;
@@ -2583,7 +2585,8 @@ tree
          (TREE_TYPE (current_class_ref), context)))
     decl = current_class_ref;
   else if (current != current_class_type
-          && context == nonlambda_method_basetype ())
+          && context == nonlambda_method_basetype ()
+          && maybe_capture_this)
     /* In a lambda, need to go through 'this' capture.  */
     decl = (build_x_indirect_ref
            ((lambda_expr_this_capture
Index: cp/semantics.c
===================================================================
--- cp/semantics.c      (revision 184041)
+++ cp/semantics.c      (working copy)
@@ -1538,7 +1538,7 @@ finish_non_static_data_member (tree decl, tree obj
       tree scope = qualifying_scope;
       if (scope == NULL_TREE)
        scope = context_for_name_lookup (decl);
-      object = maybe_dummy_object (scope, NULL);
+      object = maybe_dummy_object (scope, NULL, true);
     }
 
   if (object == error_mark_node)
@@ -1780,7 +1780,7 @@ finish_qualified_id_expr (tree qualifying_class,
       /* See if any of the functions are non-static members.  */
       /* If so, the expression may be relative to 'this'.  */
       if (!shared_member_p (expr)
-         && (ob = maybe_dummy_object (qualifying_class, NULL),
+         && (ob = maybe_dummy_object (qualifying_class, NULL, true),
              !is_dummy_object (ob)))
        expr = (build_class_member_access_expr
                (ob,
@@ -2132,7 +2132,7 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bo
        part of the access, so we pass 'B' to maybe_dummy_object.  */
 
       object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
-                                  NULL);
+                                  NULL, non_static_member_function_p (fn));
 
       if (processing_template_decl)
        {
@@ -3312,7 +3312,7 @@ finish_id_expression (tree id_expression,
              && !shared_member_p (decl))
            {
              /* A set of member functions.  */
-             decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
+             decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0, true);
              return finish_class_member_access_expr (decl, id_expression,
                                                      /*template_p=*/false,
                                                      tf_warning_or_error);
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h        (revision 184041)
+++ cp/cp-tree.h        (working copy)
@@ -1,6 +1,7 @@
 /* Definitions for C++ parsing and type checking.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+   2012
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiem...@cygnus.com)
 
@@ -5704,7 +5705,7 @@ extern bool cp_tree_equal                 (tree, tree);
 extern tree no_linkage_check                   (tree, bool);
 extern void debug_binfo                                (tree);
 extern tree build_dummy_object                 (tree);
-extern tree maybe_dummy_object                 (tree, tree *);
+extern tree maybe_dummy_object                 (tree, tree *, bool);
 extern int is_dummy_object                     (const_tree);
 extern const struct attribute_spec cxx_attribute_table[];
 extern tree make_ptrmem_cst                    (tree, tree);

Reply via email to