commit 1e940d8c7b567f7e0994ca99fe34b51309705d7f
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Oct 13 15:27:31 2011 -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.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index b53accf..e42cda1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index bfbd244..880f3d1 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index eed38e6..7d37fa3 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
 
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
index 0000000..b5ba066
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-auto1.C
@@ -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>();
+}
