public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR c++/60463, PE c++/60755 Incorrect discard of const qualifier
@ 2014-04-14 20:53 Momchil Velikov
  2014-05-01  9:10 ` [PATCH] Fix PR c++/60463, PR " Momchil Velikov
  0 siblings, 1 reply; 4+ messages in thread
From: Momchil Velikov @ 2014-04-14 20:53 UTC (permalink / raw)
  To: gcc-patches

Hello,

During overload resolution of function calls in the body of a lambda it
is possible to use an implicit/dummy 'this', which differs in const-ness
from the actual 'this' that would be captured, resulting in choosing a
non-const member function even when the captured 'this' is const. This
patch makes sure that the captured 'this' is the same as the one used in
the overload resolution.

Bootstrapped and tested with no regressions relative to version
4.10.0 20140414 (experimental) [master revision
98acb41:a7ec718:cb799f0a61f3adef32474ad4e01ffb4b8b45778d] on
x86_64-unknown-linux-gnu.

~chill


diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bf61ab7..7308b57 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2014-04-14  Momchil Velikov  <momchil.velikov@gmail.com>
+
+	PR c++/60463
+	PR c++/60755
+	* lambda.c (lambda_expr_this_capture): Add new parameter
+	add_capture_p controlling whether the functions will try to
+	capture 'this' via the default capture.
+	(maybe_resolve_dummy): Likewise.
+	* cp-tree.h: Adjust prototypes.
+	* call.c, semantics.c: Change callers of these functions.
+	* call.c (build_new_method_call_1): Use the actual 'this' that
+	would be potentially captured for the overload resolution, instead
+	of the dummy object.
+
  2014-04-11  Jason Merrill  <jason@redhat.com>
  
  	* parser.h (struct cp_token): Rename ambiguous_p to error_reported.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7c0dcc2..df22df4 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7720,7 +7720,11 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
    if (DECL_DESTRUCTOR_P (fn))
      name = complete_dtor_identifier;
  
-  first_mem_arg = instance;
+  /* For the overload resolution we need to find the actual `this`
+     that would be captured if the call turns out to be to a
+     non-static member function.  Do not actually capture it at this
+     point.  */
+  first_mem_arg = maybe_resolve_dummy (instance, false);
  
    /* Get the high-water mark for the CONVERSION_OBSTACK.  */
    p = conversion_obstack_alloc (0);
@@ -7858,7 +7862,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
  	  if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
  	      && is_dummy_object (instance))
  	    {
-	      instance = maybe_resolve_dummy (instance);
+	      instance = maybe_resolve_dummy (instance, true);
  	      if (instance == error_mark_node)
  		call = error_mark_node;
  	      else if (!is_dummy_object (instance))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index bafc32d..e020251 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5881,8 +5881,8 @@ extern void insert_pending_capture_proxies	(void);
  extern bool is_capture_proxy			(tree);
  extern bool is_normal_capture_proxy             (tree);
  extern void register_capture_members		(tree);
-extern tree lambda_expr_this_capture            (tree);
-extern tree maybe_resolve_dummy			(tree);
+extern tree lambda_expr_this_capture            (tree, bool);
+extern tree maybe_resolve_dummy			(tree, bool);
  extern tree nonlambda_method_basetype		(void);
  extern void maybe_add_lambda_conv_op            (tree);
  extern bool is_lambda_ignored_entity            (tree);
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 0b8b46a..3de1f15 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -620,11 +620,12 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
    return var;
  }
  
-/* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an
-   INDIRECT_REF, possibly adding it through default capturing.  */
+/* Return the capture pertaining to a use of 'this' in LAMBDA, in the
+   form of an INDIRECT_REF, possibly adding it through default
+   capturing, if ADD_CAPTURE_P is false.  */
  
  tree
-lambda_expr_this_capture (tree lambda)
+lambda_expr_this_capture (tree lambda, bool add_capture_p)
  {
    tree result;
  
@@ -644,7 +645,8 @@ lambda_expr_this_capture (tree lambda)
  
    /* Try to default capture 'this' if we can.  */
    if (!this_capture
-      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
+      && (!add_capture_p
+          || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE))
      {
        tree lambda_stack = NULL_TREE;
        tree init = NULL_TREE;
@@ -704,9 +706,14 @@ lambda_expr_this_capture (tree lambda)
  	}
  
        if (init)
-	this_capture = add_default_capture (lambda_stack,
-					    /*id=*/this_identifier,
-					    init);
+        {
+          if (add_capture_p)
+	    this_capture = add_default_capture (lambda_stack,
+					        /*id=*/this_identifier,
+					        init);
+          else
+	    this_capture = init;
+        }
      }
  
    if (!this_capture)
@@ -738,7 +745,7 @@ lambda_expr_this_capture (tree lambda)
     'this' capture.  */
  
  tree
-maybe_resolve_dummy (tree object)
+maybe_resolve_dummy (tree object, bool add_capture_p)
  {
    if (!is_dummy_object (object))
      return object;
@@ -754,7 +761,7 @@ maybe_resolve_dummy (tree object)
      {
        /* In a lambda, need to go through 'this' capture.  */
        tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
-      tree cap = lambda_expr_this_capture (lam);
+      tree cap = lambda_expr_this_capture (lam, add_capture_p);
        object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
  				     RO_NULL, tf_warning_or_error);
      }
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 795086a..97f7351 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1675,7 +1675,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
        object = maybe_dummy_object (scope, NULL);
      }
  
-  object = maybe_resolve_dummy (object);
+  object = maybe_resolve_dummy (object, true);
    if (object == error_mark_node)
      return error_mark_node;
  
@@ -2434,7 +2434,7 @@ finish_this_expr (void)
  
        /* In a lambda expression, 'this' refers to the captured 'this'.  */
        if (LAMBDA_TYPE_P (type))
-        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
+        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type), true);
        else
          result = current_class_ptr;
      }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6992ad6..866a7e2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-14  Momchil Velikov  <momchil.velikov@gmail.com>
+
+	PR c++/60463
+	PR c++/60755
+	* g++.dg/cpp0x/lambda/lambda-const-this.C: New testcase.
+
  2014-04-14  Richard Biener  <rguenther@suse.de>
  
  	PR middle-end/55022
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C
new file mode 100644
index 0000000..2de00d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C
@@ -0,0 +1,9 @@
+// PR c++/60463
+// PR c++/60755
+// { dg-do compile { target c++11 } }
+struct S {
+  void f(); // { dg-message "no known conversion for implicit 'this' parameter from 'const S\\*' to 'S\\*'" }
+  void g() const {
+    [=] { f(); } (); // { dg-error "no matching function for call to 'S::f\\(\\)'" }
+  }
+};

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR c++/60463, PR c++/60755 Incorrect discard of const qualifier
  2014-04-14 20:53 [PATCH] Fix PR c++/60463, PE c++/60755 Incorrect discard of const qualifier Momchil Velikov
@ 2014-05-01  9:10 ` Momchil Velikov
  2014-05-09  8:27   ` Momchil Velikov
  0 siblings, 1 reply; 4+ messages in thread
From: Momchil Velikov @ 2014-05-01  9:10 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 673 bytes --]

On 14.04.2014 23:53, Momchil Velikov wrote:

Ping

> Hello,
>
> During overload resolution of function calls in the body of a lambda it
> is possible to use an implicit/dummy 'this', which differs in const-ness
> from the actual 'this' that would be captured, resulting in choosing a
> non-const member function even when the captured 'this' is const. This
> patch makes sure that the captured 'this' is the same as the one used in
> the overload resolution.

Bootstrapped and regtested again with xgcc (GCC) 4.10.0 20140430 (experimental)
[master revision b069c2a:edc7cc5:af379dd3ed2b932a506437bca77ea4f4c320dbb4]
with no regressions on x86_64-unknown-linux-gnu.

~chill


[-- Attachment #2: this-capture-overload-fix.diff --]
[-- Type: text/x-patch, Size: 6456 bytes --]

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b201825..bb89e8f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+2014-04-30  Momchil Velikov  <momchil.velikov@gmail.com>
+
+	PR c++/60463
+	PR c++/60755
+	* lambda.c (lambda_expr_this_capture): Add new parameter
+	add_capture_p controlling whether the functions will try to
+	capture 'this' via the default capture.
+	(maybe_resolve_dummy): Likewise.
+	* cp-tree.h: Adjust prototypes.
+	* call.c, semantics.c: Change callers of these functions.
+	* call.c (build_new_method_call_1): Use the actual 'this' that
+	would be potentially captured for the overload resolution, instead
+	of the dummy object.
+
 2014-04-29  Jason Merrill  <jason@redhat.com>
 
 	DR 1351
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8c55c32..a3aaebb 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7727,7 +7727,11 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
   if (DECL_DESTRUCTOR_P (fn))
     name = complete_dtor_identifier;
 
-  first_mem_arg = instance;
+  /* For the overload resolution we need to find the actual `this`
+     that would be captured if the call turns out to be to a
+     non-static member function.  Do not actually capture it at this
+     point.  */
+  first_mem_arg = maybe_resolve_dummy (instance, false);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
@@ -7865,7 +7869,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
 	      && !DECL_CONSTRUCTOR_P (fn)
 	      && is_dummy_object (instance))
 	    {
-	      instance = maybe_resolve_dummy (instance);
+	      instance = maybe_resolve_dummy (instance, true);
 	      if (instance == error_mark_node)
 		call = error_mark_node;
 	      else if (!is_dummy_object (instance))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 55ecc4e..4a45cc1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5889,8 +5889,8 @@ extern void insert_pending_capture_proxies	(void);
 extern bool is_capture_proxy			(tree);
 extern bool is_normal_capture_proxy             (tree);
 extern void register_capture_members		(tree);
-extern tree lambda_expr_this_capture            (tree);
-extern tree maybe_resolve_dummy			(tree);
+extern tree lambda_expr_this_capture            (tree, bool);
+extern tree maybe_resolve_dummy			(tree, bool);
 extern tree nonlambda_method_basetype		(void);
 extern void maybe_add_lambda_conv_op            (tree);
 extern bool is_lambda_ignored_entity            (tree);
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 0b8b46a..3de1f15 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -620,11 +620,12 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
   return var;
 }
 
-/* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an
-   INDIRECT_REF, possibly adding it through default capturing.  */
+/* Return the capture pertaining to a use of 'this' in LAMBDA, in the
+   form of an INDIRECT_REF, possibly adding it through default
+   capturing, if ADD_CAPTURE_P is false.  */
 
 tree
-lambda_expr_this_capture (tree lambda)
+lambda_expr_this_capture (tree lambda, bool add_capture_p)
 {
   tree result;
 
@@ -644,7 +645,8 @@ lambda_expr_this_capture (tree lambda)
 
   /* Try to default capture 'this' if we can.  */
   if (!this_capture
-      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
+      && (!add_capture_p
+          || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE))
     {
       tree lambda_stack = NULL_TREE;
       tree init = NULL_TREE;
@@ -704,9 +706,14 @@ lambda_expr_this_capture (tree lambda)
 	}
 
       if (init)
-	this_capture = add_default_capture (lambda_stack,
-					    /*id=*/this_identifier,
-					    init);
+        {
+          if (add_capture_p)
+	    this_capture = add_default_capture (lambda_stack,
+					        /*id=*/this_identifier,
+					        init);
+          else
+	    this_capture = init;
+        }
     }
 
   if (!this_capture)
@@ -738,7 +745,7 @@ lambda_expr_this_capture (tree lambda)
    'this' capture.  */
 
 tree
-maybe_resolve_dummy (tree object)
+maybe_resolve_dummy (tree object, bool add_capture_p)
 {
   if (!is_dummy_object (object))
     return object;
@@ -754,7 +761,7 @@ maybe_resolve_dummy (tree object)
     {
       /* In a lambda, need to go through 'this' capture.  */
       tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
-      tree cap = lambda_expr_this_capture (lam);
+      tree cap = lambda_expr_this_capture (lam, add_capture_p);
       object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
 				     RO_NULL, tf_warning_or_error);
     }
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3f8ca44..2632fd6 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1675,7 +1675,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
       object = maybe_dummy_object (scope, NULL);
     }
 
-  object = maybe_resolve_dummy (object);
+  object = maybe_resolve_dummy (object, true);
   if (object == error_mark_node)
     return error_mark_node;
 
@@ -2434,7 +2434,7 @@ finish_this_expr (void)
 
       /* In a lambda expression, 'this' refers to the captured 'this'.  */
       if (LAMBDA_TYPE_P (type))
-        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
+        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type), true);
       else
         result = current_class_ptr;
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index de10503..df792c8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-30  Momchil Velikov  <momchil.velikov@gmail.com>
+
+	PR c++/60463
+	PR c++/60755
+	* g++.dg/cpp0x/lambda/lambda-const-this.C: New testcase.
+
 2014-04-30  Marek Polacek  <polacek@redhat.com>
 
 	PR c/60139
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C
new file mode 100644
index 0000000..2de00d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C
@@ -0,0 +1,9 @@
+// PR c++/60463
+// PR c++/60755
+// { dg-do compile { target c++11 } }
+struct S {
+  void f(); // { dg-message "no known conversion for implicit 'this' parameter from 'const S\\*' to 'S\\*'" }
+  void g() const {
+    [=] { f(); } (); // { dg-error "no matching function for call to 'S::f\\(\\)'" }
+  }
+};

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR c++/60463, PR c++/60755 Incorrect discard of const qualifier
  2014-05-01  9:10 ` [PATCH] Fix PR c++/60463, PR " Momchil Velikov
