From 85409531ff032a008ebfbb715344648f15492dac Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 4 Feb 2020 17:18:35 -0500 Subject: [PATCH] c++: Fix error-recovery with concepts. Here, push_tinst_level refused to push into the scope of Foo::Foo because it was triggered from the ill-formed function fun. But we didn't check the return value and tried to pop the un-pushed level. PR c++/93551 * constraint.cc (satisfy_declaration_constraints): Check return value of push_tinst_level. --- gcc/cp/ChangeLog | 4 +++ gcc/cp/constraint.cc | 3 +- gcc/testsuite/g++.dg/cpp2a/concepts-err1.C | 33 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-err1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 956e94b2337..4e4235d638b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2020-02-04 Jason Merrill + PR c++/93551 + * constraint.cc (satisfy_declaration_constraints): Check return + value of push_tinst_level. + PR c++/90951 * constexpr.c (cxx_eval_array_reference): {}-initialize missing elements instead of value-initializing them. diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index cda644eabe2..58044cd0f9d 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2692,7 +2692,8 @@ satisfy_declaration_constraints (tree t, subst_info info) tree result = boolean_true_node; if (norm) { - push_tinst_level (t); + if (!push_tinst_level (t)) + return result; push_access_scope (t); result = satisfy_associated_constraints (norm, args, info); pop_access_scope (t); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-err1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-err1.C new file mode 100644 index 00000000000..e482ba05b46 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-err1.C @@ -0,0 +1,33 @@ +// PR c++/93551 +// { dg-do compile { target concepts } } + +namespace std { + template + struct integral_constant + { + static constexpr _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + constexpr operator value_type() const noexcept { return value; } + }; + template + struct is_base_of + : public integral_constant + { }; + template + inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value; +} +class Bar { }; +struct Foo { + template requires std::is_base_of_v + Foo(P const&); +}; +template +Foo fun(P const& arg) { + (bool)arg; // { dg-error "" } + return Foo {arg}; +} +int main() { + fun(Bar{}); + return 0; +} -- 2.30.2