]> granicus.if.org Git - clang/commitdiff
Internal-linkage variables with constant-evaluatable initializers do not need to...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 19 Aug 2015 20:49:38 +0000 (20:49 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 19 Aug 2015 20:49:38 +0000 (20:49 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245497 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
test/CodeGen/block-with-perdefinedexpr.c
test/CodeGenCXX/const-init-cxx11.cpp
test/CodeGenCXX/dllimport.cpp
test/CodeGenCXX/typeid-cxx11.cpp
test/CodeGenObjC/local-static-block.m
test/PCH/check-deserializations.cpp

index 192120abf1b3c77d5d4e36024401a36e2679dbf6..f679377b84526a91a710de0f3806a6efa82103b9 100644 (file)
@@ -8311,6 +8311,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
     // Global named register variables (GNU extension) are never emitted.
     if (VD->getStorageClass() == SC_Register)
       return false;
+    if (VD->getDescribedVarTemplate() ||
+        isa<VarTemplatePartialSpecializationDecl>(VD))
+      return false;
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // We never need to emit an uninstantiated function template.
     if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
@@ -8383,7 +8386,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
     return true;
 
   // Variables that have initialization with side-effects are required.
-  if (VD->getInit() && VD->getInit()->HasSideEffects(*this))
+  if (VD->getInit() && VD->getInit()->HasSideEffects(*this) &&
+      !VD->evaluateValue())
     return true;
 
   return false;
index 68fdea60f3796d97b45dd545ff13afde542d5e4e..94d67c3b93b5429f2afe216884daaa4d532d8357 100644 (file)
@@ -5,6 +5,7 @@ void syslog(const char *, ...);
 
 void handler( );
 
+__attribute__((used))
 static void (^spd)() = ^()
 {
  handler( ^(){ syslog("%s", __FUNCTION__); } );
index 5127c302aa0d217f5f2c87f5d205f5d33e778822..99be265e21267a7542cf398c0f2e6bf60a0fef2e 100644 (file)
@@ -350,6 +350,7 @@ namespace VirtualMembers {
     virtual void f();
   };
   // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i64 0, i64 2) }
+  __attribute__((used))
   static nsMemoryImpl sGlobalMemory;
 
   template<class T>
index da8fb8d3802d200e29e3454318b0031f52fa634b..c87d959c5b35782d1615750dbccc4dd150bf3c38 100644 (file)
@@ -581,7 +581,7 @@ struct __declspec(dllimport) KeyFuncClass {
   constexpr KeyFuncClass() {}
   virtual void foo();
 };
-constexpr KeyFuncClass keyFuncClassVar;
+extern constexpr KeyFuncClass keyFuncClassVar = {};
 // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
 
 struct __declspec(dllimport) X : public virtual W {};
index 4e32d2dcb5a527b130b92e95a58e3d837c2d3e38..5c10ca5b21a5d069609654357ac9c7aceac3098d 100644 (file)
@@ -18,8 +18,8 @@ struct A { virtual ~A(); };
 struct B : virtual A {};
 struct C { int n; };
 
-// CHECK: @_ZN5Test1L5itemsE = internal constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }]
-constexpr Item items[] = {
+// CHECK: @_ZN5Test15itemsE = constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }]
+extern constexpr Item items[] = {
   item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
 };
 
index b55cc6af4d65d291f3b967aa8ec98a92d4973978..73c670f5c925935beeefbc13f1b81ed9fe2bfc62 100644 (file)
@@ -14,8 +14,13 @@ static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSA
   return (NSArray *)0;
 };
 
+extern NSArray *address;
+extern unsigned long level;
+
 void FUNC()
 {
+ ArrayRecurs(address, level);
+
  static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
 
   for(id rawAddress in addresses)
@@ -25,6 +30,7 @@ void FUNC()
   }
   return (NSArray *)0;
  };
+ ArrayRecurs(address, level);
 
  if (ArrayRecurs) {
    static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
@@ -36,6 +42,7 @@ void FUNC()
      }
      return (NSArray *)0;
    };
+   ArrayRecurs(address, level);
  }
 }
 
@@ -50,8 +57,9 @@ void FUNC1()
   }
   return (NSArray *)0;
  };
+ ArrayRecurs(address, level);
 }
 // CHECK-LP64: @ArrayRecurs = internal global
 // CHECK-LP64: @FUNC.ArrayRecurs = internal global
-// CHECK-LP64: @FUNC.ArrayRecurs.3 = internal global
+// CHECK-LP64: @FUNC.ArrayRecurs.1 = internal global
 // CHECK-LP64: @FUNC1.ArrayRecurs = internal global
index e24d20549385d7e945cf5dcf95c498c06d38eb10..50c84c89d1cd1544dd31698b657d26b3e1f578e9 100644 (file)
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-pch -o %t.1 %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_keyfunc -error-on-deserialized-decl S3 -include-pch %t.1 -emit-pch -o %t.2 %s
-// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_method -error-on-deserialized-decl S3 -include-pch %t.2 -emit-llvm-only %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -emit-pch -o %t.1 %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_keyfunc -error-on-deserialized-decl S3 -error-on-deserialized-decl DND -std=c++11 -include-pch %t.1 -emit-pch -o %t.2 %s
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -error-on-deserialized-decl S1_method -error-on-deserialized-decl S3 -error-on-deserialized-decl DND -std=c++11 -include-pch %t.2 -emit-llvm-only %s
 
 // FIXME: Why does this require an x86 target?
 // REQUIRES: x86-registered-target
@@ -20,6 +20,15 @@ struct S2 {
   operator S3();
 };
 
+namespace vars {
+  constexpr int f() { return 0; }
+  struct X { constexpr X() {} };
+  namespace v1 { const int DND = 0; }
+  namespace v2 { constexpr int DND = f(); }
+  namespace v3 { static X DND; }
+  namespace v4 { constexpr X DND = {}; }
+}
+
 #elif !defined(HEADER2)
 #define HEADER2