I've backported the attached patches gcc-6.

        Marek
Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-03-14  Marek Polacek  <pola...@redhat.com>

        PR c++/79962
        PR c++/79984
        * c-common.c (handle_nonnull_attribute): Save the result of default
        conversion to the attribute list.

        * c-c++-common/nonnull-3.c: New test.
        * g++.dg/warn/Wnonnull3.C: New test.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index d2e3ad4..5f17984 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -9061,7 +9061,7 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED 
(name),
       tree arg = TREE_VALUE (args);
       if (arg && TREE_CODE (arg) != IDENTIFIER_NODE
          && TREE_CODE (arg) != FUNCTION_DECL)
-       arg = default_conversion (arg);
+       TREE_VALUE (args) = arg = default_conversion (arg);
 
       if (!get_nonnull_operand (arg, &arg_num))
        {
diff --git gcc/testsuite/c-c++-common/nonnull-3.c 
gcc/testsuite/c-c++-common/nonnull-3.c
index e69de29..d2ccb24 100644
--- gcc/testsuite/c-c++-common/nonnull-3.c
+++ gcc/testsuite/c-c++-common/nonnull-3.c
@@ -0,0 +1,11 @@
+/* PR c++/79984 */
+/* { dg-do compile } */
+/* { dg-options "-Wnonnull-compare" } */
+
+enum { r = 1 };
+
+__attribute__ ((nonnull (r))) int
+f (int *p)
+{
+  return p == 0; /* { dg-warning "nonnull argument 'p' compared to NULL" } */
+}
diff --git gcc/testsuite/g++.dg/warn/Wnonnull3.C 
gcc/testsuite/g++.dg/warn/Wnonnull3.C
index e69de29..d1918ef 100644
--- gcc/testsuite/g++.dg/warn/Wnonnull3.C
+++ gcc/testsuite/g++.dg/warn/Wnonnull3.C
@@ -0,0 +1,15 @@
+// PR c++/79962
+// { dg-options "-Wnonnull" }
+
+template <class T>
+__attribute__ ((__nonnull__ (T::i))) void f (typename T::U) { }
+
+struct S1 { enum { i = 1 }; typedef void* U; };
+struct S2 { static const int i = 1; typedef void* U; };
+
+void
+g ()
+{
+  f<S1>(0); // { dg-warning "null argument where non-null required" }
+  f<S2>(0); // { dg-warning "null argument where non-null required" }
+}
We crash on an assert in strip_typedefs, because we find ourselves in a
scenario where RESULT, the main variant of a struct, was modified in
finalize_record_size (its TYPE_ALIGN changed), but its variants (T in
strip_typedefs) weren't fixed-up yet; that will happen slightly later in
finalize_type_size.  So there's a discrepancy that confuses the code.

This patch implements what Jason suggested to me on IRC, i.e., skip the
attribute handling if RESULT is complete and T isn't.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-03-09  Marek Polacek  <pola...@redhat.com>

        PR c++/79900 - ICE in strip_typedefs
        * tree.c (strip_typedefs): Skip the attribute handling if T is
        a variant type which hasn't been updated yet.

        * g++.dg/warn/Wpadded-1.C: New test.

diff --git gcc/cp/tree.c gcc/cp/tree.c
index d3c63b8..b3a4a10 100644
--- gcc/cp/tree.c
+++ gcc/cp/tree.c
@@ -1548,29 +1548,40 @@ strip_typedefs (tree t, bool *remove_attributes)
        result = TYPE_MAIN_VARIANT (t);
     }
   gcc_assert (!typedef_variant_p (result));
-  if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
-      || TYPE_ALIGN (t) != TYPE_ALIGN (result))
+
+  if (COMPLETE_TYPE_P (result) && !COMPLETE_TYPE_P (t))
+  /* If RESULT is complete and T isn't, it's likely the case that T
+     is a variant of RESULT which hasn't been updated yet.  Skip the
+     attribute handling.  */;
+  else
     {
-      gcc_assert (TYPE_USER_ALIGN (t));
-      if (remove_attributes)
-       *remove_attributes = true;
-      else
+      if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
+         || TYPE_ALIGN (t) != TYPE_ALIGN (result))
        {
-         if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
-           result = build_variant_type_copy (result);
+         gcc_assert (TYPE_USER_ALIGN (t));
+         if (remove_attributes)
+           *remove_attributes = true;
          else
-           result = build_aligned_type (result, TYPE_ALIGN (t));
-         TYPE_USER_ALIGN (result) = true;
+           {
+             if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
+               result = build_variant_type_copy (result);
+             else
+               result = build_aligned_type (result, TYPE_ALIGN (t));
+             TYPE_USER_ALIGN (result) = true;
+           }
+       }
+
+      if (TYPE_ATTRIBUTES (t))
+       {
+         if (remove_attributes)
+           result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
+                                               remove_attributes);
+         else
+           result = cp_build_type_attribute_variant (result,
+                                                     TYPE_ATTRIBUTES (t));
        }
     }
