[clang] [Clang][RISCV] Add preprocessor macros for Zicfilp CFI scheme (PR #109600)

Ming-Yi Lai via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 24 04:09:19 PDT 2024


https://github.com/mylai-mtk updated https://github.com/llvm/llvm-project/pull/109600

>From 0068ec08f28e2197a4982f876052f577988acd61 Mon Sep 17 00:00:00 2001
From: Ming-Yi Lai <ming-yi.lai at mediatek.com>
Date: Wed, 4 Sep 2024 18:40:48 +0800
Subject: [PATCH 1/2] [clang][RISCV] Introduce command line options for
 Zicfilp-backed forward-edge CFI

This patch enables the following command line flags for RISC-V targets:

+ `-fcf-protection=branch` turns on forward-edge control-flow integrity conditioning on RISC-V targets with Zicfilp extension
+ `-mcf-branch-label-scheme=unlabeled|func-sig` selects the label scheme used in the forward-edge CFI conditioning
---
 .../include/clang/Basic/CFProtectionOptions.h | 22 +++++++
 clang/include/clang/Basic/CodeGenOptions.def  |  2 +
 clang/include/clang/Basic/CodeGenOptions.h    |  1 +
 clang/include/clang/Basic/LangOptions.def     |  2 +
 clang/include/clang/Basic/LangOptions.h       |  2 +
 clang/include/clang/Basic/TargetInfo.h        |  4 ++
 clang/include/clang/Driver/Options.td         |  4 ++
 clang/lib/Basic/TargetInfo.cpp                |  5 ++
 clang/lib/Basic/Targets/RISCV.h               | 11 ++++
 clang/lib/Driver/ToolChains/Clang.cpp         |  4 ++
 clang/lib/Frontend/CompilerInvocation.cpp     | 36 ++++++++++++
 .../test/CodeGen/RISCV/riscv-cf-protection.c  | 58 +++++++++++++++++++
 12 files changed, 151 insertions(+)
 create mode 100644 clang/include/clang/Basic/CFProtectionOptions.h
 create mode 100644 clang/test/CodeGen/RISCV/riscv-cf-protection.c

diff --git a/clang/include/clang/Basic/CFProtectionOptions.h b/clang/include/clang/Basic/CFProtectionOptions.h
new file mode 100644
index 00000000000000..d97f8489c4631f
--- /dev/null
+++ b/clang/include/clang/Basic/CFProtectionOptions.h
@@ -0,0 +1,22 @@
+//===--- CFProtectionOptions.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines constants for -fcf-protection and other related flags.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H
+#define LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H
+
+namespace clang {
+
+enum class CFBranchLabelSchemeKind { Default, Unlabeled, FuncSig };
+
+} // namespace clang
+
+#endif // #ifndef LLVM_CLANG_BASIC_CFPROTECTIONOPTIONS_H
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index b600198998d85b..de7ae73f8a603b 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -110,6 +110,8 @@ CODEGENOPT(CFProtectionReturn , 1, 0) ///< if -fcf-protection is
                                       ///< set to full or return.
 CODEGENOPT(CFProtectionBranch , 1, 0) ///< if -fcf-protection is
                                       ///< set to full or branch.
+ENUM_CODEGENOPT(CFBranchLabelScheme, CFBranchLabelSchemeKind, 2,
+    CFBranchLabelSchemeKind::Default) ///< if -mcf-branch-label-scheme is set.
 CODEGENOPT(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern}
 CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix
                                          ///< is set.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index f2a707a8ba8d76..a6953c17a447ef 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H
 #define LLVM_CLANG_BASIC_CODEGENOPTIONS_H
 
+#include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/PointerAuthOptions.h"
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/XRayInstr.h"
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index fd3346d29f26a3..68db400c22e6c1 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -364,6 +364,8 @@ BENIGN_LANGOPT(CompatibilityQualifiedIdBlockParamTypeChecking, 1, 0,
 LANGOPT(ObjCDisableDirectMethodsForTesting, 1, 0,
         "Disable recognition of objc_direct methods")
 LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled")
+ENUM_LANGOPT(CFBranchLabelScheme, CFBranchLabelSchemeKind, 2, CFBranchLabelSchemeKind::Default,
+             "Control-Flow Branch Protection Label Scheme")
 LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
 ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode")
 LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL")
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 6c186c410e158d..c3d53ca92d450c 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
 #define LLVM_CLANG_BASIC_LANGOPTIONS_H
 
+#include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CommentOptions.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangStandard.h"
@@ -73,6 +74,7 @@ class LangOptionsBase {
 public:
   using Visibility = clang::Visibility;
   using RoundingMode = llvm::RoundingMode;
+  using CFBranchLabelSchemeKind = clang::CFBranchLabelSchemeKind;
 
   enum GCMode { NonGC, GCOnly, HybridGC };
   enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index f31d88a354ea28..d96a4fcca56840 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
+#include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -1727,6 +1728,9 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual bool
   checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
 
+  /// Get the target default CFBranchLabelScheme scheme
+  virtual CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const;
+
   /// Check if the target supports CFProtection return.
   virtual bool
   checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 002f60350543d9..ccbe302e4937e1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2841,6 +2841,10 @@ def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>,
   Visibility<[ClangOption, CLOption, CC1Option]>,
   Alias<fcf_protection_EQ>, AliasArgs<["full"]>,
   HelpText<"Enable cf-protection in 'full' mode">;
+def mcf_branch_label_scheme_EQ : Joined<["-"], "mcf-branch-label-scheme=">,
+  Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
+  HelpText<"Select label scheme for branch control-flow architecture protection">,
+  Values<"unlabeled,func-sig">;
 def mfunction_return_EQ : Joined<["-"], "mfunction-return=">,
   Group<m_Group>, Visibility<[ClangOption, CLOption, CC1Option]>,
   HelpText<"Replace returns with jumps to ``__x86_return_thunk`` (x86 only, error otherwise)">,
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 29f5cd14e46e11..8dfd10984ce685 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -192,6 +192,11 @@ void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) {
   UserLabelPrefix = ULP;
 }
 
+CFBranchLabelSchemeKind TargetInfo::getDefaultCFBranchLabelScheme() const {
+  // if this hook is called, the target should override it
+  llvm::report_fatal_error("not implemented");
+}
+
 bool
 TargetInfo::checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const {
   Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 351ef21e197c4d..ec0d0bba69eb9f 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -134,6 +134,17 @@ class RISCVTargetInfo : public TargetInfo {
 
   bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
                                       bool &HasSizeMismatch) const override;
+
+  bool
+  checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const override {
+    if (ISAInfo->hasExtension("zicfilp"))
+      return true;
+    return TargetInfo::checkCFProtectionBranchSupported(Diags);
+  }
+
+  CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const override {
+    return CFBranchLabelSchemeKind::FuncSig;
+  }
 };
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 0bab48caf1a5e2..d3c5c3d9872ee4 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7012,6 +7012,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) {
     CmdArgs.push_back(
         Args.MakeArgString(Twine("-fcf-protection=") + A->getValue()));
+
+    if (Arg *SA = Args.getLastArg(options::OPT_mcf_branch_label_scheme_EQ))
+      CmdArgs.push_back(Args.MakeArgString(Twine("-mcf-branch-label-scheme=") +
+                                           SA->getValue()));
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ))
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index efd852593468aa..ec49e0234ac8b0 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1688,6 +1688,19 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
   else if (Opts.CFProtectionBranch)
     GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");
 
+  if (Opts.CFProtectionBranch) {
+    switch (Opts.getCFBranchLabelScheme()) {
+    case CFBranchLabelSchemeKind::Default:
+      break;
+    case CFBranchLabelSchemeKind::Unlabeled:
+      GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, "unlabeled");
+      break;
+    case CFBranchLabelSchemeKind::FuncSig:
+      GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, "func-sig");
+      break;
+    }
+  }
+
   if (Opts.FunctionReturnThunks)
     GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");
 
@@ -2022,6 +2035,19 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
       Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
   }
 
+  if (Opts.CFProtectionBranch && T.isRISCV()) {
+    if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
+      const StringRef Scheme = A->getValue();
+      if (Scheme == "unlabeled")
+        Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::Unlabeled);
+      else if (Scheme == "func-sig")
+        Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::FuncSig);
+      else
+        Diags.Report(diag::err_drv_invalid_value)
+            << A->getAsString(Args) << Scheme;
+    }
+  }
+
   if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
     auto Val = llvm::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
                    .Case("keep", llvm::FunctionReturnThunksKind::Keep)
@@ -3952,6 +3978,16 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
     }
   }
 
+  if (Opts.CFProtectionBranch) {
+    if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
+      const StringRef Scheme = A->getValue();
+      if (Scheme == "unlabeled")
+        Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::Unlabeled);
+      else if (Scheme == "func-sig")
+        Opts.setCFBranchLabelScheme(CFBranchLabelSchemeKind::FuncSig);
+    }
+  }
+
   if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
       !Args.hasArg(OPT_sycl_std_EQ)) {
     // If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
diff --git a/clang/test/CodeGen/RISCV/riscv-cf-protection.c b/clang/test/CodeGen/RISCV/riscv-cf-protection.c
new file mode 100644
index 00000000000000..02a22006b1638f
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-cf-protection.c
@@ -0,0 +1,58 @@
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+
+// RUN: not %clang --target=riscv32 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=unlabeled -c %s -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s
+
+// RUN: not %clang --target=riscv32 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=func-sig -c %s -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s
+
+// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=unlabeled -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=func-sig -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+
+// RUN: not %clang --target=riscv64 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=unlabeled -c %s -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s
+
+// RUN: not %clang --target=riscv64 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=func-sig -c %s -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s
+
+// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=unlabeled -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=func-sig -c %s \
+// RUN:   -o /dev/null 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+
+// CHECK-BRANCH-PROT-INVALID: error: option 'cf-protection=branch' cannot be
+// CHECK-BRANCH-PROT-INVALID-SAME: specified on this target
+// CHECK-UNLABELED-SCHEME-UNUSED: warning: argument unused during compilation:
+// CHECK-UNLABELED-SCHEME-UNUSED-SAME: '-mcf-branch-label-scheme=unlabeled'
+// CHECK-FUNC-SIG-SCHEME-UNUSED: warning: argument unused during compilation:
+// CHECK-FUNC-SIG-SCHEME-UNUSED-SAME: '-mcf-branch-label-scheme=func-sig'

>From bf9ed5122a0d025a0e635d31951064d6c82da742 Mon Sep 17 00:00:00 2001
From: Ming-Yi Lai <ming-yi.lai at mediatek.com>
Date: Fri, 10 May 2024 14:16:59 +0800
Subject: [PATCH 2/2] [clang][RISCV] Add Zicfilp CFI scheme preprocessor macros

These macros allow assembly files to know which CFI label to use when the target
has Zicfilp enabled.
---
 clang/lib/Basic/Targets/RISCV.cpp             | 19 +++++
 .../test/CodeGen/RISCV/riscv-cf-protection.c  | 83 +++++++++++++------
 2 files changed, 78 insertions(+), 24 deletions(-)

diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index b6ea4440507ea1..4375355c13a30c 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -224,6 +224,25 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
     else
       Builder.defineMacro("__riscv_32e");
   }
+
+  if (ISAInfo->hasExtension("zicfilp") && Opts.CFProtectionBranch) {
+    auto Scheme = Opts.getCFBranchLabelScheme();
+    if (Scheme == CFBranchLabelSchemeKind::Default)
+      Scheme = getDefaultCFBranchLabelScheme();
+
+    Builder.defineMacro("__riscv_landing_pad", "1");
+    switch (Scheme) {
+    case CFBranchLabelSchemeKind::Unlabeled:
+      Builder.defineMacro("__riscv_landing_pad_unlabeled", "1");
+      break;
+    case CFBranchLabelSchemeKind::FuncSig:
+      Builder.defineMacro("__riscv_landing_pad_func_sig", "1");
+      break;
+    case CFBranchLabelSchemeKind::Default:
+      llvm_unreachable("default cf-branch-label scheme should already be "
+                       "transformed to other scheme");
+    }
+  }
 }
 
 static constexpr Builtin::Info BuiltinInfo[] = {
diff --git a/clang/test/CodeGen/RISCV/riscv-cf-protection.c b/clang/test/CodeGen/RISCV/riscv-cf-protection.c
index 02a22006b1638f..1906b87d63d62b 100644
--- a/clang/test/CodeGen/RISCV/riscv-cf-protection.c
+++ b/clang/test/CodeGen/RISCV/riscv-cf-protection.c
@@ -1,12 +1,30 @@
+// Default cf-branch-label-scheme is func-sig
 // RUN: %clang --target=riscv32 -menable-experimental-extensions \
-// RUN:   -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+// RUN:   -march=rv32i_zicfilp1p0 -fcf-protection=branch -E -dM %s -o - \
+// RUN:   | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_zicfilp1p0 -fcf-protection=branch -E -dM %s -o - \
+// RUN:   | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_zicfilp1p0 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=unlabeled -E -dM %s -o - \
+// RUN:   | FileCheck --check-prefix=CHECK-ZICFILP-UNLABELED %s
 
 // RUN: %clang --target=riscv32 -menable-experimental-extensions \
-// RUN:   -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+// RUN:   -march=rv32i_zicfilp1p0 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=func-sig -E -dM %s -o - \
+// RUN:   | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-UNLABELED-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN:   -march=rv32i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-FUNC-SIG-SCHEME-UNUSED %s
 
 // RUN: not %clang --target=riscv32 -fcf-protection=branch \
 // RUN:   -mcf-branch-label-scheme=unlabeled -c %s -o /dev/null 2>&1 \
@@ -16,23 +34,33 @@
 // RUN:   -mcf-branch-label-scheme=func-sig -c %s -o /dev/null 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s
 
-// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=unlabeled -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=unlabeled -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-UNLABELED-SCHEME-UNUSED %s
+
+// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=func-sig -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-FUNC-SIG-SCHEME-UNUSED %s
 
-// RUN: %clang --target=riscv32 -mcf-branch-label-scheme=func-sig -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_zicfilp1p0 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=unlabeled -E -dM %s -o - \
+// RUN:   | FileCheck --check-prefix=CHECK-ZICFILP-UNLABELED %s
+
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN:   -march=rv64i_zicfilp1p0 -fcf-protection=branch \
+// RUN:   -mcf-branch-label-scheme=func-sig -E -dM %s -o - \
+// RUN:   | FileCheck --check-prefix=CHECK-ZICFILP-FUNC-SIG %s
 
 // RUN: %clang --target=riscv64 -menable-experimental-extensions \
-// RUN:   -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+// RUN:   -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=unlabeled -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-UNLABELED-SCHEME-UNUSED %s
 
 // RUN: %clang --target=riscv64 -menable-experimental-extensions \
-// RUN:   -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+// RUN:   -march=rv64i_zicfilp1p0 -mcf-branch-label-scheme=func-sig -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-FUNC-SIG-SCHEME-UNUSED %s
 
 // RUN: not %clang --target=riscv64 -fcf-protection=branch \
 // RUN:   -mcf-branch-label-scheme=unlabeled -c %s -o /dev/null 2>&1 \
@@ -42,14 +70,21 @@
 // RUN:   -mcf-branch-label-scheme=func-sig -c %s -o /dev/null 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-BRANCH-PROT-INVALID %s
 
-// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=unlabeled -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-UNLABELED-SCHEME-UNUSED %s
+// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=unlabeled -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-UNLABELED-SCHEME-UNUSED %s
 
-// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=func-sig -c %s \
-// RUN:   -o /dev/null 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FUNC-SIG-SCHEME-UNUSED %s
+// RUN: %clang --target=riscv64 -mcf-branch-label-scheme=func-sig -E -dM %s \
+// RUN:   -o - 2>&1 | FileCheck \
+// RUN:   --check-prefixes=CHECK-NO-MACRO,CHECK-FUNC-SIG-SCHEME-UNUSED %s
 
+// CHECK-ZICFILP-UNLABELED: __riscv_landing_pad 1{{$}}
+// CHECK-ZICFILP-UNLABELED: __riscv_landing_pad_unlabeled 1{{$}}
+// CHECK-ZICFILP-FUNC-SIG: __riscv_landing_pad 1{{$}}
+// CHECK-ZICFILP-FUNC-SIG: __riscv_landing_pad_func_sig 1{{$}}
+// CHECK-NO-MACRO-NOT: __riscv_landing_pad
+// CHECK-NO-MACRO-NOT: __riscv_landing_pad_unlabeled
+// CHECK-NO-MACRO-NOT: __riscv_landing_pad_func_sig
 // CHECK-BRANCH-PROT-INVALID: error: option 'cf-protection=branch' cannot be
 // CHECK-BRANCH-PROT-INVALID-SAME: specified on this target
 // CHECK-UNLABELED-SCHEME-UNUSED: warning: argument unused during compilation:



More information about the cfe-commits mailing list