From: Argyrios Kyrtzidis Date: Sun, 15 Aug 2010 10:17:33 +0000 (+0000) Subject: Don't warn for the common pattern of disallowing copying: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=06999f8ff61de3c63a52871bd7ac61e7ada9180b;p=clang Don't warn for the common pattern of disallowing copying: class S { S(const S&); // DO NOT IMPLEMENT void operator=(const S&); // DO NOT IMPLEMENT }; git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111100 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ea65c8cf30..3271997e0e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -521,6 +521,24 @@ static void RemoveUsingDecls(LookupResult &R) { F.done(); } +/// \brief Check for this common pattern: +/// @code +/// class S { +/// S(const S&); // DO NOT IMPLEMENT +/// void operator=(const S&); // DO NOT IMPLEMENT +/// }; +/// @endcode +static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) { + // FIXME: Should check for private access too but access is set after we get + // the decl here. + if (D->isThisDeclarationADefinition()) + return false; + + if (const CXXConstructorDecl *CD = dyn_cast(D)) + return CD->isCopyConstructor(); + return D->isCopyAssignment(); +} + bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { assert(D); @@ -536,23 +554,23 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { return false; if (const FunctionDecl *FD = dyn_cast(D)) { - if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) - return false; + if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) + return false; - if (const CXXMethodDecl *MD = dyn_cast(FD)) { - if (MD->isVirtual()) - return false; - } else { - // 'static inline' functions are used in headers; don't warn. - if (FD->getStorageClass() == FunctionDecl::Static && - FD->isInlineSpecified()) - return false; - } + if (const CXXMethodDecl *MD = dyn_cast(FD)) { + if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD)) + return false; + } else { + // 'static inline' functions are used in headers; don't warn. + if (FD->getStorageClass() == FunctionDecl::Static && + FD->isInlineSpecified()) + return false; + } if (FD->isThisDeclarationADefinition()) return !Context.DeclMustBeEmitted(FD); return true; - } + } if (const VarDecl *VD = dyn_cast(D)) { if (VD->isStaticDataMember() && diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp index b51aedc54a..50d41422d3 100644 --- a/test/SemaCXX/warn-unused-filescoped.cpp +++ b/test/SemaCXX/warn-unused-filescoped.cpp @@ -11,6 +11,8 @@ namespace { void m1() { } // expected-warning{{unused}} void m2(); // expected-warning{{unused}} void m3(); + S(const S&); + void operator=(const S&); }; template