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
This commit is contained in:
Jason Merrill 2018-06-04 11:16:00 -04:00 committed by Jason Merrill
parent 8566678b9d
commit ae177d3529
4 changed files with 51 additions and 7 deletions

View file

@ -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.

View file

@ -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 ()
{

View file

@ -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

View file

@ -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() {}