re PR c++/54277 (Template class member referred to with implicit this inside lambda...
authorJason Merrill <jason@redhat.com>
Sun, 17 Mar 2013 02:41:22 +0000 (22:41 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 17 Mar 2013 02:41:22 +0000 (22:41 -0400)
PR c++/54277
* cp-tree.h (WILDCARD_TYPE_P): Split out from...
(MAYBE_CLASS_TYPE_P): ...here.
* semantics.c (lambda_capture_field_type): Only build a
magic decltype for wildcard types.
(lambda_proxy_type): Likewise.
(finish_non_static_data_member): Get the quals from
the object.

From-SVN: r196747

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

index f6f15219541bc4b93fafcc1b8851d4e4884f1a07..ec7cd0f55e18d6ed43cf3690e2fcc0062f939d3b 100644 (file)
@@ -1,5 +1,14 @@
 2013-03-16  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54277
+       * cp-tree.h (WILDCARD_TYPE_P): Split out from...
+       (MAYBE_CLASS_TYPE_P): ...here.
+       * semantics.c (lambda_capture_field_type): Only build a
+       magic decltype for wildcard types.
+       (lambda_proxy_type): Likewise.
+       (finish_non_static_data_member): Get the quals from
+       the object.
+
        PR c++/55931
        * parser.c (cp_parser_template_argument): Don't
        fold_non_dependent_expr.
index 39fb3dfeba4c2c7662db4cbd49d25497cf2f406f..7ce1acb06d70f85ecaeb137951e049c9a4d736d4 100644 (file)
@@ -1220,17 +1220,20 @@ enum languages { lang_c, lang_cplusplus, lang_java };
 /* The _DECL for this _TYPE.  */
 #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
 
-/* Nonzero if T is a class (or struct or union) type.  Also nonzero
-   for template type parameters, typename types, and instantiated
-   template template parameters.  Keep these checks in ascending code
-   order.  */
-#define MAYBE_CLASS_TYPE_P(T)                                  \
+/* Nonzero if T is a type that could resolve to any kind of concrete type
+   at instantiation time.  */
+#define WILDCARD_TYPE_P(T)                             \
   (TREE_CODE (T) == TEMPLATE_TYPE_PARM                 \
    || TREE_CODE (T) == TYPENAME_TYPE                   \
    || TREE_CODE (T) == TYPEOF_TYPE                     \
    || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM    \
-   || TREE_CODE (T) == DECLTYPE_TYPE                   \
-   || CLASS_TYPE_P (T))
+   || TREE_CODE (T) == DECLTYPE_TYPE)
+
+/* Nonzero if T is a class (or struct or union) type.  Also nonzero
+   for template type parameters, typename types, and instantiated
+   template template parameters.  Keep these checks in ascending code
+   order.  */
+#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T))
 
 /* Set CLASS_TYPE_P for T to VAL.  T must be a class, struct, or
    union type.  */
index 9a2b7285dc91de8352cd91c4a414ba7672a7f386..5143e4bd5822b0985e1fac3087a32985f2cc8c29 100644 (file)
@@ -1574,9 +1574,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
       else
        {
          /* Set the cv qualifiers.  */
-         int quals = (current_class_ref
-                      ? cp_type_quals (TREE_TYPE (current_class_ref))
-                      : TYPE_UNQUALIFIED);
+         int quals = cp_type_quals (TREE_TYPE (object));
 
          if (DECL_MUTABLE_P (decl))
            quals &= ~TYPE_QUAL_CONST;
@@ -9056,7 +9054,7 @@ tree
 lambda_capture_field_type (tree expr)
 {
   tree type;
-  if (type_dependent_expression_p (expr))
+  if (!TREE_TYPE (expr) || WILDCARD_TYPE_P (TREE_TYPE (expr)))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
@@ -9265,7 +9263,7 @@ lambda_proxy_type (tree ref)
   if (REFERENCE_REF_P (ref))
     ref = TREE_OPERAND (ref, 0);
   type = TREE_TYPE (ref);
-  if (!dependent_type_p (type))
+  if (type && !WILDCARD_TYPE_P (type))
     return type;
   type = cxx_make_type (DECLTYPE_TYPE);
   DECLTYPE_TYPE_EXPR (type) = ref;
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this9.C
new file mode 100644 (file)
index 0000000..07ddd08
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/54277
+// { dg-do compile { target c++11 } }
+
+struct Used
+{
+  void foo() { }
+};
+
+template <typename>
+struct S
+{
+  Used x;
+
+  void bar()
+  {
+    auto f = [this] { x.foo(); };
+    f();
+  }
+};