serge-sans-paille created this revision.
serge-sans-paille added reviewers: jfb, aaron.ballman.
Herald added a subscriber: jdoerfert.
Herald added a project: All.
serge-sans-paille requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This attribute would then affect all stack variables of that type, when the 
type has been evaluated as ok wrt. initialisation, or a for performance / 
security trade-offs.
An example of use could be container with preallocated storage like 
SmallVector, if we consider that it is too costly to initialize that storage.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156337

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
  clang/test/Misc/pragma-attribute-supported-attributes-list.test
  clang/test/Sema/attr-uninitialized.c

Index: clang/test/Sema/attr-uninitialized.c
===================================================================
--- clang/test/Sema/attr-uninitialized.c
+++ clang/test/Sema/attr-uninitialized.c
@@ -18,4 +18,4 @@
 
 struct TheWordIsOut {
   __attribute((uninitialized)) int youre_doin_wrong; // expected-warning {{'uninitialized' attribute only applies to local variables}}
-} __attribute((uninitialized));                      // expected-warning {{'uninitialized' attribute only applies to local variables}}
+} __attribute((uninitialized));
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
@@ -188,7 +188,7 @@
 // CHECK-NEXT: TargetVersion (SubjectMatchRule_function)
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
-// CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local)
+// CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local, SubjectMatchRule_record)
 // CHECK-NEXT: UnsafeBufferUsage (SubjectMatchRule_function)
 // CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: VecReturn (SubjectMatchRule_record)
Index: clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
===================================================================
--- clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
+++ clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
@@ -38,4 +38,24 @@
 }
 #pragma clang attribute pop
 
+struct [[clang::uninitialized]] uninitialized_record {
+  int i;
+};
+
+// UNINIT-LABEL:  test_record_attribute_uninitialized(
+// UNINIT:      alloca
+// UNINIT-NEXT: call void
+// ZERO-LABEL:    test_record_attribute_uninitialized(
+// ZERO:      alloca
+// ZERO-NOT:  !annotation
+// ZERO-NEXT: call void
+// PATTERN-LABEL: test_record_attribute_uninitialized(
+// PATTERN:      alloca
+// PATTERN-NOT:  !annotation
+// PATTERN-NEXT: call void
+void test_record_attribute_uninitialized() {
+  uninitialized_record some;
+  used(some);
+}
+
 } // extern "C"
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -8438,8 +8438,11 @@
 }
 
 static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
-  assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
-         "uninitialized is only valid on automatic duration variables");
+  assert(((isa<VarDecl>(D) &&
+           cast<VarDecl>(D)->getStorageDuration() == SD_Automatic) ||
+          isa<RecordDecl>(D)) &&
+         "uninitialized is only valid on automatic duration variables and "
+         "record type");
   D->addAttr(::new (S.Context) UninitializedAttr(S.Context, AL));
 }
 
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -1902,13 +1902,17 @@
   const Address Loc =
       locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr;
 
-  // Note: constexpr already initializes everything correctly.
-  LangOptions::TrivialAutoVarInitKind trivialAutoVarInit =
-      (D.isConstexpr()
-           ? LangOptions::TrivialAutoVarInitKind::Uninitialized
-           : (D.getAttr<UninitializedAttr>()
-                  ? LangOptions::TrivialAutoVarInitKind::Uninitialized
-                  : getContext().getLangOpts().getTrivialAutoVarInit()));
+  LangOptions::TrivialAutoVarInitKind trivialAutoVarInit;
+  if (D.isConstexpr())
+    // Note: constexpr already initializes everything correctly.
+    trivialAutoVarInit = LangOptions::TrivialAutoVarInitKind::Uninitialized;
+  else if (D.getAttr<UninitializedAttr>())
+    trivialAutoVarInit = LangOptions::TrivialAutoVarInitKind::Uninitialized;
+  else if (const auto *RecordTy = D.getType()->getAsRecordDecl();
+           RecordTy && RecordTy->hasAttr<UnusedAttr>())
+    trivialAutoVarInit = LangOptions::TrivialAutoVarInitKind::Uninitialized;
+  else
+    trivialAutoVarInit = getContext().getLangOpts().getTrivialAutoVarInit();
 
   auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
     if (trivialAutoVarInit ==
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -5782,8 +5782,10 @@
 The command-line parameter ``-ftrivial-auto-var-init=*`` can be used to
 initialize trivial automatic stack variables. By default, trivial automatic
 stack variables are uninitialized. This attribute is used to override the
-command-line parameter, forcing variables to remain uninitialized. It has no
-semantic meaning in that using uninitialized values is undefined behavior,
+command-line parameter, forcing variables to remain uninitialized.
+When set on a struct or class, all stack variables of this type are affected.
+
+It has no semantic meaning in that using uninitialized values is undefined behavior,
 it rather documents the programmer's intent.
   }];
 }
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -3960,7 +3960,7 @@
 
 def Uninitialized : InheritableAttr {
   let Spellings = [Clang<"uninitialized", 0>];
-  let Subjects = SubjectList<[LocalVar]>;
+  let Subjects = SubjectList<[LocalVar, Record]>;
   let PragmaAttributeSupport = 1;
   let Documentation = [UninitializedDocs];
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to