On 11/15/19 12:07 PM, Nathan Sidwell wrote:
Jason,
using ENUM::v is proving rather tricky, when the memberness of the
enumerator and the context of the using decl differ.
struct B
{
enum E {e};
};
struct D
{
private:
using B::e; // ok
static inline const auto ok1 = e; // #1 accessible
};
struct F : D
{
static inline const auto bad1 = e; // #2 inaccessible
}
The CONST_DECL is what gets injected into the binding level -- not the
USING_DECL. the access checking machinery expects that the context of
any member it's checking is within the inheritance graph. That's not
true and if ICEs at #1 and #2. Simply bailing out if the thing being
checked is not in the graph, fixes #1, but then we miss #2 as we can't
tell the difference -- all we have is the CONST_DECL with no separate
scope information.
I'm considering 2 ways around this:
1) push the USING_DECL, not the CONST_DECL, into the binding. I think
we do this for some other cases, but I'm not sure exactly why/where. I'm
concerned strip_using_decls will trigger too early, and we'll be back to
the above scenario.
Our do_class_using_decl does normally build USING_DECLs for class-scope
using-declarations. Are you not using that code?
2) clone the CONST_DECL, giving it a fake DECL_CONTEXT of the
using-decl's scope. We can still get to the correct context via the
CONST_DECL's type. There's probably a DECL_LANG flag we can use to mark
it as fake -- perhaps DECL_ARTIFICIAL suffices.
That could work if the normal path doesn't for some reason.
Are you going to have a chance to look at this any more in stage 1, or
should I take a crack at it?
Jason