re PR c++/53619 ([C++11] wrong capture of "this" in lambda in case of multiple inheri...
authorJason Merrill <jason@redhat.com>
Tue, 3 Jul 2012 05:03:34 +0000 (01:03 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 3 Jul 2012 05:03:34 +0000 (01:03 -0400)
PR c++/53619
* pt.c (in_template_function): New.
* cp-tree.h: Declare it.
* class.c (build_base_path, resolves_to_fixed_type_p): Use it.

From-SVN: r189191

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C [new file with mode: 0644]

index 580f8cda3abbd7683f3cb16cc452cb3745a63289..2c524230fe43260f6f8a6a7602628ce65601c97a 100644 (file)
@@ -1,5 +1,10 @@
 2012-07-02  Jason Merrill  <jason@redhat.com>
 
+       PR c++/53619
+       * pt.c (in_template_function): New.
+       * cp-tree.h: Declare it.
+       * class.c (build_base_path, resolves_to_fixed_type_p): Use it.
+
        PR c++/53783
        * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Use tsubst
        for LAMBDA_EXPR_EXTRA_SCOPE.
index e70e6747b55b40ceb42a71072f9856bdea747289..0d4a40d4dbecd2e3167e6dcd155a341c7ab9ab75 100644 (file)
@@ -325,8 +325,7 @@ build_base_path (enum tree_code code,
      up properly yet, and the value doesn't matter there either; we're just
      interested in the result of overload resolution.  */
   if (cp_unevaluated_operand != 0
-      || (current_function_decl
-         && uses_template_parms (current_function_decl)))
+      || in_template_function ())
     {
       expr = build_nop (ptr_target_type, expr);
       if (!want_pointer)
@@ -6523,8 +6522,7 @@ resolves_to_fixed_type_p (tree instance, int* nonnull)
 
   /* processing_template_decl can be false in a template if we're in
      fold_non_dependent_expr, but we still want to suppress this check.  */
-  if (current_function_decl
-      && uses_template_parms (current_function_decl))
+  if (in_template_function ())
     {
       /* In a template we only care about the type of the result.  */
       if (nonnull)
index a4b7ae3716df38e3a8bf6aa748a39e7e1dc61a15..41ca83ca8c9bee4e4d20717dca3dbc2e0d70c592 100644 (file)
@@ -5330,6 +5330,7 @@ extern tree lookup_template_class         (tree, tree, tree, tree,
 extern tree lookup_template_function           (tree, tree);
 extern int uses_template_parms                 (tree);
 extern int uses_template_parms_level           (tree, int);
+extern bool in_template_function               (void);
 extern tree instantiate_class_template         (tree);
 extern tree instantiate_template               (tree, tree, tsubst_flags_t);
 extern int fn_type_unification                 (tree, tree, tree,
index d385ea7ee76c113d146c096fc8847607bd5f432b..f618fa557d10212a24a55d96946a67f0288b73a7 100644 (file)
@@ -8027,6 +8027,23 @@ uses_template_parms (tree t)
   return dependent_p;
 }
 
+/* Returns true iff current_function_decl is an incompletely instantiated
+   template.  Useful instead of processing_template_decl because the latter
+   is set to 0 during fold_non_dependent_expr.  */
+
+bool
+in_template_function (void)
+{
+  tree fn = current_function_decl;
+  bool ret;
+  ++processing_template_decl;
+  ret = (fn && DECL_LANG_SPECIFIC (fn)
+        && DECL_TEMPLATE_INFO (fn)
+        && any_dependent_template_arguments_p (DECL_TI_ARGS (fn)));
+  --processing_template_decl;
+  return ret;
+}
+
 /* Returns true if T depends on any template parameter with level LEVEL.  */
 
 int
index cb62b113a1aec3f22de96e8e450ca5fa74235329..7ce574a64f5552be7585a5c150de7e443a56452c 100644 (file)
@@ -1,5 +1,8 @@
 2012-07-02  Jason Merrill  <jason@redhat.com>
 
+       PR c++/53619
+       * g++.dg/cpp0x/lambda/lambda-this5.C: New.
+
        PR c++/53783
        * g++.dg/cpp0x/lambda/lambda-template7.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this5.C
new file mode 100644 (file)
index 0000000..8974641
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/53619
+// { dg-do run { target c++11 } }
+
+struct C {
+  int x;
+};
+struct B {
+  int q;
+};
+struct A : public B , C  {
+  void foo();
+};
+
+void A::foo() {
+  auto k = [this]() {return (void *)(&x);};
+  if (k() != (void*)&x)
+    __builtin_abort();
+}
+
+int main(int l, char **) {
+  A a; a.foo();
+}