[clang] [PAC] Add support for __ptrauth type qualifier (PR #100830)

Daniil Kovalev via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 2 01:12:57 PDT 2024


================
@@ -166,6 +193,92 @@ CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) {
   return ::getPointerAuthInfoForType(*this, T);
 }
 
+static std::pair<llvm::Value *, CGPointerAuthInfo>
+emitLoadOfOrigPointerRValue(CodeGenFunction &CGF, const LValue &LV,
+                            SourceLocation Loc) {
+  auto *Value = CGF.EmitLoadOfScalar(LV, Loc);
+  CGPointerAuthInfo AuthInfo;
+  if (PointerAuthQualifier PtrAuth = LV.getQuals().getPointerAuth()) {
+    AuthInfo = CGF.EmitPointerAuthInfo(PtrAuth, LV.getAddress());
+  } else {
+    AuthInfo = getPointerAuthInfoForType(CGF.CGM, LV.getType());
+  }
+  return {Value, AuthInfo};
+}
+
+/// Retrieve a pointer rvalue and its ptrauth info. When possible, avoid
+/// needlessly resigning the pointer.
+std::pair<llvm::Value *, CGPointerAuthInfo>
+CodeGenFunction::EmitOrigPointerRValue(const Expr *E) {
+  assert(E->getType()->isSignableType());
+
+  E = E->IgnoreParens();
+  if (auto *Load = dyn_cast<ImplicitCastExpr>(E)) {
+    if (Load->getCastKind() == CK_LValueToRValue) {
+      E = Load->getSubExpr()->IgnoreParens();
+
+      // We're semantically required to not emit loads of certain DREs naively.
+      if (auto *RefExpr = dyn_cast<DeclRefExpr>(const_cast<Expr *>(E))) {
+        if (auto Result = tryEmitAsConstant(RefExpr)) {
+          // Fold away a use of an intermediate variable.
+          if (!Result.isReference())
+            return {Result.getValue(),
+                    getPointerAuthInfoForType(CGM, RefExpr->getType())};
+
+          // Fold away a use of an intermediate reference.
+          auto LV = Result.getReferenceLValue(*this, RefExpr);
+          return emitLoadOfOrigPointerRValue(*this, LV, RefExpr->getLocation());
+        }
+      }
+
+      // Otherwise, load and use the pointer
+      auto LV = EmitCheckedLValue(E, CodeGenFunction::TCK_Load);
+      return emitLoadOfOrigPointerRValue(*this, LV, E->getExprLoc());
+    }
+  }
+
+  // Fallback: just use the normal rules for the type.
+  auto *Value = EmitScalarExpr(E);
+  return {Value, getPointerAuthInfoForType(CGM, E->getType())};
+}
+
+llvm::Value *
+CodeGenFunction::EmitPointerAuthQualify(PointerAuthQualifier DestQualifier,
+                                        const Expr *E,
+                                        Address DestStorageAddress) {
+  assert(DestQualifier);
+
+  auto Src = EmitOrigPointerRValue(E);
+  auto *Value = Src.first;
+  auto CurAuthInfo = Src.second;
----------------
kovdan01 wrote:

Nit: you could probably just you structured bindings

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


More information about the cfe-commits mailing list