================
@@ -420,6 +420,222 @@ void 
CodeGenFunction::EmitPointerAuthCopy(PointerAuthQualifier Qual, QualType T,
   Builder.CreateStore(Value, DestAddress);
 }
 
+static const ConstantArrayType *tryGetTypeAsConstantArrayType(QualType T) {
+  if (!T->isConstantArrayType())
+    return nullptr;
+  return cast<ConstantArrayType>(T->castAsArrayTypeUnsafe());
+}
+
+using FixupErrorTy = std::pair<const CXXRecordDecl *, CXXBaseSpecifier>;
+class CodeGenFunction::FixupFinder {
+public:
+  using FixupVectorTy = CodeGenFunction::FixupVectorTy;
+  static FixupVectorTy findFixups(CodeGenFunction &CGF, QualType T) {
+    FixupFinder Finder(CGF);
+    FixupVectorTy Result;
+    Finder.findFixups(Result, T, CharUnits::Zero());
+    std::sort(Result.begin(), Result.end(),
+              [](const auto &L, const auto &R) { return L.Offset < R.Offset; 
});
+    return Result;
+  }
+
+private:
+  explicit FixupFinder(CodeGenFunction &CGF)
+      : CGF(CGF), Context(CGF.getContext()) {}
+
+  void findVTablePointerFixups(FixupVectorTy &Output, CXXRecordDecl *RD,
+                               CharUnits Offset) {
+    CodeGenFunction::VPtrsVector VPtrs = CGF.getVTablePointers(RD);
+    for (auto VPtr : VPtrs) {
+      std::optional<PointerAuthQualifier> PointerAuth =
+          CGF.CGM.getVTablePointerAuthentication(VPtr.Base.getBase());
+      if (PointerAuth && PointerAuth->isAddressDiscriminated())
+        Output.push_back(
+            {Offset + VPtr.Base.getBaseOffset(), KnownNonNull, *PointerAuth});
+    }
+  }
+  void findObjectFixups(FixupVectorTy &Output, CXXRecordDecl *RD,
+                        CharUnits Offset) {
+    if (RD->isPolymorphic())
+      findVTablePointerFixups(Output, RD, Offset);
+    findFixups(Output, RD, Offset, /*SubobjectIsBase=*/true);
+  }
+
+  void findFixups(FixupVectorTy &Output, CXXRecordDecl *RD,
+                  CharUnits SubobjectOffset, bool SubobjectIsBase) {
+    // If we've found a union it by definition cannot contain
+    // address discriminated fields.
+    if (RD->isUnion())
+      return;
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    if (Layout.hasOwnVFPtr() && RD == Layout.getPrimaryBase())
+      findVTablePointerFixups(Output, RD, SubobjectOffset);
+
+    for (auto Base : RD->bases()) {
+      CXXRecordDecl *BaseDecl =
+          Base.getType()->getAsCXXRecordDecl()->getDefinition();
+      assert(!Base.isVirtual());
+      CharUnits BaseOffset = Layout.getBaseClassOffset(BaseDecl);
+      findFixups(Output, BaseDecl, SubobjectOffset + BaseOffset,
+                 /*SubobjectIsBase=*/true);
+    }
+
+    for (const FieldDecl *Field : RD->fields()) {
+      if (Field->isBitField())
+        continue;
+      unsigned FieldBitOffset = Layout.getFieldOffset(Field->getFieldIndex());
+      CharUnits FieldOffset = Context.toCharUnitsFromBits(FieldBitOffset);
+      findFixups(Output, Field->getType(), SubobjectOffset + FieldOffset);
+    }
+  }
+  void findFixups(FixupVectorTy &Output, QualType T, CharUnits Offset) {
+    T = T.getCanonicalType();
+    if (!Context.containsAddressDiscriminatedPointerAuth(T))
+      return;
+
+    if (const ConstantArrayType *CAT = tryGetTypeAsConstantArrayType(T)) {
+      if (CAT->getSize() == 0)
+        return;
+      Output.push_back({Offset, CAT});
+      return;
+    }
+
+    if (PointerAuthQualifier Q = T.getPointerAuth();
+        Q && Q.isAddressDiscriminated()) {
+      // FIXME: Would it be reasonable to consider nullability?
+      Output.push_back({Offset, NotKnownNonNull, Q});
----------------
ojhunt wrote:

I think this is a reasonable question, but it would also turn an incorrectly 
null value become a runtime error?

https://github.com/llvm/llvm-project/pull/144420
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to