[llvm-branch-commits] [clang] [clang] [sanitizer] add pseudofunction to indicate array-bounds check (PR #128977)

Florian Mayer via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Mar 25 14:59:02 PDT 2025


https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/128977

>From 0fe2ba3242026457d8afc46c4a3338efd941c42f Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Wed, 26 Feb 2025 17:12:43 -0800
Subject: [PATCH 1/4] fmt

Created using spr 1.3.4
---
 clang/lib/CodeGen/CGExpr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index dbd24547b2304..dc3b253237e51 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3623,7 +3623,6 @@ void CodeGenFunction::EmitCheck(
   llvm::Value *RecoverableCond = nullptr;
   llvm::Value *TrapCond = nullptr;
   bool NoMerge = false;
-
   // Expand checks into:
   //   (Check1 || !allow_ubsan_check) && (Check2 || !allow_ubsan_check) ...
   // We need separate allow_ubsan_check intrinsics because they have separately
@@ -3933,6 +3932,7 @@ void CodeGenFunction::EmitTrapCheck(llvm::Value *Checked,
     TrapBBs.resize(CheckHandlerID + 1);
 
   llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
+
   NoMerge = NoMerge || !CGM.getCodeGenOpts().OptimizationLevel ||
             (CurCodeDecl && CurCodeDecl->hasAttr<OptimizeNoneAttr>());
 

>From a16b7a8c48353226fe1323a45f59cd4167ddc3d4 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Wed, 26 Feb 2025 17:15:20 -0800
Subject: [PATCH 2/4] rename & fmt

Created using spr 1.3.4
---
 clang/lib/CodeGen/CGDebugInfo.cpp              | 7 ++++---
 clang/lib/CodeGen/CGDebugInfo.h                | 8 +++++---
 clang/lib/CodeGen/CGExpr.cpp                   | 5 ++---
 clang/test/CodeGen/bounds-checking-debuginfo.c | 4 ++--
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index ae19e8f724314..35fd78b15ff30 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3598,13 +3598,14 @@ llvm::DIMacroFile *CGDebugInfo::CreateTempMacroFile(llvm::DIMacroFile *Parent,
   return DBuilder.createTempMacroFile(Parent, Line, FName);
 }
 
-llvm::DILocation *CGDebugInfo::CreateSyntheticInline(
-    llvm::DebugLoc TrapLocation, StringRef FuncName) {
+llvm::DILocation *
+CGDebugInfo::CreateSyntheticInline(llvm::DebugLoc TrapLocation,
+                                   StringRef FuncName) {
   llvm::DISubprogram *TrapSP =
       createInlinedTrapSubprogram(FuncName, TrapLocation->getFile());
   return llvm::DILocation::get(CGM.getLLVMContext(), /*Line=*/0, /*Column=*/0,
                                /*Scope=*/TrapSP, /*InlinedAt=*/TrapLocation);
-    }
+}
 
 llvm::DILocation *CGDebugInfo::CreateTrapFailureMessageFor(
     llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg) {
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 0b06bdf78ac78..d01ad3b3d8df5 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -638,9 +638,11 @@ class CGDebugInfo {
   /// Create a debug location from `TrapLocation` that adds an artificial inline
   /// frame where the frame name is FuncName
   ///
-  /// This is used to indiciate instructions that come from compiler instrumentation.
-  llvm::DILocation *CreateSyntheticInline(
-      llvm::DebugLoc TrapLocation, StringRef FuncName);
+  /// This is used to indiciate instructions that come from compiler
+  /// instrumentation.
+  llvm::DILocation *CreateSyntheticInline(llvm::DebugLoc TrapLocation,
+                                          StringRef FuncName);
+
 private:
   /// Emit call to llvm.dbg.declare for a variable declaration.
   /// Returns a pointer to the DILocalVariable associated with the
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index dc3b253237e51..d5cc2cc69c921 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1219,10 +1219,9 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
   llvm::DILocation *TrapSP = Builder.getCurrentDebugLocation();
   if (TrapSP) {
     TrapSP = getDebugInfo()->CreateSyntheticInline(
-      Builder.getCurrentDebugLocation(),
-      "check_array_bounds");
+        Builder.getCurrentDebugLocation(), "__ubsan_check_array_bounds");
   }
-   ApplyDebugLocation ApplyTrapDI(*this, TrapSP);
+  ApplyDebugLocation ApplyTrapDI(*this, TrapSP);
 
   bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
   llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index e2a604bc962ba..58fcc89058d72 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -89,7 +89,7 @@ double f1(int b, int i) {
 // CHECK-TRAP: [[DBG22]] = !DILocation(line: 65, column: 3, scope: [[DBG5]])
 // CHECK-TRAP: [[DBG23]] = !DILocation(line: 66, column: 12, scope: [[DBG5]])
 // CHECK-TRAP: [[DBG24]] = !DILocation(line: 0, scope: [[META25:![0-9]+]], inlinedAt: [[DBG27]])
-// CHECK-TRAP: [[META25]] = distinct !DISubprogram(name: "check_array_bounds", scope: [[META6]], file: [[META6]], type: [[META26:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-TRAP: [[META25]] = distinct !DISubprogram(name: "__ubsan_check_array_bounds", scope: [[META6]], file: [[META6]], type: [[META26:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-TRAP: [[META26]] = !DISubroutineType(types: null)
 // CHECK-TRAP: [[DBG27]] = !DILocation(line: 66, column: 10, scope: [[DBG5]])
 // CHECK-TRAP: [[DBG28]] = !DILocation(line: 66, column: 3, scope: [[DBG5]])
@@ -116,7 +116,7 @@ double f1(int b, int i) {
 // CHECK-NOTRAP: [[DBG22]] = !DILocation(line: 65, column: 3, scope: [[DBG5]])
 // CHECK-NOTRAP: [[DBG23]] = !DILocation(line: 66, column: 12, scope: [[DBG5]])
 // CHECK-NOTRAP: [[DBG24]] = !DILocation(line: 0, scope: [[META25:![0-9]+]], inlinedAt: [[DBG27]])
-// CHECK-NOTRAP: [[META25]] = distinct !DISubprogram(name: "check_array_bounds", scope: [[META6]], file: [[META6]], type: [[META26:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
+// CHECK-NOTRAP: [[META25]] = distinct !DISubprogram(name: "__ubsan_check_array_bounds", scope: [[META6]], file: [[META6]], type: [[META26:![0-9]+]], flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: [[META0]])
 // CHECK-NOTRAP: [[META26]] = !DISubroutineType(types: null)
 // CHECK-NOTRAP: [[DBG27]] = !DILocation(line: 66, column: 10, scope: [[DBG5]])
 // CHECK-NOTRAP: [[PROF28]] = !{!"branch_weights", i32 1048575, i32 1}

>From ff406cc02d8fc54886e01e4f364dc204110eb90e Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Wed, 26 Feb 2025 17:24:52 -0800
Subject: [PATCH 3/4] naming

Created using spr 1.3.4
---
 clang/lib/CodeGen/CGDebugInfo.cpp | 9 ++++-----
 clang/lib/CodeGen/CGDebugInfo.h   | 4 ++--
 clang/lib/CodeGen/CGExpr.cpp      | 8 ++++----
 3 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 35fd78b15ff30..907aaf710e989 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3598,13 +3598,12 @@ llvm::DIMacroFile *CGDebugInfo::CreateTempMacroFile(llvm::DIMacroFile *Parent,
   return DBuilder.createTempMacroFile(Parent, Line, FName);
 }
 
-llvm::DILocation *
-CGDebugInfo::CreateSyntheticInline(llvm::DebugLoc TrapLocation,
-                                   StringRef FuncName) {
+llvm::DILocation *CGDebugInfo::CreateSyntheticInline(llvm::DebugLoc Location,
+                                                     StringRef FuncName) {
   llvm::DISubprogram *TrapSP =
-      createInlinedTrapSubprogram(FuncName, TrapLocation->getFile());
+      createInlinedTrapSubprogram(FuncName, Location->getFile());
   return llvm::DILocation::get(CGM.getLLVMContext(), /*Line=*/0, /*Column=*/0,
-                               /*Scope=*/TrapSP, /*InlinedAt=*/TrapLocation);
+                               /*Scope=*/TrapSP, /*InlinedAt=*/Location);
 }
 
 llvm::DILocation *CGDebugInfo::CreateTrapFailureMessageFor(
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index d01ad3b3d8df5..d0aea952ccf3d 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -635,12 +635,12 @@ class CGDebugInfo {
   llvm::DILocation *CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation,
                                                 StringRef Category,
                                                 StringRef FailureMsg);
-  /// Create a debug location from `TrapLocation` that adds an artificial inline
+  /// Create a debug location from `Location` that adds an artificial inline
   /// frame where the frame name is FuncName
   ///
   /// This is used to indiciate instructions that come from compiler
   /// instrumentation.
-  llvm::DILocation *CreateSyntheticInline(llvm::DebugLoc TrapLocation,
+  llvm::DILocation *CreateSyntheticInline(llvm::DebugLoc Location,
                                           StringRef FuncName);
 
 private:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index d5cc2cc69c921..6ffff67676547 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1216,12 +1216,12 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
 
   SanitizerScope SanScope(this);
 
-  llvm::DILocation *TrapSP = Builder.getCurrentDebugLocation();
-  if (TrapSP) {
-    TrapSP = getDebugInfo()->CreateSyntheticInline(
+  llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
+  if (CheckDI) {
+    CheckDI = getDebugInfo()->CreateSyntheticInline(
         Builder.getCurrentDebugLocation(), "__ubsan_check_array_bounds");
   }
-  ApplyDebugLocation ApplyTrapDI(*this, TrapSP);
+  ApplyDebugLocation ApplyTrapDI(*this, CheckDI);
 
   bool IndexSigned = IndexType->isSignedIntegerOrEnumerationType();
   llvm::Value *IndexVal = Builder.CreateIntCast(Index, SizeTy, IndexSigned);

>From cf4d310eab70e284a21a72437e0a2839386236d1 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Tue, 4 Mar 2025 14:29:09 -0800
Subject: [PATCH 4/4] name

Created using spr 1.3.4
---
 clang/lib/CodeGen/CGDebugInfo.cpp              | 8 ++++----
 clang/lib/CodeGen/CGDebugInfo.h                | 6 +++---
 clang/lib/CodeGen/CGExpr.cpp                   | 8 +++++++-
 clang/test/CodeGen/bounds-checking-debuginfo.c | 4 ++--
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 907aaf710e989..0f71795be592b 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1771,12 +1771,12 @@ llvm::DIType *CGDebugInfo::createFieldType(
 }
 
 llvm::DISubprogram *
-CGDebugInfo::createInlinedTrapSubprogram(StringRef FuncName,
-                                         llvm::DIFile *FileScope) {
+CGDebugInfo::createInlinedSubprogram(StringRef FuncName,
+                                     llvm::DIFile *FileScope) {
   // We are caching the subprogram because we don't want to duplicate
   // subprograms with the same message. Note that `SPFlagDefinition` prevents
   // subprograms from being uniqued.
-  llvm::DISubprogram *&SP = InlinedTrapFuncMap[FuncName];
+  llvm::DISubprogram *&SP = InlinedSubprogramMap[FuncName];
 
   if (!SP) {
     llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(nullptr);
@@ -3601,7 +3601,7 @@ llvm::DIMacroFile *CGDebugInfo::CreateTempMacroFile(llvm::DIMacroFile *Parent,
 llvm::DILocation *CGDebugInfo::CreateSyntheticInline(llvm::DebugLoc Location,
                                                      StringRef FuncName) {
   llvm::DISubprogram *TrapSP =
-      createInlinedTrapSubprogram(FuncName, Location->getFile());
+      createInlinedSubprogram(FuncName, Location->getFile());
   return llvm::DILocation::get(CGM.getLLVMContext(), /*Line=*/0, /*Column=*/0,
                                /*Scope=*/TrapSP, /*InlinedAt=*/Location);
 }
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index d0aea952ccf3d..cdca1452e2dcd 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -355,12 +355,12 @@ class CGDebugInfo {
       llvm::ArrayRef<llvm::Metadata *> PreviousFieldsDI, const RecordDecl *RD);
 
   /// A cache that maps names of artificial inlined functions to subprograms.
-  llvm::StringMap<llvm::DISubprogram *> InlinedTrapFuncMap;
+  llvm::StringMap<llvm::DISubprogram *> InlinedSubprogramMap;
 
   /// A function that returns the subprogram corresponding to the artificial
   /// inlined function for traps.
-  llvm::DISubprogram *createInlinedTrapSubprogram(StringRef FuncName,
-                                                  llvm::DIFile *FileScope);
+  llvm::DISubprogram *createInlinedSubprogram(StringRef FuncName,
+                                              llvm::DIFile *FileScope);
 
   /// Helpers for collecting fields of a record.
   /// @{
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 6ffff67676547..7426c45a52e0f 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -61,8 +61,14 @@ namespace clang {
 llvm::cl::opt<bool> ClSanitizeGuardChecks(
     "ubsan-guard-checks", llvm::cl::Optional,
     llvm::cl::desc("Guard UBSAN checks with `llvm.allow.ubsan.check()`."));
+
 } // namespace clang
 
+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."));
+
 //===--------------------------------------------------------------------===//
 //                        Defines for metadata
 //===--------------------------------------------------------------------===//
@@ -1217,7 +1223,7 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound,
   SanitizerScope SanScope(this);
 
   llvm::DILocation *CheckDI = Builder.getCurrentDebugLocation();
-  if (CheckDI) {
+  if (ClArrayBoundsPseudoFn && CheckDI) {
     CheckDI = getDebugInfo()->CreateSyntheticInline(
         Builder.getCurrentDebugLocation(), "__ubsan_check_array_bounds");
   }
diff --git a/clang/test/CodeGen/bounds-checking-debuginfo.c b/clang/test/CodeGen/bounds-checking-debuginfo.c
index 7f055098f0614..61c7af6e7c5b8 100644
--- a/clang/test/CodeGen/bounds-checking-debuginfo.c
+++ b/clang/test/CodeGen/bounds-checking-debuginfo.c
@@ -1,6 +1,6 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
-// RUN: %clang_cc1 -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds -fsanitize-trap=array-bounds -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-TRAP %s
-// RUN: %clang_cc1 -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds                              -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-NOTRAP %s
+// RUN: %clang_cc1 -mllvm -array-bounds-pseudofn -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds -fsanitize-trap=array-bounds -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-TRAP %s
+// RUN: %clang_cc1 -mllvm -array-bounds-pseudofn -emit-llvm -fdebug-prefix-map=%S/= -fno-ident -fdebug-compilation-dir=%S -fsanitize=array-bounds                              -triple x86_64 -debug-info-kind=limited %s -o - | FileCheck --check-prefix=CHECK-NOTRAP %s
 
 
 int f();



More information about the llvm-branch-commits mailing list