diff options
author | Jason Merrill <jason@redhat.com> | 2018-05-30 15:31:11 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-05-30 15:31:11 -0400 |
commit | 298434c916c14e8adca2cab8a746aee29038c5b3 (patch) | |
tree | 2ec8d226631111636f2272d5019a251a36d6e3c7 /gcc | |
parent | fbf5c1c64c0fbfe529ea86924c789e1dbeeb4a24 (diff) | |
download | gcc-298434c916c14e8adca2cab8a746aee29038c5b3.zip gcc-298434c916c14e8adca2cab8a746aee29038c5b3.tar.gz gcc-298434c916c14e8adca2cab8a746aee29038c5b3.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 16 | ||||
-rw-r--r-- | gcc/cp/tree.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice14.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-nsdmi8.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/nsdmi-template17.C | 25 |
6 files changed, 51 insertions, 3 deletions
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 <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. 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<typename R, typename... Args> struct function<R (Args...)> { template<typename F> - function(const F&); + function(const F&) { } }; template<typename T> 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 <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 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 <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>(); +} |