diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-11-01 04:52:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-11-01 04:52:12 +0000 |
commit | a31174efe0c4c7c2547ecdd52f6e4d4e1027213d (patch) | |
tree | 2c860494f5338048a9f68dbbb65cc8583ea3eb93 | |
parent | 057a942d9e8441016f33134e4534846b0fa785d9 (diff) | |
download | bcm5719-llvm-a31174efe0c4c7c2547ecdd52f6e4d4e1027213d.tar.gz bcm5719-llvm-a31174efe0c4c7c2547ecdd52f6e4d4e1027213d.zip |
Fix -Wunused-private-field to fire regardless of which implicit special members have been implicitly declared.
llvm-svn: 317076
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/unused.cpp | 2 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unused-private-field.cpp | 17 |
4 files changed, 23 insertions, 3 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 58bca426770..31400e1de89 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -737,7 +737,8 @@ static bool MethodsAndNestedClassesComplete(const CXXRecordDecl *RD, E = RD->decls_end(); I != E && Complete; ++I) { if (const CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(*I)) - Complete = M->isDefined() || (M->isPure() && !isa<CXXDestructorDecl>(M)); + Complete = M->isDefined() || M->isDefaulted() || + (M->isPure() && !isa<CXXDestructorDecl>(M)); else if (const FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(*I)) // If the template function is marked as late template parsed at this // point, it has not been instantiated and therefore we have not diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index bf4cb53b7d8..03ddcc0a3ec 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1791,7 +1791,9 @@ Sema::BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, MemberType = Context.getQualifiedType(MemberType, Combined); } - UnusedPrivateFields.remove(Field); + auto *CurMethod = dyn_cast<CXXMethodDecl>(CurContext); + if (!(CurMethod && CurMethod->isDefaulted())) + UnusedPrivateFields.remove(Field); ExprResult Base = PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(), FoundDecl, Field); diff --git a/clang/test/SemaCXX/unused.cpp b/clang/test/SemaCXX/unused.cpp index ba9ab2363b0..abaf611b0df 100644 --- a/clang/test/SemaCXX/unused.cpp +++ b/clang/test/SemaCXX/unused.cpp @@ -6,7 +6,7 @@ // PR4103 : Make sure we don't get a bogus unused expression warning namespace PR4103 { class APInt { - char foo; + char foo; // expected-warning {{private field 'foo' is not used}} }; class APSInt : public APInt { char bar; // expected-warning {{private field 'bar' is not used}} diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp index fb34fa98eaf..fe44122a1d0 100644 --- a/clang/test/SemaCXX/warn-unused-private-field.cpp +++ b/clang/test/SemaCXX/warn-unused-private-field.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s class NotFullyDefined { public: @@ -246,3 +247,19 @@ namespace pr13543 { X x[4]; // no-warning }; } + +class implicit_special_member { +public: + static implicit_special_member make() { return implicit_special_member(); } + +private: + int n; // expected-warning{{private field 'n' is not used}} +}; + +class defaulted_special_member { +public: + defaulted_special_member(const defaulted_special_member&) = default; + +private: + int n; // expected-warning{{private field 'n' is not used}} +}; |