From 298434c916c14e8adca2cab8a746aee29038c5b3 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 30 May 2018 15:31:11 -0400 Subject: [PATCH] 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. From-SVN: r260972 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/init.c | 16 +++++++++++++++ gcc/cp/tree.c | 3 ++- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C | 2 +- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C | 2 +- gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C | 25 +++++++++++++++++++++++ 6 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2999fc3..ec5ee7e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-05-24 Jason Merrill + + 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 PR c++/85873 - constant initializer_list array not in .rodata. diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 24119d1..acf9c9b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 53bc9c7..4bb2879 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C index 7720379..d386f87 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C @@ -8,7 +8,7 @@ template struct function { template - function(const F&); + function(const F&) { } }; template diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C index 8c0adfa..5f58991 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C @@ -6,7 +6,7 @@ class A { public: template > - A(_Functor); + A(_Functor) { } }; template 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 index 0000000..6a5c5e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C @@ -0,0 +1,25 @@ +// PR c++/85807 +// { dg-do compile { target c++11 } } + +template +struct limits +{ + static T max(); +}; + +template< class ScalarT = double > +struct value_statistics_t +{ + double median = limits::max(); +}; + +template< class T > // required +value_statistics_t<> calc() +{ + return {}; +} + +int main() +{ + value_statistics_t<> wstats = calc(); +} -- 2.7.4