diff options
author | Richard Trieu <rtrieu@google.com> | 2012-10-03 00:41:36 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2012-10-03 00:41:36 +0000 |
commit | 6b2cc42f1504db6577fd67fa55ef023254744e2c (patch) | |
tree | fd66b4abce91aee016adb01510841d4c3eacebf6 /lib/Sema/SemaDecl.cpp | |
parent | 3d3f1f7c79c33a2e280dd289056ce68c95aa4cce (diff) |
Change how the SelfReferenceChecker handles MemberExpr. Instead of treating
each one separately, process a stack of MemberExpr's as a single unit so that
static calls and member access will not be warned on.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165074 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 50 |
1 files changed, 39 insertions, 11 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ddb41edc64..5a33230b2c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6276,6 +6276,20 @@ namespace { if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { HandleValue(CO->getTrueExpr()); HandleValue(CO->getFalseExpr()); + return; + } + + if (isa<MemberExpr>(E)) { + Expr *Base = E->IgnoreParenImpCasts(); + while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) { + // Check for static member variables and don't warn on them. + if (!isa<FieldDecl>(ME->getMemberDecl())) + return; + Base = ME->getBase()->IgnoreParenImpCasts(); + } + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) + HandleDeclRefExpr(DRE); + return; } } @@ -6287,7 +6301,7 @@ namespace { } void VisitImplicitCastExpr(ImplicitCastExpr *E) { - if ((!isRecordType && E->getCastKind() == CK_LValueToRValue) || + if (E->getCastKind() == CK_LValueToRValue || (isRecordType && E->getCastKind() == CK_NoOp)) HandleValue(E->getSubExpr()); @@ -6298,22 +6312,36 @@ namespace { // Don't warn on arrays since they can be treated as pointers. if (E->getType()->canDecayToPointerType()) return; - ValueDecl *VD = E->getMemberDecl(); - CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(VD); - if (isa<FieldDecl>(VD) || (MD && !MD->isStatic())) - if (DeclRefExpr *DRE - = dyn_cast<DeclRefExpr>(E->getBase()->IgnoreParenImpCasts())) { + // Warn when a non-static method call is followed by non-static member + // field accesses, which is followed by a DeclRefExpr. + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(E->getMemberDecl()); + bool Warn = (MD && !MD->isStatic()); + Expr *Base = E->getBase()->IgnoreParenImpCasts(); + while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) { + if (!isa<FieldDecl>(ME->getMemberDecl())) + Warn = false; + Base = ME->getBase()->IgnoreParenImpCasts(); + } + + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) { + if (Warn) HandleDeclRefExpr(DRE); - return; - } + return; + } - Inherited::VisitMemberExpr(E); + // The base of a MemberExpr is not a MemberExpr or a DeclRefExpr. + // Visit that expression. + Visit(Base); } void VisitUnaryOperator(UnaryOperator *E) { // For POD record types, addresses of its own members are well-defined. - if (E->getOpcode() == UO_AddrOf && isRecordType && isPODType && - isa<MemberExpr>(E->getSubExpr()->IgnoreParens())) return; + if (E->getOpcode() == UO_AddrOf && isRecordType && + isa<MemberExpr>(E->getSubExpr()->IgnoreParens())) { + if (!isPODType) + HandleValue(E->getSubExpr()); + return; + } Inherited::VisitUnaryOperator(E); } |