summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h')
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h106
1 files changed, 106 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
new file mode 100644
index 0000000..ecb396e
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Driver/SanitizerArgs.h
@@ -0,0 +1,106 @@
+//===--- SanitizerArgs.h - Arguments for sanitizer tools -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
+#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
+
+#include "clang/Driver/ArgList.h"
+
+namespace clang {
+namespace driver {
+
+class SanitizerArgs {
+ /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
+ /// bit positions within \c Kind.
+ enum SanitizeOrdinal {
+#define SANITIZER(NAME, ID) SO_##ID,
+#include "clang/Basic/Sanitizers.def"
+ SO_Count
+ };
+
+ /// Bugs to catch at runtime.
+ enum SanitizeKind {
+#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
+#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
+#include "clang/Basic/Sanitizers.def"
+ NeedsAsanRt = Address,
+ NeedsTsanRt = Thread,
+ NeedsUbsanRt = Undefined
+ };
+ unsigned Kind;
+
+ public:
+ SanitizerArgs() : Kind(0) {}
+ /// Parses the sanitizer arguments from an argument list.
+ SanitizerArgs(const Driver &D, const ArgList &Args);
+
+ bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+ bool needsTsanRt() const { return Kind & NeedsTsanRt; }
+ bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
+
+ bool sanitizesVptr() const { return Kind & Vptr; }
+
+ void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+ if (!Kind)
+ return;
+ llvm::SmallString<256> SanitizeOpt("-fsanitize=");
+#define SANITIZER(NAME, ID) \
+ if (Kind & ID) \
+ SanitizeOpt += NAME ",";
+#include "clang/Basic/Sanitizers.def"
+ SanitizeOpt.pop_back();
+ CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
+ }
+
+ private:
+ /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
+ /// Returns a member of the \c SanitizeKind enumeration, or \c 0 if \p Value
+ /// is not known.
+ static unsigned parse(const char *Value) {
+ return llvm::StringSwitch<SanitizeKind>(Value)
+#define SANITIZER(NAME, ID) .Case(NAME, ID)
+#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
+#include "clang/Basic/Sanitizers.def"
+ .Default(SanitizeKind());
+ }
+
+ /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
+ /// invalid components.
+ static unsigned parse(const Driver &D, const Arg *A) {
+ unsigned Kind = 0;
+ for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
+ if (unsigned K = parse(A->getValue(I)))
+ Kind |= K;
+ else
+ D.Diag(diag::err_drv_unsupported_option_argument)
+ << A->getOption().getName() << A->getValue(I);
+ }
+ return Kind;
+ }
+
+ /// Produce an argument string from argument \p A, which shows how it provides
+ /// a value in \p Mask. For instance, the argument
+ /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
+ /// "-fsanitize=alignment".
+ static std::string describeSanitizeArg(const ArgList &Args, const Arg *A,
+ unsigned Mask) {
+ if (!A->getOption().matches(options::OPT_fsanitize_EQ))
+ return A->getAsString(Args);
+
+ for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
+ if (parse(A->getValue(I)) & Mask)
+ return std::string("-fsanitize=") + A->getValue(I);
+
+ llvm_unreachable("arg didn't provide expected value");
+ }
+};
+
+} // namespace driver
+} // namespace clang
+
+#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
OpenPOWER on IntegriCloud