diff options
author | Richard Trieu <rtrieu@google.com> | 2012-05-09 00:21:34 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2012-05-09 00:21:34 +0000 |
commit | 7e9f8af453598292cb57ba8e4dd63b9a5814b9ac (patch) | |
tree | 0a3f112f1e1f205aeec962c5fb2f36aace771900 /lib/Sema/SemaDecl.cpp | |
parent | c472b2d8b730df46516a0847a0b61c6173485415 (diff) |
Update the SelfReferenceChecker. Refactored some of the visitor methods.
Added support for conditional operators and tightened the exclusion of the
unary operator from all operators to only the address of operator.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156450 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 500de928bf..fc37a25d8b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6083,55 +6083,73 @@ namespace { } } - void VisitExpr(Expr *E) { - if (isa<ObjCMessageExpr>(*E)) return; - if (isRecordType) { - Expr *expr = E; - if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { - ValueDecl *VD = ME->getMemberDecl(); - if (isa<EnumConstantDecl>(VD) || isa<VarDecl>(VD)) return; - expr = ME->getBase(); - } - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(expr)) { + // Sometimes, the expression passed in lacks the casts that are used + // to determine which DeclRefExpr's to check. Assume that the casts + // are present and continue visiting the expression. + void HandleExpr(Expr *E) { + // Skip checking T a = a where T is not a record type. Doing so is a + // way to silence uninitialized warnings. + if (isRecordType) + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) HandleDeclRefExpr(DRE); - return; - } + + if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { + HandleValue(CO->getTrueExpr()); + HandleValue(CO->getFalseExpr()); } - Inherited::VisitExpr(E); + + Visit(E); + } + + // For most expressions, the cast is directly above the DeclRefExpr. + // For conditional operators, the cast can be outside the conditional + // operator if both expressions are DeclRefExpr's. + void HandleValue(Expr *E) { + E = E->IgnoreParenImpCasts(); + if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(E)) { + HandleDeclRefExpr(DRE); + return; + } + + if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { + HandleValue(CO->getTrueExpr()); + HandleValue(CO->getFalseExpr()); + } + } + + void VisitImplicitCastExpr(ImplicitCastExpr *E) { + if ((!isRecordType && E->getCastKind() == CK_LValueToRValue) || + (isRecordType && E->getCastKind() == CK_NoOp)) + HandleValue(E->getSubExpr()); + + Inherited::VisitImplicitCastExpr(E); } void VisitMemberExpr(MemberExpr *E) { + // Don't warn on arrays since they can be treated as pointers. if (E->getType()->canDecayToPointerType()) return; + ValueDecl *VD = E->getMemberDecl(); - if (isa<FieldDecl>(VD) || isa<CXXMethodDecl>(VD)) + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(VD); + if (isa<FieldDecl>(VD) || (MD && !MD->isStatic())) if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getBase()->IgnoreParenImpCasts())) { HandleDeclRefExpr(DRE); return; } - Inherited::VisitMemberExpr(E); - } - void VisitImplicitCastExpr(ImplicitCastExpr *E) { - if ((!isRecordType &&E->getCastKind() == CK_LValueToRValue) || - (isRecordType && E->getCastKind() == CK_NoOp)) { - Expr* SubExpr = E->getSubExpr()->IgnoreParenImpCasts(); - if (MemberExpr *ME = dyn_cast<MemberExpr>(SubExpr)) - SubExpr = ME->getBase()->IgnoreParenImpCasts(); - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) { - HandleDeclRefExpr(DRE); - return; - } - } - Inherited::VisitImplicitCastExpr(E); + Inherited::VisitMemberExpr(E); } void VisitUnaryOperator(UnaryOperator *E) { // For POD record types, addresses of its own members are well-defined. - if (isRecordType && isPODType) return; + if (E->getOpcode() == UO_AddrOf && isRecordType && isPODType && + isa<MemberExpr>(E->getSubExpr())) return; Inherited::VisitUnaryOperator(E); } - + + void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; } + void HandleDeclRefExpr(DeclRefExpr *DRE) { Decl* ReferenceDecl = DRE->getDecl(); if (OrigDecl != ReferenceDecl) return; @@ -6148,7 +6166,7 @@ namespace { /// CheckSelfReference - Warns if OrigDecl is used in expression E. void Sema::CheckSelfReference(Decl* OrigDecl, Expr *E) { - SelfReferenceChecker(*this, OrigDecl).VisitExpr(E); + SelfReferenceChecker(*this, OrigDecl).HandleExpr(E); } /// AddInitializerToDecl - Adds the initializer Init to the |