Implement target(branch-protection) attribute for AArch64
This patch implements `__attribute__((target("branch-protection=...")))`
in a manner, compatible with the analogous GCC feature:
https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/AArch64-Function-Attributes.html#AArch64-Function-Attributes
Differential Revision: https://reviews.llvm.org/D68711
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index b139f8a..ec848a3 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -5056,23 +5056,38 @@
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
if (!FD)
return;
- llvm::Function *Fn = cast<llvm::Function>(GV);
- auto Kind = CGM.getCodeGenOpts().getSignReturnAddress();
- if (Kind != CodeGenOptions::SignReturnAddressScope::None) {
+ CodeGenOptions::SignReturnAddressScope Scope = CGM.getCodeGenOpts().getSignReturnAddress();
+ CodeGenOptions::SignReturnAddressKeyValue Key = CGM.getCodeGenOpts().getSignReturnAddressKey();
+ bool BranchTargetEnforcement = CGM.getCodeGenOpts().BranchTargetEnforcement;
+ if (const auto *TA = FD->getAttr<TargetAttr>()) {
+ TargetAttr::ParsedTargetAttr Attr = TA->parse();
+ if (!Attr.BranchProtection.empty()) {
+ TargetInfo::BranchProtectionInfo BPI;
+ StringRef Error;
+ (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection,
+ BPI, Error);
+ assert(Error.empty());
+ Scope = BPI.SignReturnAddr;
+ Key = BPI.SignKey;
+ BranchTargetEnforcement = BPI.BranchTargetEnforcement;
+ }
+ }
+
+ auto *Fn = cast<llvm::Function>(GV);
+ if (Scope != CodeGenOptions::SignReturnAddressScope::None) {
Fn->addFnAttr("sign-return-address",
- Kind == CodeGenOptions::SignReturnAddressScope::All
+ Scope == CodeGenOptions::SignReturnAddressScope::All
? "all"
: "non-leaf");
- auto Key = CGM.getCodeGenOpts().getSignReturnAddressKey();
Fn->addFnAttr("sign-return-address-key",
Key == CodeGenOptions::SignReturnAddressKeyValue::AKey
? "a_key"
: "b_key");
}
- if (CGM.getCodeGenOpts().BranchTargetEnforcement)
+ if (BranchTargetEnforcement)
Fn->addFnAttr("branch-target-enforcement");
}
};