[PATCH] SemaDeclCXX.cpp: Make -Wglobal-constructors more forgiving.

Nico Weber thakis at chromium.org
Thu Jan 22 08:38:45 PST 2015


You can't know that all compilers will optimize this away, can you?

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
> 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/f56b8835/attachment.html>


More information about the cfe-commits mailing list