c++: access of class-scope partial spec

Since partial specializations can't be named directly, their access
when declared at class scope is irrelevant, so we shouldn't have to set
their TREE_PRIVATE / TREE_PROTECTED in maybe_new_partial_specialization
(which is used only for constrained partial specializations anyway).

This code was added by r10-4833-gcce3c9db9e6ffa for PR92078, but it
seems better to just disable the access consistency check for partial
specializations, which lets us accept the below testcase.

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_check_access_in_redeclaration): Don't
	check access for a partial or explicit specialization.
	* pt.cc (maybe_new_partial_specialization): Don't set TREE_PRIVATE
	or TREE_PROTECTED on the newly created partial specialization.

gcc/testsuite/ChangeLog:

	* g++.dg/template/partial-specialization14.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
Patrick Palka 2024-01-15 17:01:33 -05:00
parent 47673571b2
commit f40076fa82
3 changed files with 17 additions and 3 deletions

View file

@ -35306,7 +35306,8 @@ static void
cp_parser_check_access_in_redeclaration (tree decl, location_t location)
{
if (!decl
|| (!CLASS_TYPE_P (TREE_TYPE (decl))
|| (!(CLASS_TYPE_P (TREE_TYPE (decl))
&& !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
&& TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE))
return;

View file

@ -978,8 +978,6 @@ maybe_new_partial_specialization (tree& type)
tree d = create_implicit_typedef (DECL_NAME (tmpl), t);
DECL_CONTEXT (d) = TYPE_CONTEXT (t);
DECL_SOURCE_LOCATION (d) = input_location;
TREE_PRIVATE (d) = (current_access_specifier == access_private_node);
TREE_PROTECTED (d) = (current_access_specifier == access_protected_node);
TREE_PUBLIC (d) = TREE_PUBLIC (DECL_TEMPLATE_RESULT (tmpl));
set_instantiating_module (d);

View file

@ -0,0 +1,15 @@
// Verify we don't care about the access specifier when declaring
// a partial specialization of a member class template.
struct A1 {
template<class T> struct B { };
private:
template<class T> struct B<T*> { }; // { dg-bogus "different access" }
};
struct A2 {
template<class T> struct B { };
template<class T> struct B<T*>;
private:
template<class T> struct B<T*> { }; // { dg-bogus "different access" }
};