[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