diff options
author | Richard Trieu <rtrieu@google.com> | 2014-10-01 03:44:58 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2014-10-01 03:44:58 +0000 |
commit | 2d779b984c6b25c5a3c0971fe3e62601b18da90d (patch) | |
tree | 29b47e820c828b708147ea1b3d3f4f8451abb6f4 /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 5f75f4ddb9b26612fa5517caf2bb16649ead921e (diff) | |
download | bcm5719-llvm-2d779b984c6b25c5a3c0971fe3e62601b18da90d.tar.gz bcm5719-llvm-2d779b984c6b25c5a3c0971fe3e62601b18da90d.zip |
Improve -Wuninitialized warnings for fields that are record types.
Get the record handling code from SelfReferenceChecker into
UninitializedFieldVisitor as well as copying the testcases.
llvm-svn: 218740
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 90 |
1 files changed, 59 insertions, 31 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 24d7c8f4172..b35bca2c84e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2221,7 +2221,8 @@ namespace { llvm::SmallPtrSetImpl<ValueDecl*> &Decls) : Inherited(S.Context), S(S), Decls(Decls) { } - void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly) { + void HandleMemberExpr(MemberExpr *ME, bool CheckReferenceOnly, + bool AddressOf) { if (isa<EnumConstantDecl>(ME->getMemberDecl())) return; @@ -2229,6 +2230,8 @@ namespace { // or union. MemberExpr *FieldME = ME; + bool AllPODFields = FieldME->getType().isPODType(S.Context); + Expr *Base = ME; while (isa<MemberExpr>(Base)) { ME = cast<MemberExpr>(Base); @@ -2240,12 +2243,18 @@ namespace { if (!FD->isAnonymousStructOrUnion()) FieldME = ME; - Base = ME->getBase(); + if (!FieldME->getType().isPODType(S.Context)) + AllPODFields = false; + + Base = ME->getBase()->IgnoreParenImpCasts(); } if (!isa<CXXThisExpr>(Base)) return; + if (AddressOf && AllPODFields) + return; + ValueDecl* FoundVD = FieldME->getMemberDecl(); if (!Decls.count(FoundVD)) @@ -2254,7 +2263,7 @@ namespace { const bool IsReference = FoundVD->getType()->isReferenceType(); // Prevent double warnings on use of unbounded references. - if (IsReference != CheckReferenceOnly) + if (CheckReferenceOnly && !IsReference) return; unsigned diag = IsReference @@ -2268,44 +2277,51 @@ namespace { } - void HandleValue(Expr *E) { + void HandleValue(Expr *E, bool AddressOf) { E = E->IgnoreParens(); if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { - HandleMemberExpr(ME, false /*CheckReferenceOnly*/); + HandleMemberExpr(ME, false /*CheckReferenceOnly*/, + AddressOf /*AddressOf*/); return; } if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { - HandleValue(CO->getTrueExpr()); - HandleValue(CO->getFalseExpr()); + Visit(CO->getCond()); + HandleValue(CO->getTrueExpr(), AddressOf); + HandleValue(CO->getFalseExpr(), AddressOf); return; } if (BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(E)) { - HandleValue(BCO->getFalseExpr()); + Visit(BCO->getCond()); + HandleValue(BCO->getFalseExpr(), AddressOf); return; } if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) { - HandleValue(OVE->getSourceExpr()); + HandleValue(OVE->getSourceExpr(), AddressOf); return; } if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { switch (BO->getOpcode()) { default: - return; + break; case(BO_PtrMemD): case(BO_PtrMemI): - HandleValue(BO->getLHS()); + HandleValue(BO->getLHS(), AddressOf); + Visit(BO->getRHS()); return; case(BO_Comma): - HandleValue(BO->getRHS()); + Visit(BO->getLHS()); + HandleValue(BO->getRHS(), AddressOf); return; } } + + Visit(E); } void CheckInitializer(Expr *E, const CXXConstructorDecl *FieldConstructor, @@ -2324,14 +2340,14 @@ namespace { void VisitMemberExpr(MemberExpr *ME) { // All uses of unbounded reference fields will warn. - HandleMemberExpr(ME, true /*CheckReferenceOnly*/); - - Inherited::VisitMemberExpr(ME); + HandleMemberExpr(ME, true /*CheckReferenceOnly*/, false /*AddressOf*/); } void VisitImplicitCastExpr(ImplicitCastExpr *E) { - if (E->getCastKind() == CK_LValueToRValue) - HandleValue(E->getSubExpr()); + if (E->getCastKind() == CK_LValueToRValue) { + HandleValue(E->getSubExpr(), false /*AddressOf*/); + return; + } Inherited::VisitImplicitCastExpr(E); } @@ -2339,23 +2355,24 @@ namespace { void VisitCXXConstructExpr(CXXConstructExpr *E) { if (E->getConstructor()->isCopyConstructor()) { Expr *ArgExpr = E->getArg(0); - if (ImplicitCastExpr* ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) { - if (ICE->getCastKind() == CK_NoOp) { + if (InitListExpr *ILE = dyn_cast<InitListExpr>(ArgExpr)) + if (ILE->getNumInits() == 1) + ArgExpr = ILE->getInit(0); + if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) + if (ICE->getCastKind() == CK_NoOp) ArgExpr = ICE->getSubExpr(); - } - } - - if (MemberExpr *ME = dyn_cast<MemberExpr>(ArgExpr)) { - HandleMemberExpr(ME, false /*CheckReferenceOnly*/); - } + HandleValue(ArgExpr, false /*AddressOf*/); + return; } Inherited::VisitCXXConstructExpr(E); } void VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { Expr *Callee = E->getCallee(); - if (isa<MemberExpr>(Callee)) - HandleValue(Callee); + if (isa<MemberExpr>(Callee)) { + HandleValue(Callee, false /*AddressOf*/); + return; + } Inherited::VisitCXXMemberCallExpr(E); } @@ -2365,7 +2382,8 @@ namespace { if (E->getNumArgs() == 1) { if (FunctionDecl *FD = E->getDirectCallee()) { if (FD->getIdentifier() && FD->getIdentifier()->isStr("move")) { - HandleValue(E->getArg(0)); + HandleValue(E->getArg(0), false /*AddressOf*/); + return; } } } @@ -2383,15 +2401,25 @@ namespace { DeclsToRemove.push_back(FD); if (E->isCompoundAssignmentOp()) { - HandleValue(E->getLHS()); + HandleValue(E->getLHS(), false /*AddressOf*/); + Visit(E->getRHS()); + return; } Inherited::VisitBinaryOperator(E); } void VisitUnaryOperator(UnaryOperator *E) { - if (E->isIncrementDecrementOp()) - HandleValue(E->getSubExpr()); + if (E->isIncrementDecrementOp()) { + HandleValue(E->getSubExpr(), false /*AddressOf*/); + return; + } + if (E->getOpcode() == UO_AddrOf) { + if (MemberExpr *ME = dyn_cast<MemberExpr>(E->getSubExpr())) { + HandleValue(ME->getBase(), true /*AddressOf*/); + return; + } + } Inherited::VisitUnaryOperator(E); } |