PR c++/85807 - ICE with call in template NSDMI.
authorJason Merrill <jason@redhat.com>
Wed, 30 May 2018 19:31:11 +0000 (15:31 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 30 May 2018 19:31:11 +0000 (15:31 -0400)
* init.c (get_nsdmi): Use push_to/pop_from_top_level.
* tree.c (bot_manip): Don't set_flags_from_callee in a template.

From-SVN: r260972

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C
gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C [new file with mode: 0644]

index 2999fc3..ec5ee7e 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-24  Jason Merrill  <jason@redhat.com>
+
+       PR c++/85807 - ICE with call in template NSDMI.
+       * init.c (get_nsdmi): Use push_to/pop_from_top_level.
+       * tree.c (bot_manip): Don't set_flags_from_callee in a template.
+
 2018-05-30  Jason Merrill  <jason@redhat.com>
 
        PR c++/85873 - constant initializer_list array not in .rodata.
index 24119d1..acf9c9b 100644 (file)
@@ -577,6 +577,16 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
 
          DECL_INSTANTIATING_NSDMI_P (member) = 1;
 
+         bool pushed = false;
+         if (!currently_open_class (DECL_CONTEXT (member)))
+           {
+             push_to_top_level ();
+             push_nested_class (DECL_CONTEXT (member));
+             pushed = true;
+           }
+
+         gcc_checking_assert (!processing_template_decl);
+
          inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED);
 
          start_lambda_scope (member);
@@ -599,6 +609,12 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
              nsdmi_inst->put (member, init);
            }
 
+         if (pushed)
+           {
+             pop_nested_class ();
+             pop_from_top_level ();
+           }
+
          input_location = sloc;
          cp_unevaluated_operand = un;
        }
index 53bc9c7..4bb2879 100644 (file)
@@ -3015,7 +3015,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_)
   /* Make a copy of this node.  */
   t = copy_tree_r (tp, walk_subtrees, NULL);
   if (TREE_CODE (*tp) == CALL_EXPR || TREE_CODE (*tp) == AGGR_INIT_EXPR)
-    set_flags_from_callee (*tp);
+    if (!processing_template_decl)
+      set_flags_from_callee (*tp);
   if (data.clear_location && EXPR_HAS_LOCATION (*tp))
     SET_EXPR_LOCATION (*tp, input_location);
   return t;
index 7720379..d386f87 100644 (file)
@@ -8,7 +8,7 @@ template<typename R, typename... Args>
 struct function<R (Args...)>
 {
   template<typename F>
-  function(const F&);
+  function(const F&) { }
 };
 
 template<typename T>
index 8c0adfa..5f58991 100644 (file)
@@ -6,7 +6,7 @@ class A {
 
 public:
   template <typename _Functor, typename = _Requires<_Functor, void>>
-  A(_Functor);
+  A(_Functor) { }
 };
 template <class T> class B {
   A f = [](T) {};
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C
new file mode 100644 (file)
index 0000000..6a5c5e4
--- /dev/null
@@ -0,0 +1,25 @@
+// PR c++/85807
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct limits
+{
+  static T max();
+};
+
+template< class ScalarT = double >
+struct value_statistics_t
+{
+  double median = limits<double>::max();
+};
+
+template< class T > // required
+value_statistics_t<> calc()
+{
+  return {};
+}
+
+int main()
+{
+  value_statistics_t<> wstats = calc<double>();
+}