PR12788

Nikola Smiljanic popizdeh at gmail.com
Fri Jan 17 00:30:35 PST 2014


The patch fixes the issue of protected anonymous union member not being
visible in derived class. You've reviewed this a few times but we somehow
never got to finishing. Just to remind you LookupResult can't be passed by
reference because it's not always available.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140117/7ac227cd/attachment.html>
-------------- next part --------------
 include/clang/Sema/Sema.h                      |  1 +
 lib/Sema/SemaExprMember.cpp                    |  6 ++++--
 test/CXX/class.access/class.access.base/p1.cpp | 14 ++++++++++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index ec8bb99..0e12ba2 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3262,6 +3262,7 @@ public:
       const CXXScopeSpec &SS,
       SourceLocation nameLoc,
       IndirectFieldDecl *indirectField,
+      LookupResult *R = 0,
       DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_none),
       Expr *baseObjectExpr = 0,
       SourceLocation opLoc = SourceLocation());
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 1a08c5b..91ba5de 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -724,6 +724,7 @@ ExprResult
 Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
                                                SourceLocation loc,
                                                IndirectFieldDecl *indirectField,
+                                               LookupResult *R,
                                                DeclAccessPair foundDecl,
                                                Expr *baseObjectExpr,
                                                SourceLocation opLoc) {
@@ -790,6 +791,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
       = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true);
     baseObjectIsPointer = true;
     baseQuals = ThisTy->castAs<PointerType>()->getPointeeType().getQualifiers();
+    R->setBaseObjectType(ThisTy->castAs<PointerType>()->getPointeeType());
   }
   
   // Build the implicit member references to the field of the
@@ -1059,7 +1061,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
   if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
     // We may have found a field within an anonymous union or struct
     // (C++ [class.union]).
-    return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
+    return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD, &R,
                                                     FoundDecl, BaseExpr,
                                                     OpLoc);
 
@@ -1757,7 +1759,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
   // (C++ [class.union]).
   // FIXME: template-ids inside anonymous structs?
   if (IndirectFieldDecl *FD = R.getAsSingle<IndirectFieldDecl>())
-    return BuildAnonymousStructUnionMemberReference(SS, R.getNameLoc(), FD,
+    return BuildAnonymousStructUnionMemberReference(SS, R.getNameLoc(), FD, &R,
                                                     R.begin().getPair());
   
   // If this is known to be an instance access, go ahead and build an
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp
index 43cc99e..d88e8ea 100644
--- a/test/CXX/class.access/class.access.base/p1.cpp
+++ b/test/CXX/class.access/class.access.base/p1.cpp
@@ -153,3 +153,17 @@ namespace test2 {
     t->Base::spriv++; // expected-error 2 {{private member}}
   }
 }
+
+namespace PR12788 {
+  class Base {
+  protected:
+    struct { int x; };
+  };
+  
+  class Test : public Base {
+    void mem() {
+      x++;
+      Base::x++;
+    }
+  };
+}


More information about the cfe-commits mailing list