[cfe-commits] protected anonymous union member not visible in derived class

John McCall rjmccall at apple.com
Fri Aug 17 13:11:16 PDT 2012


On Aug 17, 2012, at 3:12 AM, Nikola Smiljanic wrote:
>> You should make this a non-optional argument;  I think that should be
>> fine for all the callers.  (Your implementation isn't safe against null
>> lookup results anyway, but it doesn't matter, because you don't need
>> to rely on that.)
> 
> I tried doing this, passed LookupResult by reference and had to change
> the signature of BuildDeclarationNameExpr because it's calling
> BuildAnonymousStructUnionMemberReference and doesn't have a
> LookupResult to pass. Now the same thing happens with
> RebuildDeclRefExpr that calls BuildDeclarationNameExpr and doesn't
> have a LookupResult to pass. I went up the call chain, but couldn't
> figure out where to get the LookupResult?

Ugh, and the main DeclRefExpr paths don't seem to record found
declarations reliably.  This is probably too invasive of a refactor; sorry
for recommending it.

>> That is not the real found-decl info. :)  You're implicitly stripping off
>> UsingShadowDecls and the found access path.  You just want *R->begin().
> 
> In that case should I use *R->begin() or R->getRepresentativeDecl()?

The first.

> And is there a test case I could write to make sure this FIXME was
> actually fixed, because getFoundDecl and *begin() are the same in my
> example?

IIRC, it's just an AST accuracy concern.

The access controls will be different if modified by inheritance, e.g.:
  struct A {
    union {
      int x;
      float y;
    };
  };
  struct B : private A {
     void test() {
       x = 5;  // 'x' is public in A but private in B
     };
  };

The found declarations will be different in the presence of a using declaration:
  struct A {
    union {
      int x;
      float y;
    };
  };

  struct C : private A {
    using A::x; // C::x will be a UsingShadowDecl with public access
  };

>> This is in the implicit member access case, right?  You don't need to check
>> for a pointer type — the base expression is always 'this' and therefore
>> always has pointer type.
> 
> This 'if' was an assert at first, but when I ran the test suite it
> fired on this insanity from CodeGen/init.c:
> 
> typedef union vec3 {
>  struct { double x, y, z; };
>  double component[3];
> } vec3;
> vec3 f5(vec3 value) {
>  return (vec3) {{
>    .x = value.x
>  }};
> }

This is from building value.x, right?  That's not the implicit member access case.
It is definitely possible for an actual base expression to be non-null.

> Do you know the right place to add a test for this PR?

If there's an obviously applicable standards quote, the appropriate place
in test/CXX/ would be great.

John.



More information about the cfe-commits mailing list