re PR c++/66585 (Internal compiler error when initialize field with lambda)
authorJason Merrill <jason@redhat.com>
Fri, 19 Jun 2015 18:37:41 +0000 (14:37 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 19 Jun 2015 18:37:41 +0000 (14:37 -0400)
PR c++/66585
* pt.c (instantiate_class_template_1): Clear
cp_unevaluated_operand and c_inhibit_evaluation_warnings.

From-SVN: r224684

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

index 7d42381a47408de82290044644ce48226e864c03..080d3e11e79ff1c79b21f1b18ccbcba9e92bbb5f 100644 (file)
@@ -1,3 +1,9 @@
+2015-06-18  Jason Merrill  <jason@redhat.com>
+
+       PR c++/66585
+       * pt.c (instantiate_class_template_1): Clear
+       cp_unevaluated_operand and c_inhibit_evaluation_warnings.
+
 2015-06-19  Jason Merrill  <jason@redhat.com>
 
        PR c++/65880
index 5dd5bfe55ded08de40e78f1dcc55be4b3ea6dd1f..efb90e46f0fe1bed2c0f769585cb5f2623d5165a 100644 (file)
@@ -9215,12 +9215,20 @@ instantiate_class_template_1 (tree type)
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
 
+  int saved_unevaluated_operand = cp_unevaluated_operand;
+  int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+
   fn_context = decl_function_context (TYPE_MAIN_DECL (type));
   /* Also avoid push_to_top_level for a lambda in an NSDMI.  */
   if (!fn_context && LAMBDA_TYPE_P (type) && TYPE_CLASS_SCOPE_P (type))
     fn_context = error_mark_node;
   if (!fn_context)
     push_to_top_level ();
+  else
+    {
+      cp_unevaluated_operand = 0;
+      c_inhibit_evaluation_warnings = 0;
+    }
   /* Use #pragma pack from the template context.  */
   saved_maximum_field_alignment = maximum_field_alignment;
   maximum_field_alignment = TYPE_PRECISION (pattern);
@@ -9636,6 +9644,14 @@ instantiate_class_template_1 (tree type)
        }
     }
 
+  if (fn_context)
+    {
+      /* Restore these before substituting into the lambda capture
+        initializers.  */
+      cp_unevaluated_operand = saved_unevaluated_operand;
+      c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
+    }
+
   if (tree expr = CLASSTYPE_LAMBDA_EXPR (type))
     {
       tree decl = lambda_function (type);
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C
new file mode 100644 (file)
index 0000000..8c0adfa
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/66585
+// { dg-do compile { target c++11 } }
+
+class A {
+  template <typename, typename> using _Requires = int;
+
+public:
+  template <typename _Functor, typename = _Requires<_Functor, void>>
+  A(_Functor);
+};
+template <class T> class B {
+  A f = [](T) {};
+};
+
+B<int> a;