[PATCH] SemaDeclCXX.cpp: Make -Wglobal-constructors more forgiving.
David Blaikie
dblaikie at gmail.com
Thu Jan 22 09:39:21 PST 2015
On Thu, Jan 22, 2015 at 1:38 AM, Yury Gribov <tetra2005 at gmail.com> wrote:
> Hi rsmith, eli.friedman,
>
> This patch liberalizes -Wglobal-constructors to not emit warning if
> constructor is likely to be optimized away. This covers important
> LinkerInitialized idiom used e.g. in libsanitizer and Chromium:
> enum LinkerInitialized { LINKER_INITIALIZED };
> class Mutex {
> public:
> inline Mutex(base::LinkerInitialized) {}
> };
> Mutex mu(LINKER_INITIALIZED); // Will be optimized away
>
While this is probably a useful improvement to C++98 code, is there any
reason this code couldn't use C++11's constexpr instead? (which I think
would already not produce the warning without needing to change the
compiler)
> No regressions in check-all.
>
> http://reviews.llvm.org/D7122
>
> Files:
> lib/Sema/SemaDecl.cpp
> test/SemaCXX/warn-global-constructors.cpp
>
> Index: lib/Sema/SemaDecl.cpp
> ===================================================================
> --- lib/Sema/SemaDecl.cpp
> +++ lib/Sema/SemaDecl.cpp
> @@ -9523,18 +9523,34 @@
>
> if (!var->getDeclContext()->isDependentContext() &&
> Init && !Init->isValueDependent()) {
> - if (IsGlobal && !var->isConstexpr() &&
> - !getDiagnostics().isIgnored(diag::warn_global_constructor,
> - var->getLocation())) {
> + do {
> + if (!IsGlobal || var->isConstexpr() ||
> + getDiagnostics().isIgnored(diag::warn_global_constructor,
> + var->getLocation()))
> + break;
> +
> // Warn about globals which don't have a constant initializer.
> Don't
> // warn about globals with a non-trivial destructor because we
> already
> // warned about them.
> CXXRecordDecl *RD = baseType->getAsCXXRecordDecl();
> - if (!(RD && !RD->hasTrivialDestructor()) &&
> - !Init->isConstantInitializer(Context,
> baseType->isReferenceType()))
> - Diag(var->getLocation(), diag::warn_global_constructor)
> - << Init->getSourceRange();
> - }
> + if ((RD && !RD->hasTrivialDestructor()) ||
> + Init->isConstantInitializer(Context,
> baseType->isReferenceType()))
> + break;
> +
> + CXXConstructExpr *CtorInit =
> dyn_cast_or_null<CXXConstructExpr>(Init);
> + if (CtorInit) {
> + // Do not warn if constructor will likely generate no code.
> + CXXConstructorDecl *CtorDecl = CtorInit->getConstructor();
> + Stmt *CtorBody = CtorDecl->getBody();
> + bool HasEmptyBody = CtorBody && CtorDecl->isDefined() &&
> cast<CompoundStmt>(CtorBody)->body_empty();
> + bool HasNoInitializers = !CtorDecl->getNumCtorInitializers();
> + if (HasEmptyBody && HasNoInitializers)
> + break;
> + }
> +
> + Diag(var->getLocation(), diag::warn_global_constructor)
> + << Init->getSourceRange();
> + } while(0);
>
> if (var->isConstexpr()) {
> SmallVector<PartialDiagnosticAt, 8> Notes;
> Index: test/SemaCXX/warn-global-constructors.cpp
> ===================================================================
> --- test/SemaCXX/warn-global-constructors.cpp
> +++ test/SemaCXX/warn-global-constructors.cpp
> @@ -121,6 +121,18 @@
> E e;
> }
>
> +namespace LinkerInitialized {
> + enum LinkerInitialized { LINKER_INITIALIZED = 0 };
> +
> + struct BlockingMutex {
> + BlockingMutex(LinkerInitialized) {}
> + BlockingMutex() {}
> + char owner_;
> + };
> +
> + BlockingMutex mu(LINKER_INITIALIZED); // elided
> +}
> +
> namespace pr20420 {
> // No warning is expected. This used to crash.
> void *array_storage[1];
>
> EMAIL PREFERENCES
> http://reviews.llvm.org/settings/panel/emailpreferences/
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150122/02838019/attachment.html>
More information about the cfe-commits
mailing list