[cfe-commits] r109986 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/warn-global-constructors.cpp

John McCall rjmccall at apple.com
Sun Aug 1 14:51:45 PDT 2010


Author: rjmccall
Date: Sun Aug  1 16:51:45 2010
New Revision: 109986

URL: http://llvm.org/viewvc/llvm-project?rev=109986&view=rev
Log:
Kill off RequiresGlobalConstructor in favor of isConstantInitializer.
Note some obvious false positives in the test case.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/warn-global-constructors.cpp

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=109986&r1=109985&r2=109986&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sun Aug  1 16:51:45 2010
@@ -309,7 +309,7 @@
   }
   /// isConstantInitializer - Returns true if this expression is a constant
   /// initializer, which can be emitted at compile-time.
-  bool isConstantInitializer(ASTContext &Ctx) const; 
+  bool isConstantInitializer(ASTContext &Ctx) const;
 
   /// EvalResult is a struct with detailed info about an evaluated expression.
   struct EvalResult {

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=109986&r1=109985&r2=109986&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sun Aug  1 16:51:45 2010
@@ -1358,6 +1358,20 @@
   case ObjCStringLiteralClass:
   case ObjCEncodeExprClass:
     return true;
+  case CXXTemporaryObjectExprClass:
+  case CXXConstructExprClass: {
+    const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
+    if (!CE->getConstructor()->isTrivial()) return false;
+    for (CXXConstructExpr::const_arg_iterator
+           I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I)
+      if (!(*I)->isConstantInitializer(Ctx))
+        return false;
+    return true;
+  }
+  case CXXBindReferenceExprClass: {
+    const CXXBindReferenceExpr *RE = cast<CXXBindReferenceExpr>(this);
+    return RE->getSubExpr()->isConstantInitializer(Ctx);
+  }
   case CompoundLiteralExprClass: {
     // This handles gcc's extension that allows global initializers like
     // "struct x {int x;} x = (struct x) {};".
@@ -1397,6 +1411,7 @@
       return true;
     break;
   }
+  case CXXStaticCastExprClass:
   case ImplicitCastExprClass:
   case CStyleCastExprClass:
     // Handle casts with a destination that's a struct or union; this

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=109986&r1=109985&r2=109986&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Aug  1 16:51:45 2010
@@ -3866,57 +3866,6 @@
   AddInitializerToDecl(dcl, move(init), /*DirectInit=*/false);
 }
 
-/// Make a reasonable guess at whether the given initializer will
-/// require a global constructor.
-static bool RequiresGlobalConstructor(Sema &S, Expr *Init) {
-  // FIXME: reproducing the logic of CGExprConstant is kindof dumb.
-  // Maybe this should be integrated into the constant-evaluator?
-  // We'd need array and struct value types.
-  //
-  // It's probably okay to still warn in the theoretical cases where
-  // IR gen can eliminate a global constructor based on
-  // initialization order (not that it actually does that
-  // optimization at the moment).
-  if (Init->isEvaluatable(S.Context)) return false;
-
-  Init = Init->IgnoreParenNoopCasts(S.Context);
-
-  // Look through reference-bindings.
-  if (CXXBindReferenceExpr *BE = dyn_cast<CXXBindReferenceExpr>(Init))
-    return RequiresGlobalConstructor(S, BE);
-
-  // A constructor call needs a global constructor if:
-  if (CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(Init)) {
-    //  - the constructor is non-trivial
-    if (!CE->getConstructor()->isTrivial()) return true;
-
-    //  - any of the argument expressions needs a global constructor
-    for (CXXConstructExpr::arg_iterator
-           I = CE->arg_begin(), E = CE->arg_end(); I != E; ++I)
-      if (RequiresGlobalConstructor(S, *I))
-        return true;
-
-    // We don't have to worry about building temporaries with
-    // non-trivial destructors because we should never have walked
-    // through the CXXExprWithTemporaries.
-
-    // So it should be emitted as a constant expression.
-    return false;
-  }
-
-  /// An initializer list requires a global constructor if any of the
-  /// components do.
-  if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
-    for (unsigned I = 0, E = ILE->getNumInits(); I != E; ++I)
-      if (RequiresGlobalConstructor(S, ILE->getInit(I)))
-        return true;
-    return false;
-  }
-
-  // Assume everything else does.
-  return true;
-}
-
 /// AddInitializerToDecl - Adds the initializer Init to the
 /// declaration dcl. If DirectInit is true, this is C++ direct
 /// initialization rather than copy initialization.
@@ -4118,7 +4067,7 @@
   if (getLangOptions().CPlusPlus) {
     if (!VDecl->isInvalidDecl() &&
         !VDecl->getDeclContext()->isDependentContext() &&
-        VDecl->hasGlobalStorage() && RequiresGlobalConstructor(*this, Init))
+        VDecl->hasGlobalStorage() && !Init->isConstantInitializer(Context))
       Diag(VDecl->getLocation(), diag::warn_global_constructor);
 
     // Make sure we mark the destructor as used if necessary.
@@ -4332,7 +4281,7 @@
         if (getLangOptions().CPlusPlus && !Var->isInvalidDecl() && 
             Var->hasGlobalStorage() &&
             !Var->getDeclContext()->isDependentContext() &&
-            RequiresGlobalConstructor(*this, Var->getInit()))
+            !Var->getInit()->isConstantInitializer(Context))
           Diag(Var->getLocation(), diag::warn_global_constructor);
       }
     }

Modified: cfe/trunk/test/SemaCXX/warn-global-constructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-global-constructors.cpp?rev=109986&r1=109985&r2=109986&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-global-constructors.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-global-constructors.cpp Sun Aug  1 16:51:45 2010
@@ -29,6 +29,11 @@
   A a; // expected-warning {{global constructor}}
   A b[10]; // expected-warning {{global constructor}}
   A c[10][10]; // expected-warning {{global constructor}}
+
+  // FIXME: false positives!
+  A &d = a; // expected-warning {{global constructor}}
+  A &e = b[5]; // expected-warning {{global constructor}}
+  A &f = c[5][7]; // expected-warning {{global constructor}}
 }
 
 namespace test3 {
@@ -36,4 +41,15 @@
   A a; // expected-warning {{global destructor}}
   A b[10]; // expected-warning {{global destructor}}
   A c[10][10]; // expected-warning {{global destructor}}
+
+  // FIXME: false positives!
+  A &d = a; // expected-warning {{global constructor}}
+  A &e = b[5]; // expected-warning {{global constructor}}
+  A &f = c[5][7]; // expected-warning {{global constructor}}
+}
+
+namespace test4 {
+  char a[] = "hello";
+  char b[5] = "hello";
+  char c[][5] = { "hello" };
 }





More information about the cfe-commits mailing list