-  if (TYPE_ATTRIBUTES (t))
-    {
-      if (remove_attributes)
-       result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
-                                           remove_attributes);
-      else
-       result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t));
-    }
+
   return cp_build_qualified_type (result, cp_type_quals (t));
 }
 
diff --git gcc/testsuite/g++.dg/warn/Wpadded-1.C 
gcc/testsuite/g++.dg/warn/Wpadded-1.C
index e69de29..b3f0581 100644
--- gcc/testsuite/g++.dg/warn/Wpadded-1.C
+++ gcc/testsuite/g++.dg/warn/Wpadded-1.C
@@ -0,0 +1,22 @@
+// PR c++/79900 - ICE in strip_typedefs
+// { dg-do compile }
+// { dg-options "-Wpadded" }
+
+template <class> struct A;
+template <typename> struct B { // { dg-warning "padding struct size to 
alignment boundary" }
+  long _M_off;
+  int _M_state;
+};
+template <> struct A<char> { typedef B<int> pos_type; };
+enum _Ios_Openmode {};
+struct C {
+  typedef _Ios_Openmode openmode;
+};
+template <typename, typename _Traits> struct D {
+  typedef typename _Traits::pos_type pos_type;
+  pos_type m_fn1(pos_type, C::openmode);
+};
+template class D<char, A<char> >;
+template <typename _CharT, typename _Traits>
+typename D<_CharT, _Traits>::pos_type D<_CharT, _Traits>::m_fn1(pos_type x,
+                                                                C::openmode) { 
return x; }
Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-03-09  Marek Polacek  <pola...@redhat.com>

        PR c++/79687
        * init.c (constant_value_1): Break if the variable has a dynamic
        initializer.

        * g++.dg/expr/ptrmem8.C: New test.
        * g++.dg/expr/ptrmem9.C: New test.

diff --git gcc/cp/init.c gcc/cp/init.c
index 7ded37e..12e6bf4 100644
--- gcc/cp/init.c
+++ gcc/cp/init.c
@@ -2193,6 +2193,13 @@ constant_value_1 (tree decl, bool strict_p, bool 
return_aggregate_cst_ok_p)
       if (TREE_CODE (init) == CONSTRUCTOR
          && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
        break;
+      /* If the variable has a dynamic initializer, don't use its
+        DECL_INITIAL which doesn't reflect the real value.  */
+      if (VAR_P (decl)
+         && TREE_STATIC (decl)
+         && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
+         && DECL_NONTRIVIALLY_INITIALIZED_P (decl))
+       break;
       decl = unshare_expr (init);
     }
   return decl;
diff --git gcc/testsuite/g++.dg/expr/ptrmem8.C 
gcc/testsuite/g++.dg/expr/ptrmem8.C
index e69de29..c5a766a 100644
--- gcc/testsuite/g++.dg/expr/ptrmem8.C
+++ gcc/testsuite/g++.dg/expr/ptrmem8.C
@@ -0,0 +1,15 @@
+// PR c++/79687
+// { dg-do run }
+
+struct A
+{
+  char c;
+};
+
+int main()
+{
+  char A::* p = &A::c;
+  static char A::* const q = p;
+  A a;
+  return &(a.*q) - &a.c;
+}
diff --git gcc/testsuite/g++.dg/expr/ptrmem9.C 
gcc/testsuite/g++.dg/expr/ptrmem9.C
index e69de29..32ce777 100644
--- gcc/testsuite/g++.dg/expr/ptrmem9.C
+++ gcc/testsuite/g++.dg/expr/ptrmem9.C
@@ -0,0 +1,19 @@
+// PR c++/79687
+// { dg-do run }
+
+struct A
+{
+  char c;
+};
+
+int main()
+{
+  static char A::* p1 = &A::c;
+  char A::* const q1 = p1;
+
+  char A::* p2 = &A::c;
+  static char A::* const q2 = p2;
+
+  A a;
+  return (&(a.*q1) - &a.c) || (&(a.*q2) - &a.c);
+}
2017-01-17  Nathan Sidwell  <nat...@acm.org>

        PR c++/61636
        * cp-tree.h (maybe_generic_this_capture): Declare.
        * lambda.c (resolvable_dummy_lambda): New, broken out of ...
        (maybe_resolve_dummy): ... here.  Call it.
        (maybe_generic_this_capture): New.
        * parser.c (cp_parser_postfix_expression): Speculatively capture
        this in generic lambda in unresolved member function call.
        * pt.c (tsubst_copy_and_build): Force hard error from failed
        member function lookup in generic lambda.

        * g++.dg/cpp1y/pr61636-1.C: New.
        * g++.dg/cpp1y/pr61636-2.C: New.
        * g++.dg/cpp1y/pr61636-3.C: New.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 24de346..0c8f147 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6551,6 +6551,7 @@ 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, bool);
