diff options
author | Marek Polacek <polacek@redhat.com> | 2019-02-23 14:05:31 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-02-23 14:05:31 +0000 |
commit | 28a19c5be3c3982595230497f1a6142fda69bdfa (patch) | |
tree | 2e28c31b6d5c2e1f9a5384301740141655ad547e | |
parent | 524cee402e974b7e8e6e8e7ca6af189360c99526 (diff) | |
download | gcc-28a19c5be3c3982595230497f1a6142fda69bdfa.zip gcc-28a19c5be3c3982595230497f1a6142fda69bdfa.tar.gz gcc-28a19c5be3c3982595230497f1a6142fda69bdfa.tar.bz2 |
PR c++/88294 - ICE with non-constant noexcept-specifier.
* pt.c (maybe_instantiate_noexcept): Set up the list of local
specializations. Set current_class_{ptr,ref}.
* g++.dg/cpp0x/noexcept34.C: New test.
* g++.dg/cpp0x/noexcept35.C: New test.
From-SVN: r269158
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 39 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept34.C | 29 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept35.C | 21 |
5 files changed, 95 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2a5056a..2da2e3d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-02-23 Marek Polacek <polacek@redhat.com> + + PR c++/88294 - ICE with non-constant noexcept-specifier. + * pt.c (maybe_instantiate_noexcept): Set up the list of local + specializations. Set current_class_{ptr,ref}. + 2019-02-22 David Malcolm <dmalcolm@redhat.com> PR c++/89390 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 42dd095..d678e27 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -24203,12 +24203,39 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) push_access_scope (fn); push_deferring_access_checks (dk_no_deferred); input_location = DECL_SOURCE_LOCATION (fn); - noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex), - DEFERRED_NOEXCEPT_ARGS (noex), - tf_warning_or_error, fn, - /*function_p=*/false, - /*integral_constant_expression_p=*/true); - spec = build_noexcept_spec (noex, tf_warning_or_error); + + /* A new stack interferes with pop_access_scope. */ + { + /* Set up the list of local specializations. */ + local_specialization_stack lss (lss_copy); + + tree save_ccp = current_class_ptr; + tree save_ccr = current_class_ref; + /* If needed, set current_class_ptr for the benefit of + tsubst_copy/PARM_DECL. */ + tree tdecl = DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (fn)); + if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tdecl)) + { + tree this_parm = DECL_ARGUMENTS (tdecl); + current_class_ptr = NULL_TREE; + current_class_ref = cp_build_fold_indirect_ref (this_parm); + current_class_ptr = this_parm; + } + + /* Create substitution entries for the parameters. */ + register_parameter_specializations (tdecl, fn); + + /* Do deferred instantiation of the noexcept-specifier. */ + noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex), + DEFERRED_NOEXCEPT_ARGS (noex), + tf_warning_or_error, fn, + /*function_p=*/false, + /*i_c_e_p=*/true); + current_class_ptr = save_ccp; + current_class_ref = save_ccr; + spec = build_noexcept_spec (noex, tf_warning_or_error); + } + pop_deferring_access_checks (); pop_access_scope (fn); pop_tinst_level (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc5a87d..da4aa85 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-02-23 Marek Polacek <polacek@redhat.com> + + PR c++/88294 - ICE with non-constant noexcept-specifier. + * g++.dg/cpp0x/noexcept34.C: New test. + * g++.dg/cpp0x/noexcept35.C: New test. + 2019-02-23 Paul Thomas <pault@gcc.gnu.org> PR fortran/88117 diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept34.C b/gcc/testsuite/g++.dg/cpp0x/noexcept34.C new file mode 100644 index 0000000..dce3565 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept34.C @@ -0,0 +1,29 @@ +// PR c++/88294 +// { dg-do compile { target c++11 } } + +constexpr int foo (bool b) { return b; } + +template<typename> struct A +{ + constexpr int f () { return 0; } + bool b = true; + void g () noexcept (f()) { } // { dg-error "use of parameter" } + void g2 () noexcept (this->f()) { } // { dg-error "use of parameter" } + void g3 () noexcept (b) { } // { dg-error "use of .this. in a constant expression|use of parameter" } + void g4 (int i) noexcept (i) { } // { dg-error "use of parameter" } + void g5 () noexcept (A::f()) { } // { dg-error "use of parameter" } + void g6 () noexcept (foo(b)) { } // { dg-error "use of .this. in a constant expression|use of parameter" } + void g7 () noexcept (int{f()}) { } // { dg-error "use of parameter" } +}; + +int main () +{ + A<int> a; + a.g (); + a.g2 (); + a.g3 (); + a.g4 (1); + a.g5 (); + a.g6 (); + a.g7 (); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept35.C b/gcc/testsuite/g++.dg/cpp0x/noexcept35.C new file mode 100644 index 0000000..8606b1a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept35.C @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +template <typename _Tp, _Tp __v> struct A { static constexpr _Tp value = __v; }; +typedef A<bool, false> false_type; +struct is_same : false_type {}; +template <bool> struct enable_if; +template <typename> using __remove_cvref_t = int; +template <typename _Tp> class reference_wrapper { + static _Tp _S_fun(); + template <typename _Up, typename = __remove_cvref_t<_Up>> + using __not_same = enable_if<is_same::value>; + +public: + template <typename _Up, typename = __not_same<_Up>> + reference_wrapper(_Up) noexcept(noexcept(reference_wrapper::_S_fun)); +}; + +reference_wrapper<int> fn1() { + int __t = 10; + return __t; +} |