This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFH / Patch] PR 54191


Hi,

this is an update on C++/54191, where in a number of cases, having to do with inaccessible bases, we don't handle correctly access control under SFINAE.

The attached draft patch p fixes a number of tests (and passes regression testing), where we are currently emitting inaccessible base diagnostics from lookup_base instead of properly handling the failure in SFINAE. As you can see in the draft, after a number of tries, I'm simply adding a tsubst_flags_t parameter to lookup_base: obviously something is redundant with base_access, but knowing that a returned error_mark_node in every case means that the base is either ambiguous or inaccessible (when we error out outside SFINAE) is *so* convenient! For comparison, the existing get_delta_difference_1 shows an alternate approach, quite contorted IMHO. But these are just implementation details...

More interesting are the cases, commented out in the attached 54191.C, which we still get wrong also with the patch applied. In those cases we do *not* currently produce any inaccessible base diagnostics, we simply mishandle the SFINAE, apparently we don't perform any form of access control. I'm really looking for help about this set of 5 tests (4 braced casts + conditional operator)

Thanks!
Paolo.

///////////////////////////

Attachment: p
Description: Text document

struct B
{};

struct D
  : private B
{};

template<typename T>
T &&declval();

/*
template<typename From, typename = decltype(B{declval<From>()})>
constexpr bool test_braced_cast_to_base(int)
{ return true; }

template<typename>
constexpr bool test_braced_cast_to_base(bool)
{ return false; }

static_assert(!test_braced_cast_to_base<D>(0), "");


template<typename From, typename = decltype(D{declval<From>()})>
constexpr bool test_braced_cast_to_derived(int)
{ return true; }

template<typename>
constexpr bool test_braced_cast_to_derived(bool)
{ return false; }

static_assert(!test_braced_cast_to_derived<B>(0), "");


typedef B *PB;

template<typename From, typename = decltype(PB{declval<From>()})>
constexpr bool test_braced_cast_to_ptr_to_base(int)
{ return true; }

template<typename>
constexpr bool test_braced_cast_to_ptr_to_base(bool)
{ return false; }

static_assert(!test_braced_cast_to_ptr_to_base<D *>(0), "");


typedef D *PD;

template<typename From, typename = decltype(PD{declval<From>()})>
constexpr bool test_braced_cast_to_ptr_to_derived(int)
{ return true; }

template<typename>
constexpr bool test_braced_cast_to_ptr_to_derived(bool)
{ return false; }

static_assert(!test_braced_cast_to_ptr_to_derived<B *>(0), "");
*/

template<typename From, typename To,
         typename = decltype(static_cast<To>(declval<From>()))>
constexpr bool test_static_cast(int)
{ return true; }

template<typename, typename>
constexpr bool test_static_cast(bool)
{ return false; }

static_assert(!test_static_cast<B &, D &>(0), "");
static_assert(!test_static_cast<B *, D *>(0), "");


template<typename From, typename To,
         typename = decltype(dynamic_cast<To>(declval<From>()))>
constexpr bool test_dynamic_cast(int)
{ return true; }

template<typename, typename>
constexpr bool test_dynamic_cast(bool)
{ return false; }

static_assert(!test_dynamic_cast<D &, B &>(0), "");
static_assert(!test_dynamic_cast<D *, B *>(0), "");


int B::*pm = 0;

template<typename T, typename = decltype(declval<T>().*pm)>
constexpr bool test_member_ptr_dot(int)
{ return true; }

template<typename>
constexpr bool test_member_ptr_dot(bool)
{ return false; }

static_assert(!test_member_ptr_dot<D>(0), "");


template<typename T, typename = decltype(declval<T>()->*pm)>
constexpr bool test_member_ptr_arrow(int)
{ return true; }

template<typename>
constexpr bool test_member_ptr_arrow(bool)
{ return false; }

static_assert(!test_member_ptr_arrow<D *>(0), "");


template<typename T, typename U,
         typename = decltype(declval<T>() < declval<U>())>
constexpr bool test_rel_op(int)
{ return true; }

template<typename, typename>
constexpr bool test_rel_op(bool)
{ return false; }

static_assert(!test_rel_op<D *, B *>(0), "");


template<typename T, typename U,
         typename = decltype(declval<T>() == declval<U>())>
constexpr bool test_eq(int)
{ return true; }

template<typename, typename>
constexpr bool test_eq(bool)
{ return false; }

static_assert(!test_eq<D *, B *>(0), "");

/*
template<typename T, typename U,
         typename = decltype(false ? declval<T>() : declval<U>())>
constexpr bool test_cond_op(int)
{ return true; }

template<typename, typename>
constexpr bool test_cond_op(bool)
{ return false; }

static_assert(!test_cond_op<B *, D *>(0), "");
*/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]