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

Reply via email to