From: Eric Fiselier Date: Sun, 8 Apr 2018 05:12:55 +0000 (+0000) Subject: [Sema] Remove dead code in BuildAnonymousStructUnionMemberReference. NFCI X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4faa6cefe24ab0f6b2a0b5a914d5969c4984c37c;p=clang [Sema] Remove dead code in BuildAnonymousStructUnionMemberReference. NFCI Summary: This patch cleans up a bunch of dead or unused code in BuildAnonymousStructUnionMemberReference. The dead code was a branch that built a new CXXThisExpr when we weren't given a base object expression or base variable. However, BuildAnonymousFoo has only two callers. One of which always builds a base object expression first, the second only calls when the IndirectFieldDecl is not a C++ class member. Even within C this branch seems entirely unused. I tried diligently to write a test which hit it with no success. This patch removes the branch and replaces it with an assertion that we were given either a base object expression or a base variable. Reviewers: rsmith, aaron.ballman, majnemer, rjmccall Reviewed By: rjmccall Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D45410 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@329518 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 522e4bbe07..c737d7bfd4 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -802,16 +802,13 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, Expr *baseObjectExpr, SourceLocation opLoc) { // First, build the expression that refers to the base object. - - bool baseObjectIsPointer = false; - Qualifiers baseQuals; - + // Case 1: the base of the indirect field is not a field. VarDecl *baseVariable = indirectField->getVarDecl(); CXXScopeSpec EmptySS; if (baseVariable) { assert(baseVariable->getType()->isRecordType()); - + // In principle we could have a member access expression that // accesses an anonymous struct/union that's a static member of // the base object's class. However, under the current standard, @@ -824,68 +821,37 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, ExprResult result = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable); if (result.isInvalid()) return ExprError(); - - baseObjectExpr = result.get(); - baseObjectIsPointer = false; - baseQuals = baseObjectExpr->getType().getQualifiers(); - - // Case 2: the base of the indirect field is a field and the user - // wrote a member expression. - } else if (baseObjectExpr) { - // The caller provided the base object expression. Determine - // whether its a pointer and whether it adds any qualifiers to the - // anonymous struct/union fields we're looking into. - QualType objectType = baseObjectExpr->getType(); - - if (const PointerType *ptr = objectType->getAs()) { - baseObjectIsPointer = true; - objectType = ptr->getPointeeType(); - } else { - baseObjectIsPointer = false; - } - baseQuals = objectType.getQualifiers(); - - // Case 3: the base of the indirect field is a field and we should - // build an implicit member access. - } else { - // We've found a member of an anonymous struct/union that is - // inside a non-anonymous struct/union, so in a well-formed - // program our base object expression is "this". - QualType ThisTy = getCurrentThisType(); - if (ThisTy.isNull()) { - Diag(loc, diag::err_invalid_member_use_in_static_method) - << indirectField->getDeclName(); - return ExprError(); - } - - // Our base object expression is "this". - CheckCXXThisCapture(loc); - baseObjectExpr - = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/ true); - baseObjectIsPointer = true; - baseQuals = ThisTy->castAs()->getPointeeType().getQualifiers(); + + baseObjectExpr = result.get(); } - + + assert((baseVariable || baseObjectExpr) && + "referencing anonymous struct/union without a base variable or " + "expression"); + // Build the implicit member references to the field of the // anonymous struct/union. Expr *result = baseObjectExpr; IndirectFieldDecl::chain_iterator FI = indirectField->chain_begin(), FEnd = indirectField->chain_end(); - - // Build the first member access in the chain with full information. + + // Case 2: the base of the indirect field is a field and the user + // wrote a member expression. if (!baseVariable) { FieldDecl *field = cast(*FI); - + + bool baseObjectIsPointer = baseObjectExpr->getType()->isPointerType(); + // Make a nameInfo that properly uses the anonymous name. DeclarationNameInfo memberNameInfo(field->getDeclName(), loc); - result = BuildFieldReferenceExpr(result, baseObjectIsPointer, - SourceLocation(), EmptySS, field, - foundDecl, memberNameInfo).get(); + // Build the first member access in the chain with full information. + result = + BuildFieldReferenceExpr(result, baseObjectIsPointer, SourceLocation(), + EmptySS, field, foundDecl, memberNameInfo) + .get(); if (!result) return ExprError(); - - // FIXME: check qualified member access } // In all cases, we should now skip the first declaration in the chain.