JonChesterfield updated this revision to Diff 247156.
JonChesterfield added a comment.

- clang-format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74361/new/

https://reviews.llvm.org/D74361

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/AST/DeclBase.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGenCXX/attr-no-zero-initializer.cpp
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/attr-no-zero-initializer.cpp

Index: clang/test/Sema/attr-no-zero-initializer.cpp
===================================================================
--- /dev/null
+++ clang/test/Sema/attr-no-zero-initializer.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int good __attribute__((no_zero_initializer));
+const int still_cant_be_const __attribute__((no_zero_initializer)); // expected-error {{default initialization of an object of const type}}
+extern int external __attribute__((no_zero_initializer));
+
+void func() __attribute__((no_zero_initializer)) // expected-warning {{'no_zero_initializer' attribute only applies to global variables}}
+{
+  int local __attribute__((no_zero_initializer)); // expected-warning {{'no_zero_initializer' attribute only applies to global variables}}
+
+  static int sl __attribute__((no_zero_initializer));
+}
+
+struct s {
+  __attribute__((no_zero_initializer)) int field; // expected-warning {{'no_zero_initializer' attribute only applies to global variables}}
+
+  static __attribute__((no_zero_initializer)) int sfield;
+
+} __attribute__((no_zero_initializer)); // expected-warning {{'no_zero_initializer' attribute only applies to global variables}}
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -94,6 +94,7 @@
 // CHECK-NEXT: NoStackProtector (SubjectMatchRule_function)
 // CHECK-NEXT: NoThreadSafetyAnalysis (SubjectMatchRule_function)
 // CHECK-NEXT: NoThrow (SubjectMatchRule_hasType_functionType)
+// CHECK-NEXT: NoZeroInitializer (SubjectMatchRule_variable_is_global)
 // CHECK-NEXT: NotTailCalled (SubjectMatchRule_function)
 // CHECK-NEXT: OSConsumed (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: OSReturnsNotRetained (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_variable_is_parameter)
Index: clang/test/CodeGenCXX/attr-no-zero-initializer.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/attr-no-zero-initializer.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: @_ZZ4funcvE4data = internal global i32 undef
+int* func(void)
+{
+  static int data [[clang::no_zero_initializer]];
+  return &data;
+}
+
+// No code emitted
+extern int extern_unhelpful_but_harmless [[clang::no_zero_initializer]];
+
+// CHECK: @tentative = global i32 undef
+int tentative  [[clang::no_zero_initializer]];
+
+// CHECK: @_ZL16tentative_static = internal global i32 undef
+static int tentative_static [[clang::no_zero_initializer]] __attribute__((used));
+
+// CHECK: @nominally_zero_init = global i32 undef
+int nominally_zero_init  [[clang::no_zero_initializer]] = 0;
+
+// CHECK: @nominally_value_init = global i32 undef
+int nominally_value_init  [[clang::no_zero_initializer]] = 4;
+
+class trivial
+{
+  float x;
+};
+
+// CHECK: @ut = global %class.trivial undef
+trivial ut [[clang::no_zero_initializer]];
+
+struct nontrivial
+{
+  nontrivial() : x(3.14) {}
+  double x;
+};
+
+// CHECK: @unt = global %struct.nontrivial undef
+nontrivial unt [[clang::no_zero_initializer]];
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -6505,6 +6505,11 @@
   D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
 }
 
+static void handleNoZeroInitializerAttr(Sema &S, Decl *D,
+                                        const ParsedAttr &AL) {
+  D->addAttr(::new (S.Context) NoZeroInitializerAttr(S.Context, AL));
+}
+
 static bool tryMakeVariablePseudoStrong(Sema &S, VarDecl *VD,
                                         bool DiagnoseFailure) {
   QualType Ty = VD->getType();
@@ -7427,6 +7432,10 @@
     handleUninitializedAttr(S, D, AL);
     break;
 
+  case ParsedAttr::AT_NoZeroInitializer:
+    handleNoZeroInitializerAttr(S, D, AL);
+    break;
+
   case ParsedAttr::AT_ObjCExternallyRetained:
     handleObjCExternallyRetainedAttr(S, D, AL);
     break;
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -3942,6 +3942,8 @@
   if (getLangOpts().CUDA &&
       (IsCUDASharedVar || IsCUDAShadowVar || IsHIPPinnedShadowVar))
     Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy));
+  else if (D->hasAttr<NoZeroInitializerAttr>())
+    Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy));
   else if (!InitExpr) {
     // This is a tentative definition; tentative definitions are
     // implicitly initialized with { 0 }.
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -249,7 +249,7 @@
   // variables cannot have an initializer.
   llvm::Constant *Init = nullptr;
   if (Ty.getAddressSpace() == LangAS::opencl_local ||
-      D.hasAttr<CUDASharedAttr>())
+      D.hasAttr<CUDASharedAttr>() || D.hasAttr<NoZeroInitializerAttr>())
     Init = llvm::UndefValue::get(LTy);
   else
     Init = EmitNullConstant(Ty);
Index: clang/lib/AST/DeclBase.cpp
===================================================================
--- clang/lib/AST/DeclBase.cpp
+++ clang/lib/AST/DeclBase.cpp
@@ -454,7 +454,8 @@
 }
 
 bool Decl::hasDefiningAttr() const {
-  return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
+  return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>() ||
+         hasAttr<NoZeroInitializerAttr>();
 }
 
 const Attr *Decl::getDefiningAttr() const {
@@ -462,6 +463,8 @@
     return AA;
   if (auto *IFA = getAttr<IFuncAttr>())
     return IFA;
+  if (auto *NZA = getAttr<NoZeroInitializerAttr>())
+    return NZA;  
   return nullptr;
 }
 
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -3430,6 +3430,12 @@
   let Documentation = [UninitializedDocs];
 }
 
+def NoZeroInitializer : InheritableAttr {
+  let Spellings = [Clang<"no_zero_initializer">];
+  let Subjects = SubjectList<[GlobalVar]>;
+  let Documentation = [Undocumented];
+}
+  
 def ObjCExternallyRetained : InheritableAttr {
   let LangOpts = [ObjCAutoRefCount];
   let Spellings = [Clang<"objc_externally_retained">];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to