+extern void maybe_generic_this_capture         (tree, tree);
 extern tree maybe_resolve_dummy                        (tree, bool);
 extern tree current_nonlambda_function         (void);
 extern tree nonlambda_method_basetype          (void);
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 98fdb74..4d22c3d 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -793,16 +793,14 @@ lambda_expr_this_capture (tree lambda, bool add_capture_p)
   return result;
 }
 
-/* We don't want to capture 'this' until we know we need it, i.e. after
-   overload resolution has chosen a non-static member function.  At that
-   point we call this function to turn a dummy object into a use of the
-   'this' capture.  */
+/* Return the current LAMBDA_EXPR, if this is a resolvable dummy
+   object.  NULL otherwise..  */
 
-tree
-maybe_resolve_dummy (tree object, bool add_capture_p)
+static tree
+resolvable_dummy_lambda (tree object)
 {
   if (!is_dummy_object (object))
-    return object;
+    return NULL_TREE;
 
   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (object));
   gcc_assert (!TYPE_PTR_P (type));
@@ -812,18 +810,55 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
       && LAMBDA_TYPE_P (current_class_type)
       && lambda_function (current_class_type)
       && DERIVED_FROM_P (type, current_nonlambda_class_type ()))
-    {
-      /* In a lambda, need to go through 'this' capture.  */
-      tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
-      tree cap = lambda_expr_this_capture (lam, add_capture_p);
-      if (cap && cap != error_mark_node)
+    return CLASSTYPE_LAMBDA_EXPR (current_class_type);
+
+  return NULL_TREE;
+}
+
+/* We don't want to capture 'this' until we know we need it, i.e. after
+   overload resolution has chosen a non-static member function.  At that
+   point we call this function to turn a dummy object into a use of the
+   'this' capture.  */
+
+tree
+maybe_resolve_dummy (tree object, bool add_capture_p)
+{
+  if (tree lam = resolvable_dummy_lambda (object))
+    if (tree cap = lambda_expr_this_capture (lam, add_capture_p))
+      if (cap != error_mark_node)
        object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
                                       RO_NULL, tf_warning_or_error);
-    }
 
   return object;
 }
 
