diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access40.C | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access40a.C | 28 |
3 files changed, 60 insertions, 1 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e5a2a2c..f2039e0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11769,8 +11769,11 @@ instantiate_class_template_1 (tree type) deferring_access_check_sentinel acs (dk_no_deferred); /* Determine what specialization of the original template to - instantiate. */ + instantiate; do this relative to the scope of the class for + sake of access checking. */ + push_nested_class (type); t = most_specialized_partial_spec (type, tf_warning_or_error); + pop_nested_class (); if (t == error_mark_node) return error_mark_node; else if (t) diff --git a/gcc/testsuite/g++.dg/template/access40.C b/gcc/testsuite/g++.dg/template/access40.C new file mode 100644 index 0000000..d035e99 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access40.C @@ -0,0 +1,28 @@ +// PR c++/96204 + +template<class, class = void> +struct has_type_member { + static const bool value = false; +}; + +template<class T> +struct has_type_member<T, typename T::type> { + static const bool value = true; +}; + +struct Parent; + +struct Child { +private: + friend struct Parent; + typedef void type; +}; + +struct Parent { + static void f() { + // The partial specialization does not match despite Child::type + // being accessible from the current scope. + extern int x[1]; + extern int x[!has_type_member<Child>::value]; + } +}; diff --git a/gcc/testsuite/g++.dg/template/access40a.C b/gcc/testsuite/g++.dg/template/access40a.C new file mode 100644 index 0000000..94025c5 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access40a.C @@ -0,0 +1,28 @@ +// PR c++/96204 + +template<class, class = void> +struct has_type_member { + static const bool value = false; +}; + +template<class T> +struct has_type_member<T, typename T::type> { + static const bool value = true; +}; + +struct Parent; + +struct Child { +private: + friend struct has_type_member<Child>; + typedef void type; +}; + +struct Parent { + static void f() { + // The partial specialization matches because has_type_member<Child> + // is a friend of Child. + extern int x[1]; + extern int x[has_type_member<Child>::value]; + } +}; |