aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGDebugInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index fbcc330a..001b208 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -58,6 +58,13 @@
using namespace clang;
using namespace clang::CodeGen;
+// TODO: consider deprecating ClArrayBoundsPseudoFn; functionality is subsumed
+// by -fsanitize-annotate-debug-info
+static llvm::cl::opt<bool> ClArrayBoundsPseudoFn(
+ "array-bounds-pseudofn", llvm::cl::Hidden, llvm::cl::Optional,
+ llvm::cl::desc("Emit debug info that places array-bounds instrumentation "
+ "in an inline function called __ubsan_check_array_bounds."));
+
static uint32_t getTypeAlignIfRequired(const Type *Ty, const ASTContext &Ctx) {
auto TI = Ctx.getTypeInfo(Ty);
if (TI.isAlignRequired())
@@ -6412,3 +6419,78 @@ CodeGenFunction::LexicalScope::~LexicalScope() {
ForceCleanup();
}
}
+
+static std::string SanitizerHandlerToCheckLabel(SanitizerHandler Handler) {
+ std::string Label;
+ switch (Handler) {
+#define SANITIZER_CHECK(Enum, Name, Version) \
+ case Enum: \
+ Label = "__ubsan_check_" #Name; \
+ break;
+
+ LIST_SANITIZER_CHECKS
+#undef SANITIZER_CHECK
+ };
+
+ // Label doesn't require sanitization
+ return Label;
+}
+
+static std::string
+SanitizerOrdinalToCheckLabel(SanitizerKind::SanitizerOrdinal Ordinal) {
+ std::string Label;
+ switch (Ordinal) {
+#define SANITIZER(NAME, ID) \
+ case SanitizerKind::SO_##ID: \
+ Label = "__ubsan_check_" NAME; \
+ break;
+#include "clang/Basic/Sanitizers.def"
+ default:
+ llvm_unreachable("unexpected sanitizer kind");
+ }
+
+ // Sanitize label (convert hyphens to underscores; also futureproof against
+ // non-alpha)
+ for (unsigned int i = 0; i < Label.length(); i++)
+ if (!std::isalpha(Label[i]))
+ Label[i] = '_';
+
+ return Label;
+}
+
+llvm::DILocation *CodeGenFunction::SanitizerAnnotateDebugInfo(
+ ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+ SanitizerHandler Handler) {
+ std::string Label;
+ if (Ordinals.size() == 1)
+ Label = SanitizerOrdinalToCheckLabel(Ordinals[0]);
+ else
+ Label = SanitizerHandlerToCheckLabel(Handler);
+
+ llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
+
+ for (auto Ord : Ordinals) {
+ // TODO: deprecate ClArrayBoundsPseudoFn
+ if (((ClArrayBoundsPseudoFn && Ord == SanitizerKind::SO_ArrayBounds) ||
+ CGM.getCodeGenOpts().SanitizeAnnotateDebugInfo.has(Ord)) &&
+ CheckDI) {
+ return getDebugInfo()->CreateSyntheticInlineAt(CheckDI, Label);
+ }
+ }
+
+ return CheckDI;
+}
+
+SanitizerDebugLocation::SanitizerDebugLocation(
+ CodeGenFunction *CGF, ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals,
+ SanitizerHandler Handler)
+ : CGF(CGF),
+ Apply(*CGF, CGF->SanitizerAnnotateDebugInfo(Ordinals, Handler)) {
+ assert(!CGF->IsSanitizerScope);
+ CGF->IsSanitizerScope = true;
+}
+
+SanitizerDebugLocation::~SanitizerDebugLocation() {
+ assert(CGF->IsSanitizerScope);
+ CGF->IsSanitizerScope = false;
+}