diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2012-11-15 08:19:20 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2012-11-15 08:19:20 +0000 |
commit | 621ba4f0dba0accdf67fb38e98bbe14db22ddf8e (patch) | |
tree | 93e43356c8293ce353791c1a6bd3f6be53075bc1 /lib/Sema/SemaDeclCXX.cpp | |
parent | 931c0833811c030884fa50b2ccbd3c34f0f4c4ee (diff) |
Teach the uninitialized field warning about anonymous structs and union members.
Fixes PR14073!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168031 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 2c760f4930..a8ddc51f3f 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1795,7 +1795,11 @@ namespace { public: typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited; UninitializedFieldVisitor(Sema &S, ValueDecl *VD) : Inherited(S.Context), - S(S), VD(VD) { + S(S) { + if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(VD)) + this->VD = IFD->getAnonField(); + else + this->VD = VD; } void HandleExpr(Expr *E) { @@ -1812,23 +1816,33 @@ namespace { if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) { if (isa<EnumConstantDecl>(ME->getMemberDecl())) - return; + return; + + // FieldME is the inner-most MemberExpr that is not an anonymous struct + // or union. + MemberExpr *FieldME = ME; + Expr *Base = E; while (isa<MemberExpr>(Base)) { - ME = dyn_cast<MemberExpr>(Base); - if (VarDecl *VarD = dyn_cast<VarDecl>(ME->getMemberDecl())) - if (VarD->hasGlobalStorage()) - return; + ME = cast<MemberExpr>(Base); + + if (isa<VarDecl>(ME->getMemberDecl())) + return; + + if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) + if (!FD->isAnonymousStructOrUnion()) + FieldME = ME; + Base = ME->getBase(); } - if (VD == ME->getMemberDecl() && isa<CXXThisExpr>(Base)) { + if (VD == FieldME->getMemberDecl() && isa<CXXThisExpr>(Base)) { unsigned diag = VD->getType()->isReferenceType() ? diag::warn_reference_field_is_uninit : diag::warn_field_is_uninit; - S.Diag(ME->getExprLoc(), diag) << ME->getMemberNameInfo().getName(); - return; + S.Diag(FieldME->getExprLoc(), diag) << VD; } + return; } if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { |