Skip to content

[PAC][Driver] Support pauthtest ABI for AArch64 Linux triples #97237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
StringRef AArch64TargetInfo::getABI() const { return ABI; }

bool AArch64TargetInfo::setABI(const std::string &Name) {
if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs")
if (Name != "aapcs" && Name != "aapcs-soft" && Name != "darwinpcs" &&
Name != "pauthtest")
return false;

ABI = Name;
Expand All @@ -218,6 +219,12 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const {
Diags.Report(diag::err_target_unsupported_abi_with_fpu) << ABI;
return false;
}
if (getTriple().getEnvironment() == llvm::Triple::PAuthTest &&
getTriple().getOS() != llvm::Triple::Linux) {
Diags.Report(diag::err_target_unsupported_abi_for_triple)
<< getTriple().getEnvironmentName() << getTriple().getTriple();
return false;
}
return true;
}

Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64);
else if (Target.getABI() == "aapcs-soft")
Kind = AArch64ABIKind::AAPCSSoft;
else if (Target.getABI() == "pauthtest")
Kind = AArch64ABIKind::PAuthTest;

return createAArch64TargetCodeGenInfo(CGM, Kind);
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ enum class AArch64ABIKind {
DarwinPCS,
Win64,
AAPCSSoft,
PAuthTest,
};

std::unique_ptr<TargetCodeGenInfo>
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1031,11 +1031,12 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
}
case llvm::Triple::aarch64: {
llvm::Triple Triple = getTriple();
tools::aarch64::setPAuthABIInTriple(getDriver(), Args, Triple);
if (!Triple.isOSBinFormatMachO())
return getTripleString();
return Triple.getTriple();

if (Triple.isArm64e())
return getTripleString();
return Triple.getTriple();

// FIXME: older versions of ld64 expect the "arm64" component in the actual
// triple string and query it to determine whether an LTO file can be
Expand Down
21 changes: 21 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,24 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
Features.push_back("+no-bti-at-return-twice");
}

void aarch64::setPAuthABIInTriple(const Driver &D, const ArgList &Args,
llvm::Triple &Triple) {
Arg *ABIArg = Args.getLastArg(options::OPT_mabi_EQ);
bool HasPAuthABI =
ABIArg ? (StringRef(ABIArg->getValue()) == "pauthtest") : false;

switch (Triple.getEnvironment()) {
case llvm::Triple::UnknownEnvironment:
if (HasPAuthABI)
Triple.setEnvironment(llvm::Triple::PAuthTest);
break;
case llvm::Triple::PAuthTest:
break;
default:
if (HasPAuthABI)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< ABIArg->getAsString(Args) << Triple.getTriple();
break;
}
}
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple,
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple, llvm::opt::Arg *&A);

void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args,
llvm::Triple &triple);

} // end namespace aarch64
} // end namespace target
} // end namespace driver
Expand Down
60 changes: 57 additions & 3 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,41 @@ void AddUnalignedAccessWarning(ArgStringList &CmdArgs) {
}
}

// Each combination of options here forms a signing schema, and in most cases
// each signing schema is its own incompatible ABI. The default values of the
// options represent the default signing schema.
static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) {
if (!DriverArgs.hasArg(options::OPT_fptrauth_intrinsics,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See addOptInFlag.

But the implementation seems quite different from the title/description.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See addOptInFlag.

Do you mean that we need to replace

  if (!DriverArgs.hasArg(options::OPT_fptrauth_xxx,
                         options::OPT_fno_ptrauth_xxx))
    CC1Args.push_back("-fptrauth-xxx");

with

  DriverArgs.addOptInFlag(CC1Args, options::OPT_fptrauth_xxx,
                          options::OPT_fno_ptrauth_xxx);

...?

If so, this does not look correct - addOptInFlag would add the flag present (if any) in DriverArgs to CC1Args, but we want to append a list of ptrauth flags to cc1 args unconditionally if pauthabi is passed as branch protection.

Do I miss smth? I suppose I might have misunderstood you point.

But the implementation seems quite different from the title/description.

Hmm, it actually looks consistent to me, the implementation seems matching the description from my point of view - we want to add a bunch of arguments with -mbranch-protection=pauthabi used as a shortcut, we do that. Could you please describe what is inconsistent between description and implementation in a bit more detail?

options::OPT_fno_ptrauth_intrinsics))
CC1Args.push_back("-fptrauth-intrinsics");

if (!DriverArgs.hasArg(options::OPT_fptrauth_calls,
options::OPT_fno_ptrauth_calls))
CC1Args.push_back("-fptrauth-calls");

if (!DriverArgs.hasArg(options::OPT_fptrauth_returns,
options::OPT_fno_ptrauth_returns))
CC1Args.push_back("-fptrauth-returns");

if (!DriverArgs.hasArg(options::OPT_fptrauth_auth_traps,
options::OPT_fno_ptrauth_auth_traps))
CC1Args.push_back("-fptrauth-auth-traps");

if (!DriverArgs.hasArg(
options::OPT_fptrauth_vtable_pointer_address_discrimination,
options::OPT_fno_ptrauth_vtable_pointer_address_discrimination))
CC1Args.push_back("-fptrauth-vtable-pointer-address-discrimination");

if (!DriverArgs.hasArg(
options::OPT_fptrauth_vtable_pointer_type_discrimination,
options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");

if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini,
options::OPT_fno_ptrauth_init_fini))
CC1Args.push_back("-fptrauth-init-fini");
}

static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs, bool isAArch64) {
const Arg *A = isAArch64
Expand Down Expand Up @@ -1546,16 +1581,30 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args,

CmdArgs.push_back(
Args.MakeArgString(Twine("-msign-return-address=") + Scope));
if (Scope != "none")
if (Scope != "none") {
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << Triple.getTriple();
CmdArgs.push_back(
Args.MakeArgString(Twine("-msign-return-address-key=") + Key));
if (BranchProtectionPAuthLR)
}
if (BranchProtectionPAuthLR) {
if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << Triple.getTriple();
CmdArgs.push_back(
Args.MakeArgString(Twine("-mbranch-protection-pauth-lr")));
}
if (IndirectBranches)
CmdArgs.push_back("-mbranch-target-enforce");
if (GuardedControlStack)
// GCS is currently untested with PAuthABI, but enabling this could be allowed
// in future after testing with a suitable system.
if (GuardedControlStack) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GuardedControlStack should be compatible with PAuthABI but there won't be hardware available for some time so we could retrospectively support it later after testing it.

Perhaps worth a comment that GCS is untested with PAuthABI, but could be enabled after testing with a suitable system.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment, thanks! See 4f3da9e

if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << Triple.getTriple();
CmdArgs.push_back("-mguarded-control-stack");
}
}

void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args,
Expand Down Expand Up @@ -1699,6 +1748,8 @@ void RenderAArch64ABI(const llvm::Triple &Triple, const ArgList &Args,
ABIName = A->getValue();
else if (Triple.isOSDarwin())
ABIName = "darwinpcs";
else if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
ABIName = "pauthtest";
else
ABIName = "aapcs";

Expand Down Expand Up @@ -1735,6 +1786,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
// Enable/disable return address signing and indirect branch targets.
CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/);

if (Triple.getEnvironment() == llvm::Triple::PAuthTest)
handlePAuthABI(Args, CmdArgs);

// Handle -msve_vector_bits=<bits>
if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
StringRef Val = A->getValue();
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ std::string Linux::getMultiarchTriple(const Driver &D,
case llvm::Triple::aarch64:
if (IsAndroid)
return "aarch64-linux-android";
if (hasEffectiveTriple() &&
getEffectiveTriple().getEnvironment() == llvm::Triple::PAuthTest)
return "aarch64-linux-pauthtest";
return "aarch64-linux-gnu";
case llvm::Triple::aarch64_be:
return "aarch64_be-linux-gnu";
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Driver/aarch64-multilib-pauthabi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// RUN: %clang --target=aarch64-linux-pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks this is not used: "clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep"
BTW we could just add to the test:
rm -rf %t.dir && mkdir -p %t.dir/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/ && mkdir -p %t.dir/multilib_aarch64_linux_tree/usr/include/aarch64-linux-pauthtest/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks this is not used: "clang/test/Driver/Inputs/multilib_aarch64_linux_tree/usr/include/aarch64-linux-gnu/.keep"

It's not directly used in this test, but I've added that in order to have a choice between two directories (one with default triple, one with pauthtest) and check that the pauthtest directory is chosen. Is this considered unneeded?

BTW we could just add to the test

Yes, that's possible, thanks for suggestion! But I've followed convention with already present multilib_arm_linux_tree (see clang/test/Driver/arm-multilibs.c test). I'm not sure what's better - stick with old existing conventions or not clutter source tree with empty directories which can be created on demand during test. So, I'll leave this "as is" currently and change this if there are more requests.

If you actually have a strong preference for not keeping empty multilib folders in source tree and just creating directories during test - please let me know.

// RUN: %clang --target=aarch64-linux -mabi=pauthtest --sysroot=%S/Inputs/multilib_aarch64_linux_tree -### -c %s 2>&1 | FileCheck %s

// CHECK: "-internal-externc-isystem" "{{.*}}/usr/include/aarch64-linux-pauthtest"
85 changes: 76 additions & 9 deletions clang/test/Driver/aarch64-ptrauth.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// REQUIRES: aarch64-registered-target

// RUN: %clang -### -c --target=aarch64 %s 2>&1 | FileCheck %s --check-prefix NONE
// NONE: "-cc1"
// NONE: "-cc1"
// NONE-NOT: "-fptrauth-

// RUN: %clang -### -c --target=aarch64 \
Expand All @@ -13,13 +15,78 @@
// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL
// ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"

// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1
// RUN: %clang -### -c --target=aarch64-linux-pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1
// PAUTHABI1: "-cc1"{{.*}} "-triple" "aarch64-unknown-linux-pauthtest"
// PAUTHABI1-SAME: "-target-abi" "pauthtest"
// PAUTHABI1-SAME: "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-init-fini"

// RUN: %clang -### -c --target=aarch64 -mabi=pauthtest -fno-ptrauth-intrinsics \
// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
// RUN: %clang -### -c --target=aarch64-pauthtest -fno-ptrauth-intrinsics \
// RUN: -fno-ptrauth-calls -fno-ptrauth-returns -fno-ptrauth-auth-traps \
// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fno-ptrauth-vtable-pointer-type-discrimination \
// RUN: -fno-ptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2
// PAUTHABI2: "-cc1"
// PAUTHABI2-NOT: "-fptrauth-

// RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \
// RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \
// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR
// ERR: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
// ERR-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
// ERR-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
// ERR-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
// ERR-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
// ERR-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'
// RUN: -fptrauth-init-fini %s 2>&1 | FileCheck %s --check-prefix=ERR1
// ERR1: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}'
// ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}'
// ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}'
// ERR1-NEXT: error: unsupported option '-fptrauth-auth-traps' for target '{{.*}}'
// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-address-discrimination' for target '{{.*}}'
// ERR1-NEXT: error: unsupported option '-fptrauth-vtable-pointer-type-discrimination' for target '{{.*}}'
// ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}'

//// Only support PAuth ABI for Linux as for now.
// RUN: not %clang -c --target=aarch64-unknown -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2
// RUN: not %clang -c --target=aarch64-unknown-pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2
// ERR2: error: ABI 'pauthtest' is not supported for 'aarch64-unknown-unknown-pauthtest'

//// PAuth ABI is encoded as environment part of the triple, so don't allow to explicitly set other environments.
// RUN: not %clang -c --target=aarch64-linux-gnu -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR3
// ERR3: error: unsupported option '-mabi=pauthtest' for target 'aarch64-unknown-linux-gnu'
// RUN: %clang -c --target=aarch64-linux-pauthtest -mabi=pauthtest %s

//// The only branch protection option compatible with PAuthABI is BTI.
// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=pac-ret %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR4
// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=pac-ret %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR4
// ERR4: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest'

// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=gcs %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR5
// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=gcs %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR5
// ERR5: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest'

// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=standard %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR6
// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=standard %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR6
// ERR6: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest'

// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=all %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR7
// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=all %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR7
// ERR7: error: unsupported option '-msign-return-address=all' for target 'aarch64-unknown-linux-pauthtest'

// RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=non-leaf %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR8
// RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=non-leaf %s 2>&1 | \
// RUN: FileCheck %s --check-prefix=ERR8
// ERR8: error: unsupported option '-msign-return-address=non-leaf' for target 'aarch64-unknown-linux-pauthtest'

// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=none %s
// RUN: %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=none %s
// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=bti %s
// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=bti %s
// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=none %s
// RUN: %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=none %s
6 changes: 4 additions & 2 deletions llvm/include/llvm/TargetParser/Triple.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class Triple {
Cygnus,
CoreCLR,
Simulator, // Simulator variants of other systems, e.g., Apple's iOS
MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
MacABI, // Mac Catalyst variant of Apple's iOS deployment target.

// Shader Stages
// The order of these values matters, and must be kept in sync with the
Expand All @@ -292,7 +292,9 @@ class Triple {
OpenCL,
OpenHOS,

LastEnvironmentType = OpenHOS
PAuthTest,

LastEnvironmentType = PAuthTest
};
enum ObjectFormatType {
UnknownObjectFormat,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/TargetParser/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case OpenCL:
return "opencl";
case OpenHOS: return "ohos";
case PAuthTest:
return "pauthtest";
}

llvm_unreachable("Invalid EnvironmentType!");
Expand Down Expand Up @@ -728,6 +730,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
.StartsWith("amplification", Triple::Amplification)
.StartsWith("opencl", Triple::OpenCL)
.StartsWith("ohos", Triple::OpenHOS)
.StartsWith("pauthtest", Triple::PAuthTest)
.Default(Triple::UnknownEnvironment);
}

Expand Down
6 changes: 6 additions & 0 deletions llvm/unittests/TargetParser/TripleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,12 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::Serenity, T.getOS());
EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());

T = Triple("aarch64-unknown-linux-pauthtest");
EXPECT_EQ(Triple::aarch64, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::Linux, T.getOS());
EXPECT_EQ(Triple::PAuthTest, T.getEnvironment());

T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
}
Expand Down