[clang] [codegen] Fix crash in codegan caused by pointer calculation overflow (PR #115791)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 11 16:10:37 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: None (vabridgers)
<details>
<summary>Changes</summary>
Fixes https://github.com/llvm/llvm-project/issues/48168
Under certain conditions, the front end does not detect a possible overflow address calculations until codegen. This change emits a warning instead of allowing the compiler to crash.
```
clang: <root>/clang/lib/CodeGen/CGExprScalar.cpp:5834: llvm::Value* clang::CodeGen::CodeGenFunction::EmitCheckedInBoundsGEP(
llvm::Type*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, bool, bool, clang::SourceLocation, const llvm::Twine&):
Assertion `(!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) || EvaluatedGEP.OffsetOverflows == Builder.getFalse())
&& "If the offset got constant-folded, we don't expect that there was an " "overflow."' failed.
0. Program arguments: clang -c --target=x86_64-- -fsanitize=undefined ubsan-emit-bounds-check-crash-x86.c
1. <eof> parser at end of file
2. ubsan-emit-bounds-check-crash-x86.c:4:5: LLVM IR generation of declaration 'main'
3. ubsan-emit-bounds-check-crash-x86.c:4:5: Generating code for declaration 'main'
...
#<!-- -->9 <addr> clang::CodeGen::CodeGenFunction::EmitCheckedInBoundsGEP(clang::CodeGen::Address,
llvm::ArrayRef<llvm::Value*>, llvm::Type*, bool, bool, clang::SourceLocation,
clang::CharUnits, llvm::Twine const&)
llvm::ArrayRef<llvm::Value*>, clang::QualType, bool, bool, clang::SourceLocation,
clang::QualType*, clang::Expr const*, llvm::Twine const&) CGExpr.cpp:0:0
bool)
```
---
Full diff: https://github.com/llvm/llvm-project/pull/115791.diff
3 Files Affected:
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+9-4)
- (added) clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c (+7)
- (added) clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c (+7)
``````````diff
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 287d911e10ba58..5ed865820a9151 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5831,10 +5831,15 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
GEPOffsetAndOverflow EvaluatedGEP =
EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder);
- assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
- EvaluatedGEP.OffsetOverflows == Builder.getFalse()) &&
- "If the offset got constant-folded, we don't expect that there was an "
- "overflow.");
+ if (!(!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
+ EvaluatedGEP.OffsetOverflows == Builder.getFalse())) {
+ DiagnosticsEngine &Diags = CGM.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(
+ DiagnosticsEngine::Error, "Expression caused pointer calculation "
+ "overflow during code generation");
+ Diags.Report(Loc, DiagID);
+ return GEPVal;
+ }
auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
diff --git a/clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c
new file mode 100644
index 00000000000000..b4da2f2b7ee720
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c
@@ -0,0 +1,7 @@
+// REQUIRES: msp430-registered-target
+// RUN: %clang -c -fsanitize=undefined -Wno-tentative-definition-array -Wno-return-type -Wno-unused-value -Wno-array-bounds -Xclang -verify --target=msp430-- %s
+int a;
+_Complex double b[1][1];
+void c(void) {
+ b[a][8920]; // expected-error {{Expression caused pointer calculation overflow during code generation}}
+}
diff --git a/clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c
new file mode 100644
index 00000000000000..63bda82c14ae20
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c
@@ -0,0 +1,7 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -c -Wno-tentative-definition-array -Wno-return-type -Wno-unused-value -Wno-array-bounds -Xclang -verify --target=x86_64-- -fsanitize=undefined %s
+int **a[];
+int main() {
+ (*a)[3300220222222200000]; // expected-error {{Expression caused pointer calculation overflow during code generation}}
+ return 0;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/115791
More information about the cfe-commits
mailing list