+/* When parsing a generic lambda containing an argument-dependent
+   member function call we defer overload resolution to instantiation
+   time.  But we have to know now whether to capture this or not.
+   Do that if FNS contains any non-static fns.
+   The std doesn't anticipate this case, but I expect this to be the
+   outcome of discussion.  */
+
+void
+maybe_generic_this_capture (tree object, tree fns)
+{
+  if (tree lam = resolvable_dummy_lambda (object))
+    if (!LAMBDA_EXPR_THIS_CAPTURE (lam))
+      {
+       /* We've not yet captured, so look at the function set of
+          interest.  */
+       if (BASELINK_P (fns))
+         fns = BASELINK_FUNCTIONS (fns);
+       for (; fns; fns = OVL_NEXT (fns))
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (OVL_CURRENT (fns)))
+           {
+             /* Found a non-static member.  Capture this.  */
+             lambda_expr_this_capture (lam, true);
+             break;
+           }
+      }
+}
+
 /* Returns the innermost non-lambda function.  */
 
 tree
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 295c450..6d3b877 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6971,6 +6971,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
                        || type_dependent_expression_p (fn)
                        || any_type_dependent_arguments_p (args)))
                  {
+                   maybe_generic_this_capture (instance, fn);
                    postfix_expression
                      = build_nt_call_vec (postfix_expression, args);
                    release_tree_vector (args);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dec7d39..022ffda 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17142,19 +17142,34 @@ tsubst_copy_and_build (tree t,
 
                if (unq != function)
                  {
-                   tree fn = unq;
-                   if (INDIRECT_REF_P (fn))
-                     fn = TREE_OPERAND (fn, 0);
-                   if (TREE_CODE (fn) == COMPONENT_REF)
-                     fn = TREE_OPERAND (fn, 1);
-                   if (is_overloaded_fn (fn))
-                     fn = get_first_fn (fn);
-                   if (permerror (EXPR_LOC_OR_LOC (t, input_location),
-                                  "%qD was not declared in this scope, "
-                                  "and no declarations were found by "
-                                  "argument-dependent lookup at the point "
-                                  "of instantiation", function))
+                   /* In a lambda fn, we have to be careful to not
+                      introduce new this captures.  Legacy code can't
+                      be using lambdas anyway, so it's ok to be
+                      stricter.  */
+                   bool in_lambda = (current_class_type
+                                     && LAMBDA_TYPE_P (current_class_type));
+                   char const *msg = "%qD was not declared in this scope, "
+                     "and no declarations were found by "
+                     "argument-dependent lookup at the point "
+                     "of instantiation";
+
+                   bool diag = true;
+                   if (in_lambda)
+                     error_at (EXPR_LOC_OR_LOC (t, input_location),
+                               msg, function);
+                   else
+                     diag = permerror (EXPR_LOC_OR_LOC (t, input_location),
+                                       msg, function);
+                   if (diag)
                      {
+                       tree fn = unq;
+                       if (INDIRECT_REF_P (fn))
+                         fn = TREE_OPERAND (fn, 0);
+                       if (TREE_CODE (fn) == COMPONENT_REF)
+                         fn = TREE_OPERAND (fn, 1);
+                       if (is_overloaded_fn (fn))
+                         fn = get_first_fn (fn);
+
                        if (!DECL_P (fn))
                          /* Can't say anything more.  */;
                        else if (DECL_CLASS_SCOPE_P (fn))
@@ -17177,7 +17192,13 @@ tsubst_copy_and_build (tree t,
                          inform (DECL_SOURCE_LOCATION (fn),
                                  "%qD declared here, later in the "
                                  "translation unit", fn);
+                       if (in_lambda)
+                         {
+                           release_tree_vector (call_args);
+                           RETURN (error_mark_node);
+                         }
                      }
+
                    function = unq;
                  }
              }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C 
b/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C
new file mode 100644
index 0000000..9426d5f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C
@@ -0,0 +1,31 @@
+// PR c++/61636
+// { dg-do compile { target c++14 } }
+
+// ICE because we figure this capture too late.
+
+struct Base
+{
+  void Bar (int);
+};
+
+struct A : Base {
+  void b ();
+  void Foo (int);
+  using Base::Bar;
+  template <typename T> void Baz (T);
+};
+
+void A::b() {
+
+  auto lam = [&](auto asdf) { Foo (asdf); };
+
+  lam (0);
+
+  auto lam1 = [&](auto asdf) { Bar (asdf); };
+
+  lam1 (0);
+
+  auto lam2 = [&](auto asdf) { Baz (asdf); };
+
+  lam2 (0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr61636-2.C 
b/gcc/testsuite/g++.dg/cpp1y/pr61636-2.C
new file mode 100644
index 0000000..a1bd597
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr61636-2.C
@@ -0,0 +1,72 @@
+// PR c++/61636
+// { dg-do run { target c++14 } }
+
+// Check we don't capture this (too) unnecessarily
+
+struct A {
+  int b ();
+  void f (int) {}
+  static void f (double) {}
+
+  static void g (int) {}
+  static void g (double) {}
+};
+
+struct O {
+  void x (int) {}
+  static void x (double) {}
+};
+
+namespace N {
+  void y (double) {}
+}
+
+int Check (bool expect, unsigned size)
+{
+  return (expect ? sizeof (void *) : 1) != size;
+}
+
+int A::b() {
+  int r = 0;
+
+  // one of the functions is non-static
+  auto l0 = [&](auto z) { f (z); };
+  r += Check (true, sizeof l0);
+  l0(0.0); // doesn't need this capture for A::f(double), but too late
+  l0 (0); // Needs this capture for A::f(int)
+
+  // no fn is non-static.
+  auto l00 = [&](auto z) { g (z); };
+  r += Check (false, sizeof l00);
+  l00(0.0); 
+  l00 (0);
+
+  // sizeof isn't an evaluation context, so no this capture
+  auto l1 = [&](auto z) { sizeof (f (z), 1); };
+  r += Check (false, sizeof l1);
+  l1(0.0); l1 (0); 
+
+  auto l2 = [&](auto) { f (2.4); };
+  auto l3 = [&](auto) { f (0); };
+  l2(0); l3(0); l2(0.0); l3 (0.0);
+  r += Check (false, sizeof l2);
+  r += Check (true, sizeof l3);
+
+  auto l4 = [&](auto) { O::x (2.4); };
+  auto l5 = [&](auto) { N::y (2.4); };
+  auto l6 = [&](auto) { };
+  l4(0); l5(0); l6(0);
+  l4(0.0); l5(0.0); l6(0.0);
+  r += Check (false, sizeof l4);
+  r += Check (false, sizeof l5);
+  r += Check (false, sizeof l6);
+
+  return r;
+}
+
+int main ()
+{
+  A a;
+
+  return a.b () ? 1 : 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr61636-3.C 
b/gcc/testsuite/g++.dg/cpp1y/pr61636-3.C
new file mode 100644
index 0000000..18f83fe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr61636-3.C
@@ -0,0 +1,25 @@
+// PR c++/61636
+// { dg-do compile { target c++14 } }
+// permissiveness doesn't make this permitted
+// { dg-additional-options "-fpermissive" }
+
+// ICE because we attempt to use dependent Foo during error recovery
+// and die with an unexpected this capture need.
+
+template <typename T> struct Base
+{
+  void Foo (int);
+};
+
+template <typename T> struct A : Base<T> {
+  void b ();
+};
+
+template <typename T> void A<T>::b() {
+
+  auto lam = [&](auto asdf) { Foo (asdf); }; // { dg-error "not declared" }
+
+  lam (T(0));
+}
+
+template void A<int>::b ();
2017-01-31  Nathan Sidwell  <nat...@acm.org>

        PR c++/79264
        * lambda.c (maybe_generic_this_capture): Deal with template-id-exprs.
        * semantics.c (finish_member_declaration): Assert class is being
        defined.

        * g++.dg/cpp1y/pr61636-1.C: Augment.

diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 538c806..46ab30f 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -849,13 +849,21 @@ maybe_generic_this_capture (tree object, tree fns)
           interest.  */
        if (BASELINK_P (fns))
          fns = BASELINK_FUNCTIONS (fns);
+       bool id_expr = TREE_CODE (fns) == TEMPLATE_ID_EXPR;
+       if (id_expr)
+         fns = TREE_OPERAND (fns, 0);
        for (; fns; fns = OVL_NEXT (fns))
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (OVL_CURRENT (fns)))
-           {
-             /* Found a non-static member.  Capture this.  */
-             lambda_expr_this_capture (lam, true);
-             break;
-           }
+         {
+           tree fn = OVL_CURRENT (fns);
+
+           if ((!id_expr || TREE_CODE (fn) == TEMPLATE_DECL)
+               && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+             {
+               /* Found a non-static member.  Capture this.  */
+               lambda_expr_this_capture (lam, true);
+               break;
+             }
+         }
       }
 }
 
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index bd91e18..e4f2a6a 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2962,6 +2962,12 @@ finish_member_declaration (tree decl)
   /* We should see only one DECL at a time.  */
   gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
 
+  /* Don't add decls after definition.  */
+  gcc_assert (TYPE_BEING_DEFINED (current_class_type)
+             /* We can add lambda types when late parsing default
+                arguments.  */
+             || LAMBDA_TYPE_P (TREE_TYPE (decl)));
+
   /* Set up access control for DECL.  */
   TREE_PRIVATE (decl)
     = (current_access_specifier == access_private_node);
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C 
b/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C
index 9426d5f..5cc8ca1 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr61636-1.C
@@ -1,4 +1,5 @@
 // PR c++/61636
+// PR c++/79264
 // { dg-do compile { target c++14 } }
 
 // ICE because we figure this capture too late.
@@ -28,4 +29,8 @@ void A::b() {
   auto lam2 = [&](auto asdf) { Baz (asdf); };
 
   lam2 (0);
+
+  auto lam3 = [&](auto asdf) { Baz<int> (asdf); };
+
+  lam3 (0);
 }

Reply via email to