[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 30 10:29:10 PDT 2024


================
@@ -268,6 +268,69 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
   updateStringLiteralType(Str, DeclT);
 }
 
+template <class Predicate, class RecordFilter>
+std::enable_if_t<std::is_void_v<decltype(std::declval<Predicate &>()(
+                     std::declval<const FieldDecl *>()))>,
+                 size_t>
+forEachFieldRecursive(const RecordDecl *Record, Predicate FieldPred,
+                      RecordFilter RecordPreFilter) {
+  size_t NumFound = 0;
+  SmallVector<const RecordDecl *> Stack;
+  llvm::SmallDenseSet<const RecordDecl *> Seen;
+  Stack.push_back(Record);
+  while (!Stack.empty()) {
+    const RecordDecl *RD = Stack.back();
+    Stack.pop_back();
+    const size_t OldStackSize = Stack.size();
+    if (RD) {
+      RD = dyn_cast_if_present<RecordDecl>(RD->getCanonicalDecl());
+    }
+    if (RD && Seen.insert(RD).second && RecordPreFilter(RD)) {
+      for (const FieldDecl *Field : RD->fields()) {
+        FieldPred(Field);
+        ++NumFound;
+        QualType FieldType = Field->getType();
+        if (!FieldType.isNull()) {
+          const RecordDecl *FieldRD = FieldType->getAsRecordDecl();
+          if (FieldRD && !Seen.contains(FieldRD) && RecordPreFilter(FieldRD)) {
+            Stack.push_back(FieldRD);
+          }
+        }
+      }
+      if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+        CXXRD->forallBases([&](const CXXRecordDecl *Base) {
+          if (Base) {
+            Base = Base->getCanonicalDecl();
+          }
+          if (Base && !Seen.contains(Base) && RecordPreFilter(Base)) {
+            Stack.push_back(Base);
+          }
+          return true;
+        });
+      }
+    }
+    // Preserve push order when popping
+    std::reverse(Stack.begin() + OldStackSize, Stack.end());
+  }
+  return NumFound;
+}
+
+size_t emitUninitializedExplicitInitFields(Sema &S, const RecordDecl *R) {
----------------
erichkeane wrote:

What is the return value used for here?

https://github.com/llvm/llvm-project/pull/102040


More information about the cfe-commits mailing list