r186367 - Fix member refs with using decl + anonymous union.
Eli Friedman
eli.friedman at gmail.com
Mon Jul 15 17:01:31 PDT 2013
Author: efriedma
Date: Mon Jul 15 19:01:31 2013
New Revision: 186367
URL: http://llvm.org/viewvc/llvm-project?rev=186367&view=rev
Log:
Fix member refs with using decl + anonymous union.
Make sure we call BuildFieldReferenceExpr with the appropriate decl
when a member of an anonymous union is made public with a using decl.
Also, fix a crash on invalid field access into an anonymous union.
Fixes PR16630.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/SemaCXX/anonymous-union.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=186367&r1=186366&r2=186367&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul 15 19:01:31 2013
@@ -3150,11 +3150,14 @@ public:
const CXXScopeSpec *SS = 0,
NamedDecl *FoundD = 0);
ExprResult
- BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
- SourceLocation nameLoc,
- IndirectFieldDecl *indirectField,
- Expr *baseObjectExpr = 0,
- SourceLocation opLoc = SourceLocation());
+ BuildAnonymousStructUnionMemberReference(
+ const CXXScopeSpec &SS,
+ SourceLocation nameLoc,
+ IndirectFieldDecl *indirectField,
+ DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_none),
+ Expr *baseObjectExpr = 0,
+ SourceLocation opLoc = SourceLocation());
+
ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
LookupResult &R,
Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=186367&r1=186366&r2=186367&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Mon Jul 15 19:01:31 2013
@@ -703,6 +703,7 @@ ExprResult
Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
SourceLocation loc,
IndirectFieldDecl *indirectField,
+ DeclAccessPair foundDecl,
Expr *baseObjectExpr,
SourceLocation opLoc) {
// First, build the expression that refers to the base object.
@@ -780,15 +781,15 @@ Sema::BuildAnonymousStructUnionMemberRef
if (!baseVariable) {
FieldDecl *field = cast<FieldDecl>(*FI);
- // FIXME: use the real found-decl info!
- DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess());
-
// Make a nameInfo that properly uses the anonymous name.
DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer,
EmptySS, field, foundDecl,
memberNameInfo).take();
+ if (!result)
+ return ExprError();
+
baseObjectIsPointer = false;
// FIXME: check qualified member access
@@ -799,14 +800,15 @@ Sema::BuildAnonymousStructUnionMemberRef
while (FI != FEnd) {
FieldDecl *field = cast<FieldDecl>(*FI++);
-
+
// FIXME: these are somewhat meaningless
DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
- DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess());
-
+ DeclAccessPair fakeFoundDecl =
+ DeclAccessPair::make(field, field->getAccess());
+
result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false,
- (FI == FEnd? SS : EmptySS), field,
- foundDecl, memberNameInfo).take();
+ (FI == FEnd? SS : EmptySS), field,
+ fakeFoundDecl, memberNameInfo).take();
}
return Owned(result);
@@ -990,7 +992,8 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
// We may have found a field within an anonymous union or struct
// (C++ [class.union]).
return BuildAnonymousStructUnionMemberReference(SS, MemberLoc, FD,
- BaseExpr, OpLoc);
+ FoundDecl, BaseExpr,
+ OpLoc);
if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
@@ -1688,7 +1691,8 @@ Sema::BuildImplicitMemberExpr(const CXXS
// (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.begin().getPair());
// If this is known to be an instance access, go ahead and build an
// implicit 'this' expression now.
Modified: cfe/trunk/test/SemaCXX/anonymous-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/anonymous-union.cpp?rev=186367&r1=186366&r2=186367&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/anonymous-union.cpp (original)
+++ cfe/trunk/test/SemaCXX/anonymous-union.cpp Mon Jul 15 19:01:31 2013
@@ -197,3 +197,12 @@ namespace PR8326 {
Foo<int> baz;
}
+
+namespace PR16630 {
+ struct A { union { int x; float y; }; }; // expected-note {{member is declared here}}
+ struct B : private A { using A::x; } b; // expected-note 2 {{private}}
+ void foo () {
+ b.x = 10;
+ b.y = 0; // expected-error {{cannot cast 'struct B' to its private base class 'PR16630::A'}} expected-error {{'y' is a private member of 'PR16630::A'}}
+ }
+}
More information about the cfe-commits
mailing list