[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
Ahmed Bougacha via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jun 18 18:26:16 PDT 2024
================
@@ -2074,16 +2091,91 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg,
if (convertArgumentToType(S, Arg, ExpectedTy))
return true;
- // Warn about null pointers for non-generic sign and auth operations.
- if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
- Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) {
- S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign
- ? diag::warn_ptrauth_sign_null_pointer
- : diag::warn_ptrauth_auth_null_pointer)
- << Arg->getSourceRange();
+ if (!RequireConstant) {
+ // Warn about null pointers for non-generic sign and auth operations.
+ if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
+ Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) {
+ S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign
+ ? diag::warn_ptrauth_sign_null_pointer
+ : diag::warn_ptrauth_auth_null_pointer)
+ << Arg->getSourceRange();
+ }
+
+ return false;
}
- return false;
+ // Perform special checking on the arguments to ptrauth_sign_constant.
+
+ // The main argument.
+ if (OpKind == PAO_Sign) {
+ // Require the value we're signing to have a special form.
+ auto BaseOffsetPair = findConstantBaseAndOffset(S, Arg);
+ bool Invalid;
+
+ // Must be rooted in a declaration reference.
+ if (!BaseOffsetPair.first) {
+ Invalid = true;
+
+ // If it's a function declaration, we can't have an offset.
+ } else if (isa<FunctionDecl>(BaseOffsetPair.first)) {
+ Invalid = !BaseOffsetPair.second.isZero();
+
+ // Otherwise we're fine.
+ } else {
+ Invalid = false;
+ }
+
+ if (Invalid) {
+ S.Diag(Arg->getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
+ }
+ return Invalid;
+ }
+
+ // The discriminator argument.
+ assert(OpKind == PAO_Discriminator);
+
+ // Must be a pointer or integer or blend thereof.
+ Expr *Pointer = nullptr;
+ Expr *Integer = nullptr;
+ if (auto *Call = dyn_cast<CallExpr>(Arg->IgnoreParens())) {
+ if (Call->getBuiltinCallee() ==
+ Builtin::BI__builtin_ptrauth_blend_discriminator) {
+ Pointer = Call->getArg(0);
+ Integer = Call->getArg(1);
+ }
+ }
+ if (!Pointer && !Integer) {
+ if (Arg->getType()->isPointerType())
+ Pointer = Arg;
+ else
+ Integer = Arg;
+ }
+
+ // Check the pointer.
+ bool Invalid = false;
+ if (Pointer) {
+ assert(Pointer->getType()->isPointerType());
+
+ // TODO: if we're initializing a global, check that the address is
+ // somehow related to what we're initializing. This probably will
+ // never really be feasible and we'll have to catch it at link-time.
+ auto BaseOffsetPair = findConstantBaseAndOffset(S, Pointer);
+ if (!BaseOffsetPair.first || !isa<VarDecl>(BaseOffsetPair.first)) {
+ Invalid = true;
----------------
ahmedbougacha wrote:
The missing base was covered, but the VarDecl check wasn't I think; I added tests where the discriminator is a function decl
https://github.com/llvm/llvm-project/pull/93904
More information about the llvm-branch-commits
mailing list