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

Yury Gribov tetra2005 at gmail.com
Thu Jan 22 01:38:15 PST 2015


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/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7122.18596.patch
Type: text/x-patch
Size: 2618 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150122/60c2b3df/attachment.bin>


More information about the cfe-commits mailing list