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