aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-06-04 11:16:00 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-06-04 11:16:00 -0400
commitae177d3529441c5c834748bc890cf6823960b008 (patch)
tree8c2bcb9e7a4d2d05d42477516dee59e8ca226f01 /gcc
parent8566678b9da3db996f7566ecb691be07ff376c8f (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/pt.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/sfinae63.C39
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() {}