From 76a11f8abd26c4c3d5f90f201962122b7b6d3e84 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 18 Feb 2011 02:44:58 +0000 Subject: [PATCH] When building a qualified reference to a member of an anonymous struct or union, place the qualifier on the outermost member reference expression, which actually contains the entity name. Fixes PR9188/. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125822 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExpr.cpp | 13 +++++++------ test/SemaTemplate/instantiate-anonymous-union.cpp | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2b1b8b290..92e671165 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1004,6 +1004,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, // Case 1: the base of the indirect field is not a field. VarDecl *baseVariable = indirectField->getVarDecl(); + CXXScopeSpec EmptySS; if (baseVariable) { assert(baseVariable->getType()->isRecordType()); @@ -1017,7 +1018,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, DeclarationNameInfo baseNameInfo(DeclarationName(), loc); ExprResult result = - BuildDeclarationNameExpr(SS, baseNameInfo, baseVariable); + BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable); if (result.isInvalid()) return ExprError(); baseObjectExpr = result.take(); @@ -1078,7 +1079,7 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer, - SS, field, foundDecl, + EmptySS, field, foundDecl, memberNameInfo).take(); baseObjectIsPointer = false; @@ -1088,16 +1089,16 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, // In all cases, we should now skip the first declaration in the chain. ++FI; - for (; FI != FEnd; FI++) { - FieldDecl *field = cast(*FI); + while (FI != FEnd) { + FieldDecl *field = cast(*FI++); // FIXME: these are somewhat meaningless DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess()); - CXXScopeSpec memberSS; result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false, - memberSS, field, foundDecl, memberNameInfo) + (FI == FEnd? SS : EmptySS), field, + foundDecl, memberNameInfo) .take(); } diff --git a/test/SemaTemplate/instantiate-anonymous-union.cpp b/test/SemaTemplate/instantiate-anonymous-union.cpp index f2862db6b..68b233a7f 100644 --- a/test/SemaTemplate/instantiate-anonymous-union.cpp +++ b/test/SemaTemplate/instantiate-anonymous-union.cpp @@ -66,3 +66,24 @@ namespace PR7402 { X x(42.0); } + +namespace PR9188 { + struct X0 { + union { + int member; + }; + }; + + static union { + int global; + }; + + struct X1 : X0 { + template + int f() { + return this->X0::member + PR9188::global; + } + }; + + template int X1::f(); +} -- 2.11.4.GIT