From 051aa171d2177776964cc309d14d8333af66135f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 30 Aug 2023 19:29:50 +0000 Subject: [PATCH] [Driver] Adjust -fsanitize=function & -mexecute-only interop after D158614 clangDriver depends on clangBasic, so clangBasic should not depend on clangDriver, even just its header. Also remove clangBasic's dependency on LLVMOption. The issue can be seen through the bazel commit d26dd681f9726ed7d43d7c0bdd8ee3cb2db69a2b which is reverted now. Add hasFlagNoClaim and use it as we don't want to suppress -Wunused-command-line-argument for -mexecute-only just because -fsanitize= is specified. --- clang/include/clang/Basic/Sanitizers.h | 5 ----- clang/lib/Basic/CMakeLists.txt | 1 - clang/lib/Basic/Sanitizers.cpp | 13 ------------- clang/lib/Driver/SanitizerArgs.cpp | 10 ++++++++++ llvm/include/llvm/Option/ArgList.h | 1 + llvm/lib/Option/ArgList.cpp | 7 +++++++ 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index c212f80fe03a..4659e45c7883 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -209,11 +209,6 @@ StringRef AsanDetectStackUseAfterReturnModeToString( llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr); -/// Return true if an execute-only target disallows data access to code -/// sections. -bool isExecuteOnlyTarget(const llvm::Triple &Triple, - const llvm::opt::ArgList &Args); - } // namespace clang #endif // LLVM_CLANG_BASIC_SANITIZERS_H diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index d6620ec204ad..caa1b6002e6f 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -1,5 +1,4 @@ set(LLVM_LINK_COMPONENTS - Option Support TargetParser ) diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp index 6fbc32df3148..62ccdf8e9bbf 100644 --- a/clang/lib/Basic/Sanitizers.cpp +++ b/clang/lib/Basic/Sanitizers.cpp @@ -11,13 +11,10 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Sanitizers.h" -#include "clang/Driver/Options.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/Option/ArgList.h" #include "llvm/Support/MathExtras.h" -#include "llvm/TargetParser/Triple.h" using namespace clang; @@ -115,14 +112,4 @@ AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr) { .Default(llvm::AsanDetectStackUseAfterReturnMode::Invalid); } -bool isExecuteOnlyTarget(const llvm::Triple &Triple, - const llvm::opt::ArgList &Args) { - if (Triple.isPS5()) - return true; - - // On Arm, the clang `-mexecute-only` option is used to generate the - // execute-only output (no data access to code sections). - return Args.hasFlag(clang::driver::options::OPT_mexecute_only, - clang::driver::options::OPT_mno_execute_only, false); -} } // namespace clang diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index a4e947594748..12fe55be9113 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -143,6 +143,16 @@ static std::string describeSanitizeArg(const llvm::opt::Arg *A, /// Sanitizers set. static std::string toString(const clang::SanitizerSet &Sanitizers); +/// Return true if an execute-only target disallows data access to code +/// sections. +static bool isExecuteOnlyTarget(const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) { + if (Triple.isPS5()) + return true; + return Args.hasFlagNoClaim(options::OPT_mexecute_only, + options::OPT_mno_execute_only, false); +} + static void validateSpecialCaseListFormat(const Driver &D, std::vector &SCLFiles, unsigned MalformedSCLErrorDiagID, diff --git a/llvm/include/llvm/Option/ArgList.h b/llvm/include/llvm/Option/ArgList.h index 310c8900af9e..c57bd2350af1 100644 --- a/llvm/include/llvm/Option/ArgList.h +++ b/llvm/include/llvm/Option/ArgList.h @@ -299,6 +299,7 @@ class ArgList { /// \p Default if neither option is given. If both the option and its /// negation are present, the last one wins. bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const; + bool hasFlagNoClaim(OptSpecifier Pos, OptSpecifier Neg, bool Default) const; /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative /// form \p Neg, return true if the option or its alias is present, false if diff --git a/llvm/lib/Option/ArgList.cpp b/llvm/lib/Option/ArgList.cpp index 400bedabc003..86f28e578e5d 100644 --- a/llvm/lib/Option/ArgList.cpp +++ b/llvm/lib/Option/ArgList.cpp @@ -75,6 +75,13 @@ bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const { return Default; } +bool ArgList::hasFlagNoClaim(OptSpecifier Pos, OptSpecifier Neg, + bool Default) const { + if (Arg *A = getLastArgNoClaim(Pos, Neg)) + return A->getOption().matches(Pos); + return Default; +} + bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, bool Default) const { if (Arg *A = getLastArg(Pos, PosAlias, Neg))