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:
parent
8566678b9d
commit
ae177d3529
4 changed files with 51 additions and 7 deletions
|
@ -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.
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
39
gcc/testsuite/g++.dg/cpp0x/sfinae63.C
Normal file
39
gcc/testsuite/g++.dg/cpp0x/sfinae63.C
Normal 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() {}
|
Loading…
Add table
Reference in a new issue