diff options
author | Thurston Dang <thurston@google.com> | 2025-06-06 14:59:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-06 14:59:32 -0700 |
commit | 428afa62b0aa1bb0ac344cbfc62429a60c42b265 (patch) | |
tree | 8ecd95edfec80811713ecd9dc8560d1e99c52d47 /clang/lib/CodeGen/CGDebugInfo.cpp | |
parent | a42bb8b57a6dcf298789ae88b36bbbba19e151fb (diff) | |
download | llvm-428afa62b0aa1bb0ac344cbfc62429a60c42b265.zip llvm-428afa62b0aa1bb0ac344cbfc62429a60c42b265.tar.gz llvm-428afa62b0aa1bb0ac344cbfc62429a60c42b265.tar.bz2 |
[ubsan] Add more -fsanitize-annotate-debug-info checks (#141997)
This extends https://github.com/llvm/llvm-project/pull/138577 to more UBSan checks, by changing SanitizerDebugLocation (formerly SanitizerScope) to add annotations if enabled for the specified ordinals.
Annotations will use the ordinal name if there is exactly one ordinal specified in the SanitizerDebugLocation; otherwise, it will use the handler name.
Updates the tests from https://github.com/llvm/llvm-project/pull/141814.
---------
Co-authored-by: Vitaly Buka <vitalybuka@google.com>
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 82 |
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; +} |