Author: Yingwei Zheng
Date: 2025-05-09T14:53:00+08:00
New Revision: d2b012e3913a56d3cb2d9798bf77dc2599148dfb

URL: 
https://github.com/llvm/llvm-project/commit/d2b012e3913a56d3cb2d9798bf77dc2599148dfb
DIFF: 
https://github.com/llvm/llvm-project/commit/d2b012e3913a56d3cb2d9798bf77dc2599148dfb.diff

LOG: [Clang][CodeGen] Enable pointer overflow check for GCC workaround (#137849)

Do not suppress the pointer overflow check for the `(i8*) nullptr + N`
idiom.

Related issue: https://github.com/llvm/llvm-project/issues/137833

Added: 
    

Modified: 
    clang/lib/CodeGen/CGExprScalar.cpp
    clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index f639a87e3ad0b..df793a5a46359 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4180,11 +4180,28 @@ static Value *emitPointerArithmetic(CodeGenFunction 
&CGF,
   //   The index is not pointer-sized.
   //   The pointer type is not byte-sized.
   //
-  if (BinaryOperator::isNullPointerArithmeticExtension(CGF.getContext(),
-                                                       op.Opcode,
-                                                       expr->getLHS(),
-                                                       expr->getRHS()))
-    return CGF.Builder.CreateIntToPtr(index, pointer->getType());
+  // Note that we do not suppress the pointer overflow check in this case.
+  if (BinaryOperator::isNullPointerArithmeticExtension(
+          CGF.getContext(), op.Opcode, expr->getLHS(), expr->getRHS())) {
+    Value *Ptr = CGF.Builder.CreateIntToPtr(index, pointer->getType());
+    if (CGF.getLangOpts().PointerOverflowDefined ||
+        !CGF.SanOpts.has(SanitizerKind::PointerOverflow) ||
+        NullPointerIsDefined(CGF.Builder.GetInsertBlock()->getParent(),
+                             PtrTy->getPointerAddressSpace()))
+      return Ptr;
+    // The inbounds GEP of null is valid iff the index is zero.
+    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    Value *IsZeroIndex = CGF.Builder.CreateIsNull(index);
+    llvm::Constant *StaticArgs[] = {
+        CGF.EmitCheckSourceLocation(op.E->getExprLoc())};
+    llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
+    Value *IntPtr = llvm::Constant::getNullValue(IntPtrTy);
+    Value *ComputedGEP = CGF.Builder.CreateZExtOrTrunc(index, IntPtrTy);
+    Value *DynamicArgs[] = {IntPtr, ComputedGEP};
+    CGF.EmitCheck({{IsZeroIndex, SanitizerKind::SO_PointerOverflow}},
+                  SanitizerHandler::PointerOverflow, StaticArgs, DynamicArgs);
+    return Ptr;
+  }
 
   if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
     // Zero-extend or sign-extend the pointer value according to

diff  --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c 
b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
index 63b6db2c2adeb..26d17e7b23aaf 100644
--- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
+++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
@@ -32,6 +32,7 @@
 // CHECK-SANITIZE-ANYRECOVER-DAG: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 15 
} }
 // CHECK-SANITIZE-ANYRECOVER-DAG: @[[LINE_1600:.*]] = {{.*}}, i32 1600, i32 15 
} }
 // CHECK-SANITIZE-ANYRECOVER-DAG: @[[LINE_1700:.*]] = {{.*}}, i32 1700, i32 15 
} }
+// CHECK-SANITIZE-ANYRECOVER-DAG: @[[LINE_1800:.*]] = {{.*}}, i32 1800, i32 20 
} }
 
 #ifdef __cplusplus
 extern "C" {
@@ -431,6 +432,26 @@ char *void_ptr(void *base, unsigned long offset) {
   return base + offset;
 }
 
+char *constant_null_add(unsigned long offset) {
+  // CHECK: define{{.*}} ptr @constant_null_add(i64 noundef %[[OFFSET:.*]])
+  // CHECK-NEXT:                      [[ENTRY:.*]]:
+  // CHECK-NEXT:                        %[[OFFSET_ADDR:.*]] = alloca i64, 
align 8
+  // CHECK-NEXT:                        store i64 %[[OFFSET]], ptr 
%[[OFFSET_ADDR]], align 8
+  // CHECK-NEXT:                        %[[OFFSET_RELOADED:.*]] = load i64, 
ptr %[[OFFSET_ADDR]], align 8
+  // CHECK-NEXT:                        %[[ADD_PTR:.*]] = inttoptr i64 
%[[OFFSET_RELOADED]] to ptr
+  // CHECK-SANITIZE-NEXT:               %[[IS_NULL:.*]] = icmp eq i64 
%[[OFFSET_RELOADED]], 0, !nosanitize
+  // CHECK-SANITIZE-NEXT:               br i1 %[[IS_NULL]], label 
%[[CONT:.*]], label %[[HANDLER_POINTER_OVERFLOW:[^,]+]],{{.*}} !nosanitize
+  // CHECK-SANITIZE:                  [[HANDLER_POINTER_OVERFLOW]]:
+  // CHECK-SANITIZE-NORECOVER-NEXT:     call void 
@__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1800]], i64 0, i64 
%[[OFFSET_RELOADED]])
+  // CHECK-SANITIZE-RECOVER-NEXT:       call void 
@__ubsan_handle_pointer_overflow(ptr @[[LINE_1800]], i64 0, i64 
%[[OFFSET_RELOADED]])
+  // CHECK-SANITIZE-TRAP-NEXT:          call void @llvm.ubsantrap(i8 
19){{.*}}, !nosanitize
+  // CHECK-SANITIZE-UNREACHABLE-NEXT:   unreachable, !nosanitize
+  // CHECK-SANITIZE:                  [[CONT]]:
+  // CHECK-NEXT:                        ret ptr %[[ADD_PTR]]
+#line 1800
+  return (char *)0 + offset;
+}
+
 #ifdef __cplusplus
 }
 #endif


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to