@ 2014-05-09  8:27   ` Momchil Velikov
  2014-05-09 20:07     ` Jason Merrill
  0 siblings, 1 reply; 4+ messages in thread
From: Momchil Velikov @ 2014-05-09  8:27 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

[-- Attachment #1: Type: text/plain, Size: 1341 bytes --]

Ping

>> On 14.04.2014 23:53, Momchil Velikov wrote:
>> Hello,
>>
>> During overload resolution of function calls in the body of a lambda it
>> is possible to use an implicit/dummy 'this', which differs in const-ness
>> from the actual 'this' that would be captured, resulting in choosing a
>> non-const member function even when the captured 'this' is const. This
>> patch makes sure that the captured 'this' is the same as the one used in
>> the overload resolution.

Bootstrapped/regtested for C/C++ on x86_64-unknown-linux-gnu against
xg++ (GCC) 4.10.0 20140508 (experimental) [master revision ed50168:49aa3a5:e79f58c7b12f37014efb7425399c93814cddb4c4]


~chill

2014-05-08  Momchil Velikov  <momchil.velikov@gmail.com>

	PR c++/60463
	PR c++/60755
	* lambda.c (lambda_expr_this_capture): Add new parameter
	add_capture_p controlling whether the functions will try to
	capture 'this' via the default capture.
	(maybe_resolve_dummy): Likewise.
	* cp-tree.h: Adjust prototypes.
	* call.c, semantics.c: Change callers of these functions.
	* call.c (build_new_method_call_1): Use the actual 'this' that
	would be potentially captured for the overload resolution, instead
	of the dummy object.

2014-05-08  Momchil Velikov  <momchil.velikov@gmail.com>

	PR c++/60463
	PR c++/60755
	* g++.dg/cpp0x/lambda/lambda-const-this.C: New testcase.





[-- Attachment #2: this-capture-overload-fix.diff --]
[-- Type: text/x-patch, Size: 5332 bytes --]

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 857df57..bfedfef 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7726,7 +7726,11 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
   if (DECL_DESTRUCTOR_P (fn))
     name = complete_dtor_identifier;
 
-  first_mem_arg = instance;
+  /* For the overload resolution we need to find the actual `this`
+     that would be captured if the call turns out to be to a
+     non-static member function.  Do not actually capture it at this
+     point.  */
+  first_mem_arg = maybe_resolve_dummy (instance, false);
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
@@ -7864,7 +7868,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
 	      && !DECL_CONSTRUCTOR_P (fn)
 	      && is_dummy_object (instance))
 	    {
-	      instance = maybe_resolve_dummy (instance);
+	      instance = maybe_resolve_dummy (instance, true);
 	      if (instance == error_mark_node)
 		call = error_mark_node;
 	      else if (!is_dummy_object (instance))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 34d3d20..ed8d099 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5890,8 +5890,8 @@ extern void insert_pending_capture_proxies	(void);
 extern bool is_capture_proxy			(tree);
 extern bool is_normal_capture_proxy             (tree);
 extern void register_capture_members		(tree);
-extern tree lambda_expr_this_capture            (tree);
-extern tree maybe_resolve_dummy			(tree);
+extern tree lambda_expr_this_capture            (tree, bool);
+extern tree maybe_resolve_dummy			(tree, bool);
 extern tree nonlambda_method_basetype		(void);
 extern void maybe_add_lambda_conv_op            (tree);
 extern bool is_lambda_ignored_entity            (tree);
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 5ba6f14..3ce9ebb 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -624,11 +624,12 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
   return var;
 }
 
-/* Return the capture pertaining to a use of 'this' in LAMBDA, in the form of an
-   INDIRECT_REF, possibly adding it through default capturing.  */
+/* Return the capture pertaining to a use of 'this' in LAMBDA, in the
+   form of an INDIRECT_REF, possibly adding it through default
+   capturing, if ADD_CAPTURE_P is false.  */
 
 tree
-lambda_expr_this_capture (tree lambda)
+lambda_expr_this_capture (tree lambda, bool add_capture_p)
 {
   tree result;
 
@@ -648,7 +649,8 @@ lambda_expr_this_capture (tree lambda)
 
   /* Try to default capture 'this' if we can.  */
   if (!this_capture
-      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
+      && (!add_capture_p
+          || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE))
     {
       tree lambda_stack = NULL_TREE;
       tree init = NULL_TREE;
@@ -708,9 +710,14 @@ lambda_expr_this_capture (tree lambda)
 	}
 
       if (init)
-	this_capture = add_default_capture (lambda_stack,
-					    /*id=*/this_identifier,
-					    init);
+        {
+          if (add_capture_p)
+	    this_capture = add_default_capture (lambda_stack,
+					        /*id=*/this_identifier,
+					        init);
+          else
+	    this_capture = init;
+        }
     }
 
   if (!this_capture)
@@ -742,7 +749,7 @@ lambda_expr_this_capture (tree lambda)
    'this' capture.  */
 
 tree
-maybe_resolve_dummy (tree object)
+maybe_resolve_dummy (tree object, bool add_capture_p)
 {
   if (!is_dummy_object (object))
     return object;
@@ -758,7 +765,7 @@ maybe_resolve_dummy (tree object)
     {
       /* In a lambda, need to go through 'this' capture.  */
       tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
-      tree cap = lambda_expr_this_capture (lam);
+      tree cap = lambda_expr_this_capture (lam, add_capture_p);
       object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
 				     RO_NULL, tf_warning_or_error);
     }
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4afb821..d925f5c 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1675,7 +1675,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
       object = maybe_dummy_object (scope, NULL);
     }
 
