]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/50437 ([C++0x] [4.7 regression] ICE for trivial use of lambda in template...
authorJason Merrill <jason@redhat.com>
Thu, 13 Oct 2011 21:23:36 +0000 (17:23 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 13 Oct 2011 21:23:36 +0000 (17:23 -0400)
PR c++/50437
* cp-tree.h (struct tree_lambda_expr): Add closure field.
(LAMBDA_EXPR_CLOSURE): New.
* pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Likewise.
* semantics.c (build_lambda_object): Use it instead of TREE_TYPE.
(begin_lambda_type, lambda_function, add_capture): Likewise.
(add_default_capture, lambda_expr_this_capture): Likewise.

From-SVN: r179944

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

index 039b155810f2262b3dc40f9fd733f65d9d1330f3..0322103c94126b64617b1add5e1ee1933e2ad328 100644 (file)
@@ -1,3 +1,13 @@
+2011-10-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/50437
+       * cp-tree.h (struct tree_lambda_expr): Add closure field.
+       (LAMBDA_EXPR_CLOSURE): New.
+       * pt.c (tsubst_copy_and_build) [LAMBDA_EXPR]: Likewise.
+       * semantics.c (build_lambda_object): Use it instead of TREE_TYPE.
+       (begin_lambda_type, lambda_function, add_capture): Likewise.
+       (add_default_capture, lambda_expr_this_capture): Likewise.
+
 2011-10-13   Diego Novillo  <dnovillo@google.com>
 
        * cp-tree.h (struct language_function): Rename in_function_try_handler
index 1b896b819870e7c771c1058feadc8d49c29fcafd..bae6071ebcb701cd6cf22ee739c320875d497108 100644 (file)
@@ -671,6 +671,12 @@ enum cp_lambda_default_capture_mode_type {
 #define LAMBDA_EXPR_PENDING_PROXIES(NODE) \
   (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->pending_proxies)
 
+/* The closure type of the lambda.  Note that the TREE_TYPE of a
+   LAMBDA_EXPR is always NULL_TREE, because we need to instantiate the
+   LAMBDA_EXPR in order to instantiate the type.  */
+#define LAMBDA_EXPR_CLOSURE(NODE) \
+  (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->closure)
+
 struct GTY (()) tree_lambda_expr
 {
   struct tree_typed typed;
@@ -678,6 +684,7 @@ struct GTY (()) tree_lambda_expr
   tree this_capture;
   tree return_type;
   tree extra_scope;
+  tree closure;
   VEC(tree,gc)* pending_proxies;
   location_t locus;
   enum cp_lambda_default_capture_mode_type default_capture_mode;
index bfbd24443254b455515be6810b9cfc0d4e05b99b..880f3d1510d51bf483f3b97b6dab75a58fff7b5c 100644 (file)
@@ -13937,8 +13937,8 @@ tsubst_copy_and_build (tree t,
       {
        tree r = build_lambda_expr ();
 
-       tree type = tsubst (TREE_TYPE (t), args, complain, NULL_TREE);
-       TREE_TYPE (r) = type;
+       tree type = tsubst (LAMBDA_EXPR_CLOSURE (t), args, complain, NULL_TREE);
+       LAMBDA_EXPR_CLOSURE (r) = type;
        CLASSTYPE_LAMBDA_EXPR (type) = r;
 
        LAMBDA_EXPR_LOCATION (r)
index eed38e62f7b88f5a82d8d4ee2bea72ab98e83676..7d37fa3e2c10b8364ce95b1e199cc427f8543fc5 100644 (file)
@@ -8324,7 +8324,7 @@ build_lambda_object (tree lambda_expr)
 
   /* N2927: "[The closure] class type is not an aggregate."
      But we briefly treat it as an aggregate to make this simpler.  */
-  type = TREE_TYPE (lambda_expr);
+  type = LAMBDA_EXPR_CLOSURE (lambda_expr);
   CLASSTYPE_NON_AGGREGATE (type) = 0;
   expr = finish_compound_literal (type, expr, tf_warning_or_error);
   CLASSTYPE_NON_AGGREGATE (type) = 1;
@@ -8365,7 +8365,7 @@ begin_lambda_type (tree lambda)
   type = begin_class_definition (type, /*attributes=*/NULL_TREE);
 
   /* Cross-reference the expression and the type.  */
-  TREE_TYPE (lambda) = type;
+  LAMBDA_EXPR_CLOSURE (lambda) = type;
   CLASSTYPE_LAMBDA_EXPR (type) = lambda;
 
   return type;
@@ -8399,7 +8399,7 @@ lambda_function (tree lambda)
 {
   tree type;
   if (TREE_CODE (lambda) == LAMBDA_EXPR)
-    type = TREE_TYPE (lambda);
+    type = LAMBDA_EXPR_CLOSURE (lambda);
   else
     type = lambda;
   gcc_assert (LAMBDA_TYPE_P (type));
@@ -8714,7 +8714,7 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
 
   /* If TREE_TYPE isn't set, we're still in the introducer, so check
      for duplicates.  */
-  if (!TREE_TYPE (lambda))
+  if (!LAMBDA_EXPR_CLOSURE (lambda))
     {
       if (IDENTIFIER_MARKED (name))
        {
@@ -8740,13 +8740,14 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
     LAMBDA_EXPR_THIS_CAPTURE (lambda) = member;
 
   /* Add it to the appropriate closure class if we've started it.  */
-  if (current_class_type && current_class_type == TREE_TYPE (lambda))
+  if (current_class_type
+      && current_class_type == LAMBDA_EXPR_CLOSURE (lambda))
     finish_member_declaration (member);
 
   LAMBDA_EXPR_CAPTURE_LIST (lambda)
     = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
 
-  if (TREE_TYPE (lambda))
+  if (LAMBDA_EXPR_CLOSURE (lambda))
     return build_capture_proxy (member);
   /* For explicit captures we haven't started the function yet, so we wait
      and build the proxy from cp_parser_lambda_body.  */
@@ -8789,7 +8790,7 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
     {
       tree lambda = TREE_VALUE (node);
 
-      current_class_type = TREE_TYPE (lambda);
+      current_class_type = LAMBDA_EXPR_CLOSURE (lambda);
       var = add_capture (lambda,
                             id,
                             initializer,
@@ -8820,7 +8821,7 @@ lambda_expr_this_capture (tree lambda)
   if (!this_capture
       && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) != CPLD_NONE)
     {
-      tree containing_function = TYPE_CONTEXT (TREE_TYPE (lambda));
+      tree containing_function = TYPE_CONTEXT (LAMBDA_EXPR_CLOSURE (lambda));
       tree lambda_stack = tree_cons (NULL_TREE, lambda, NULL_TREE);
       tree init = NULL_TREE;
 
@@ -8870,7 +8871,8 @@ lambda_expr_this_capture (tree lambda)
   else
     {
       /* To make sure that current_class_ref is for the lambda.  */
-      gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
+      gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref))
+                 == LAMBDA_EXPR_CLOSURE (lambda));
 
       result = this_capture;
 
index 283b699a36d1841fb5eaf3c5506ae05e1d6bc4e2..3c15036747cc8f90bbf2ea1c94c963e36e13f5f3 100644 (file)
@@ -1,5 +1,8 @@
 2011-10-13  Jason Merrill  <jason@redhat.com>
 
+       PR c++/50437
+       * g++.dg/cpp0x/lambda/lambda-auto1.C: New.
+
        PR c++/50618
        * g++.dg/init/vbase1.C: New.
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C
new file mode 100644 (file)
index 0000000..b5ba066
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/50437
+// { dg-options -std=c++0x }
+
+template <typename T>
+void f()
+{
+    auto g = [](T t){ return t == 0; };
+    g(T());
+}
+
+int main()
+{
+    f<int>();
+}