diff options
author | Jason Merrill <jason@redhat.com> | 2018-06-04 11:16:00 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2018-06-04 11:16:00 -0400 |
commit | ae177d3529441c5c834748bc890cf6823960b008 (patch) | |
tree | 8c2bcb9e7a4d2d05d42477516dee59e8ca226f01 /gcc | |
parent | 8566678b9da3db996f7566ecb691be07ff376c8f (diff) | |
download | gcc-ae177d3529441c5c834748bc890cf6823960b008.zip gcc-ae177d3529441c5c834748bc890cf6823960b008.tar.gz gcc-ae177d3529441c5c834748bc890cf6823960b008.tar.bz2 |
PR c++/61806 - missed SFINAE with partial specialization.
* cp-tree.h (deferring_access_check_sentinel): Add deferring_kind
parameter to constructor.
* pt.c (instantiate_class_template_1): Enable access checking
before call to most_specialized_partial_spec.
From-SVN: r261151
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/sfinae63.C | 39 |
4 files changed, 51 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 773e933..c07371e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2018-06-04 Jason Merrill <jason@redhat.com> + PR c++/61806 - missed SFINAE with partial specialization. + * cp-tree.h (deferring_access_check_sentinel): Add deferring_kind + parameter to constructor. + * pt.c (instantiate_class_template_1): Enable access checking + before call to most_specialized_partial_spec. + PR c++/85765 - SFINAE and non-type default template arg. * pt.c (type_unification_real): Do full semantic processing if substituting a partial args list replaces all template parms. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 6a97abb..f2016f1 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6807,9 +6807,9 @@ extern bool perform_or_defer_access_check (tree, tree, tree, struct deferring_access_check_sentinel { - deferring_access_check_sentinel () + deferring_access_check_sentinel (enum deferring_kind kind = dk_deferred) { - push_deferring_access_checks (dk_deferred); + push_deferring_access_checks (kind); } ~deferring_access_check_sentinel () { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d3915dd..aad68a3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10850,6 +10850,10 @@ instantiate_class_template_1 (tree type) /* Mark the type as in the process of being defined. */ TYPE_BEING_DEFINED (type) = 1; + /* We may be in the middle of deferred access check. Disable + it now. */ + deferring_access_check_sentinel acs (dk_no_deferred); + /* Determine what specialization of the original template to instantiate. */ t = most_specialized_partial_spec (type, tf_warning_or_error); @@ -10889,10 +10893,6 @@ instantiate_class_template_1 (tree type) if (! push_tinst_level (type)) return type; - /* We may be in the middle of deferred access check. Disable - it now. */ - push_deferring_access_checks (dk_no_deferred); - int saved_unevaluated_operand = cp_unevaluated_operand; int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; @@ -11373,7 +11373,6 @@ instantiate_class_template_1 (tree type) maximum_field_alignment = saved_maximum_field_alignment; if (!fn_context) pop_from_top_level (); - pop_deferring_access_checks (); pop_tinst_level (); /* The vtable for a template class can be emitted in any translation diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae63.C b/gcc/testsuite/g++.dg/cpp0x/sfinae63.C new file mode 100644 index 0000000..7ad3849 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae63.C @@ -0,0 +1,39 @@ +// PR c++/61806 +// { dg-do compile { target c++11 } } + +struct true_type +{ + static const bool value = true; +}; + +struct false_type +{ + static const bool value = false; +}; + +template<class T> +T&& declval(); + +template<typename> struct check { typedef void type; }; + +template<typename T, typename Enable = void> +struct has_public_f : false_type {}; + +template<typename T> +struct has_public_f< + T, + typename check< + decltype( + declval<T&>().f() + ) + >::type +> : true_type {}; + + +struct Spub { public: void f(); }; +struct Spriv { private: void f(); }; + +static_assert( has_public_f<Spub>::value, "Ouch"); +static_assert(!has_public_f<Spriv>::value, "Ouch"); + +int main() {} |