-  object = maybe_resolve_dummy (object);
+  object = maybe_resolve_dummy (object, true);
   if (object == error_mark_node)
     return error_mark_node;
 
@@ -2434,7 +2434,7 @@ finish_this_expr (void)
 
       /* In a lambda expression, 'this' refers to the captured 'this'.  */
       if (LAMBDA_TYPE_P (type))
-        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type));
+        result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type), true);
       else
         result = current_class_ptr;
     }
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C
new file mode 100644
index 0000000..2de00d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-const-this.C
@@ -0,0 +1,9 @@
+// PR c++/60463
+// PR c++/60755
+// { dg-do compile { target c++11 } }
+struct S {
+  void f(); // { dg-message "no known conversion for implicit 'this' parameter from 'const S\\*' to 'S\\*'" }
+  void g() const {
+    [=] { f(); } (); // { dg-error "no matching function for call to 'S::f\\(\\)'" }
+  }
+};



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix PR c++/60463, PR c++/60755 Incorrect discard of const qualifier
  2014-05-09  8:27   ` Momchil Velikov
@ 2014-05-09 20:07     ` Jason Merrill
  0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2014-05-09 20:07 UTC (permalink / raw)
  To: Momchil Velikov, gcc-patches

Thanks for the patch, and for pinging me directly.

It looks like you don't have a copyright assignment on file; this and 
your other patch are small enough not to need one, but if you're going 
to continue working on GCC it would be good to get on file so that it 
doesn't hold up future patches.  See http://gcc.gnu.org/contribute.html 
for more information.

I'm going to apply this patch to trunk.

Jason

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-05-09 20:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-14 20:53 [PATCH] Fix PR c++/60463, PE c++/60755 Incorrect discard of const qualifier Momchil Velikov
2014-05-01  9:10 ` [PATCH] Fix PR c++/60463, PR " Momchil Velikov
2014-05-09  8:27   ` Momchil Velikov
2014-05-09 20:07     ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).