PR c++/89612 - ICE with member friend template with noexcept.
* pt.c (maybe_instantiate_noexcept): For function templates, use their template result (function decl). Don't set up local specializations. Temporarily turn on processing_template_decl. Update the template type too. * g++.dg/cpp0x/noexcept38.C: New test. * g++.dg/cpp0x/noexcept39.C: New test. * g++.dg/cpp1z/noexcept-type21.C: New test. From-SVN: r270005
This commit is contained in:
parent
ddfd99ac13
commit
c526171d73
|
@ -1,5 +1,11 @@
|
|||
2019-03-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/89612 - ICE with member friend template with noexcept.
|
||||
* pt.c (maybe_instantiate_noexcept): For function templates, use their
|
||||
template result (function decl). Don't set up local specializations.
|
||||
Temporarily turn on processing_template_decl. Update the template type
|
||||
too.
|
||||
|
||||
PR c++/89836 - bool constant expression and explicit conversions.
|
||||
* call.c (build_converted_constant_expr_internal): New function,
|
||||
renamed from...
|
||||
|
|
73
gcc/cp/pt.c
73
gcc/cp/pt.c
|
@ -24193,6 +24193,17 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
|
|||
|
||||
if (DECL_CLONED_FUNCTION_P (fn))
|
||||
fn = DECL_CLONED_FUNCTION (fn);
|
||||
|
||||
tree orig_fn = NULL_TREE;
|
||||
/* For a member friend template we can get a TEMPLATE_DECL. Let's use
|
||||
its FUNCTION_DECL for the rest of this function -- push_access_scope
|
||||
doesn't accept TEMPLATE_DECLs. */
|
||||
if (DECL_FUNCTION_TEMPLATE_P (fn))
|
||||
{
|
||||
orig_fn = fn;
|
||||
fn = DECL_TEMPLATE_RESULT (fn);
|
||||
}
|
||||
|
||||
fntype = TREE_TYPE (fn);
|
||||
spec = TYPE_RAISES_EXCEPTIONS (fntype);
|
||||
|
||||
|
@ -24229,37 +24240,41 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
|
|||
push_deferring_access_checks (dk_no_deferred);
|
||||
input_location = DECL_SOURCE_LOCATION (fn);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
/* If this function is represented by a TEMPLATE_DECL, then
|
||||
the deferred noexcept-specification might still contain
|
||||
dependent types, even after substitution. And we need the
|
||||
dependency check functions to work in build_noexcept_spec. */
|
||||
if (orig_fn)
|
||||
++processing_template_decl;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
current_class_ptr = save_ccp;
|
||||
current_class_ref = save_ccr;
|
||||
|
||||
/* Build up the noexcept-specification. */
|
||||
spec = build_noexcept_spec (noex, tf_warning_or_error);
|
||||
|
||||
if (orig_fn)
|
||||
--processing_template_decl;
|
||||
|
||||
pop_deferring_access_checks ();
|
||||
pop_access_scope (fn);
|
||||
|
@ -24279,6 +24294,8 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
|
|||
}
|
||||
|
||||
TREE_TYPE (fn) = build_exception_variant (fntype, spec);
|
||||
if (orig_fn)
|
||||
TREE_TYPE (orig_fn) = TREE_TYPE (fn);
|
||||
}
|
||||
|
||||
FOR_EACH_CLONE (clone, fn)
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2019-03-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/89612 - ICE with member friend template with noexcept.
|
||||
* g++.dg/cpp0x/noexcept38.C: New test.
|
||||
* g++.dg/cpp0x/noexcept39.C: New test.
|
||||
* g++.dg/cpp1z/noexcept-type21.C: New test.
|
||||
|
||||
2019-03-28 Uroš Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR target/89848
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// PR c++/89612
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <typename>
|
||||
struct C {
|
||||
template <int N>
|
||||
friend int foo() noexcept(N);
|
||||
|
||||
template <int N>
|
||||
friend int foo2() noexcept(N); // { dg-error "different exception" }
|
||||
};
|
||||
|
||||
template <int N>
|
||||
int foo() noexcept(N);
|
||||
|
||||
template <int N>
|
||||
int foo2() noexcept(N + 1);
|
||||
|
||||
C<int> c;
|
|
@ -0,0 +1,19 @@
|
|||
// PR c++/89612
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <typename T>
|
||||
struct C {
|
||||
template <int N>
|
||||
friend void foo(T t) noexcept(sizeof(decltype(t)) > 1);
|
||||
|
||||
template <int N>
|
||||
friend void foo2(T t) noexcept(sizeof(decltype(t)) < 1); // { dg-error "different exception" }
|
||||
};
|
||||
|
||||
template <int N>
|
||||
void foo(int i) noexcept { }
|
||||
|
||||
template <int N>
|
||||
void foo2(int i) noexcept { }
|
||||
|
||||
C<int> c;
|
|
@ -0,0 +1,16 @@
|
|||
// PR c++/89612
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
template <typename a> using b = typename a ::c;
|
||||
template <typename> bool d;
|
||||
template <typename, typename> struct e {
|
||||
template <typename f, typename g> e(f, g) {}
|
||||
template <typename h, typename i, typename j>
|
||||
friend auto k(h &&, const j &, i &&) noexcept(d<b<h>, h> &&d<b<i>, i>);
|
||||
};
|
||||
template <typename l, typename m> e(l, m)->e<l, m>;
|
||||
template <typename l, typename m, typename j>
|
||||
auto k(l &&, const j &, m &&) noexcept(d<b<l>, l> &&d<b<m>, m>);
|
||||
int main() {
|
||||
e(0, [] {});
|
||||
}
|
Loading…
Reference in New Issue