This patch generalizes our existing functionality for deferring access checking of typedefs when parsing a function or class template to now defer all kinds of access checks until template instantiation time, including member function and member object accesses. Since all access checks eventually go through enforce_access, the main component of this patch is new handling inside enforce_access to defer the current access check if we're inside a template. The bulk of the rest of the patch consists of removing now-unneeded code pertaining to suppressing access checks inside templates or pertaining to typedef-specific access handling. Renamings and other changes with no functional impact have been split off into the followup patch. gcc/cp/ChangeLog: PR c++/41437 PR c++/47346 * call.c (enforce_access): Move to semantics.c. * cp-tree.h (enforce_access): Delete. (get_types_needing_access_check): Delete. (add_typedef_to_current_template_for_access_check): Delete. * decl.c (make_typename_type): Adjust accordingly. Use check_accessibility_of_qualified_id instead of directly using perform_or_defer_access_check. * parser.c (cp_parser_template_declaration_after_parameters): Don't push a dk_no_check access state when parsing a template. * pt.c (get_types_needing_access_check): Delete. (append_type_to_template_for_access_check_1): Delete. (perform_typedefs_access_check): Adjust. If type_decl is a FIELD_DECL, also check its DECL_CONTEXT for dependence. Use tsubst_copy instead of tsubst to substitute into type_decl so that we substitute into the DECL_CONTEXT of a FIELD_DECL. (append_type_to_template_for_access_check): Delete. * search.c (accessible_p): Remove the processing_template_decl early exit. * semantics.c (enforce_access): Moved from call.c. If we're parsing a template and the access check failed, add the check to TI_TYPEDEFS_NEEDING_ACCESS_CHECKING. (perform_or_defer_access_check): Adjust comment. (add_typedef_to_current_template_for_access_check): Delete. (check_accessibility_of_qualified_id): Adjust accordingly. Exit early if the scope is dependent. gcc/testsuite/ChangeLog: PR c++/41437 PR c++/47346 * g++.dg/cpp2a/concepts-using2.C: Adjust. * g++.dg/lto/20081219_1.C: Adjust. * g++.dg/lto/20091002-1_0.C: Adjust. * g++.dg/lto/pr65475c_0.C: Adjust. * g++.dg/opt/dump1.C: Adjust. * g++.dg/other/pr53574.C: Adjust. * g++.dg/template/access30.C: New test. * g++.dg/template/access31.C: New test. * g++.dg/wrappers/wrapper-around-type-pack-expansion.C: Adjust. libstdc++-v3/ChangeLog: PR libstdc++/94003 * testsuite/20_util/is_constructible/94003.cc: New test.
50 lines
1.4 KiB
C
50 lines
1.4 KiB
C
// PR c++/93907
|
|
// { dg-options -std=gnu++20 }
|
|
|
|
template <int a> struct c {
|
|
static constexpr int d = a;
|
|
typedef c e;
|
|
};
|
|
template <typename> struct f;
|
|
template <typename b> using g = typename f<b>::e;
|
|
struct b;
|
|
template <typename b> struct f { using e = b; };
|
|
template <typename ai> struct m { typedef g<ai> aj; };
|
|
template <typename b> struct n { typedef typename m<b>::aj e; };
|
|
template <typename b> using an = typename n<b>::e;
|
|
template <typename> constexpr bool ao = c<true>::d;
|
|
template <typename> constexpr bool i = c<1>::d;
|
|
template <typename> concept bb = i<b>;
|
|
#ifdef __SIZEOF_INT128__
|
|
using cc = __int128;
|
|
#else
|
|
using cc = long long;
|
|
#endif
|
|
template <typename> concept cd = bb<cc>;
|
|
template <typename bt> concept ce = requires { requires cd<bt>; };
|
|
template <typename bt> concept h = ce<bt>;
|
|
template <typename bt> concept l = h<bt>;
|
|
template <typename> concept cl = ao<b>;
|
|
template <typename b> concept cp = requires(b j) {
|
|
requires h<an<decltype(j.begin())>>;
|
|
};
|
|
struct o {
|
|
template <cl b> requires cp<b> auto operator()(b) {}
|
|
};
|
|
template <typename b> using cm = decltype(o{}(b()));
|
|
template <typename bt> concept ct = l<bt>;
|
|
template <typename da> concept dd = ct<cm<da>>;
|
|
template <typename da> concept de = dd<da>;
|
|
struct {
|
|
template <de da, typename b> void operator()(da, b);
|
|
} di;
|
|
struct p {
|
|
void begin();
|
|
};
|
|
template <typename> using df = p;
|
|
template <int> void q() {
|
|
df<int> k;
|
|
int d;
|
|
di(k, d);
|
|
}
|