Skip to content

[Clang] Add -fwrapv-pointer flag #122486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 28, 2025
Merged

[Clang] Add -fwrapv-pointer flag #122486

merged 5 commits into from
Jan 28, 2025

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Jan 10, 2025

GCC supports three flags related to overflow behavior:

  • -fwrapv: Makes signed integer overflow well-defined.
  • -fwrapv-pointer: Makes pointer overflow well-defined.
  • -fno-strict-overflow: Implies -fwrapv -fwrapv-pointer, making both signed integer overflow and pointer overflow well-defined.

Clang currently only supports -fno-strict-overflow and -fwrapv, but not -fwrapv-pointer.

This PR proposes to introduce -fwrapv-pointer and adjust the semantics of -fwrapv to match GCC.

This allows signed integer overflow and pointer overflow to be controlled independently, while -fno-strict-overflow still exists to control both at the same time (and that option is consistent across GCC and Clang).

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. labels Jan 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 10, 2025

@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Nikita Popov (nikic)

Changes

GCC supports three flags related to overflow behavior:

  • -fwrapv: Makes signed integer overflow well-defined.
  • -fwrapv-pointer: Makes pointer overflow well-defined.
  • -fno-strict-overflow: Implies -fwrapv -fwrapv-pointer, making both signed integer overflow and pointer overflow well-defined.

Clang currently only supports -fno-strict-overflow and -fwrapv, but not -fwrapv-pointer.

This PR proposes to introduce -fwrapv-pointer and adjust the semantics of -fwrapv to match GCC.

This allows signed integer overflow and pointer overflow to be controlled independently, while -fno-strict-overflow still exists to control both at the same time (and that option is consistent across GCC and Clang).


Full diff: https://github.com/llvm/llvm-project/pull/122486.diff

13 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+11)
  • (modified) clang/include/clang/Basic/LangOptions.def (+1)
  • (modified) clang/include/clang/Driver/Options.td (+5)
  • (modified) clang/lib/CodeGen/CGBuiltin.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+11-11)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+6-6)
  • (modified) clang/lib/Driver/SanitizerArgs.cpp (+3)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+11-4)
  • (modified) clang/lib/Frontend/CompilerInvocation.cpp (+4)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+1-1)
  • (modified) clang/test/CodeGen/integer-overflow.c (+2-11)
  • (modified) clang/test/Driver/clang_wrapv_opts.c (+16-3)
  • (modified) clang/test/Sema/tautological-pointer-comparison.c (+1-1)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 511a28c5554bbb..44d98d98411d12 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -58,6 +58,12 @@ code bases.
   containing strict-aliasing violations. The new default behavior can be
   disabled using ``-fno-pointer-tbaa``.
 
+- The ``-fwrapv`` flag now only makes signed integer overflow well-defined,
+  without affecting pointer overflow, which is controlled by a new
+  ``-fwrapv-pointer`` flag. The ``-fno-strict-overflow`` flag now implies
+  both ``-fwrapv`` and ``-fwrapv-pointer`` and as such retains its old meaning.
+  The new behavior matches GCC.
+
 C/C++ Language Potentially Breaking Changes
 -------------------------------------------
 
@@ -464,6 +470,11 @@ New Compiler Flags
 - clang-cl and clang-dxc now support ``-fdiagnostics-color=[auto|never|always]``
   in addition to ``-f[no-]color-diagnostics``.
 
+- The new ``-fwrapv-pointer`` flag opts-in to a language dialect where pointer
+  overflow is well-defined. The ``-fwrapv`` flag previously implied
+  ``-fwrapv-pointer`` as well, but no longer does. ``-fno-strict-overflow``
+  implies ``-fwrapv -fwrapv-pointer``. The flags now match GCC.
+
 Deprecated Compiler Flags
 -------------------------
 
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 3b833240e5b68c..c4c53d7455c417 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -407,6 +407,7 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0,
              "stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.")
 ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined,
              "signed integer overflow handling")
+LANGOPT(PointerOverflowDefined, 1, 0, "make pointer overflow defined")
 ENUM_LANGOPT(ThreadModel  , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model")
 
 BENIGN_LANGOPT(ArrowDepth, 32, 256,
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 41a7e8c3728066..8b45aa6dd4c2df 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4291,6 +4291,11 @@ def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
   HelpText<"Treat signed integer overflow as two's complement">;
 def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
   Visibility<[ClangOption, CLOption, FlangOption]>;
+def fwrapv_pointer : Flag<["-"], "fwrapv-pointer">, Group<f_Group>,
+  Visibility<[ClangOption, CLOption, CC1Option, FlangOption, FC1Option]>,
+  HelpText<"Treat pointer overflow as two's complement">;
+def fno_wrapv_pointer : Flag<["-"], "fno-wrapv-pointer">, Group<f_Group>,
+  Visibility<[ClangOption, CLOption, FlangOption]>;
 def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Store string literals as writable data">,
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index ca03fb665d423d..b5bbfeae576029 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -22113,7 +22113,7 @@ RValue CodeGenFunction::EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp) {
     // By adding the mask, we ensure that align_up on an already aligned
     // value will not change the value.
     if (Args.Src->getType()->isPointerTy()) {
-      if (getLangOpts().isSignedOverflowDefined())
+      if (getLangOpts().PointerOverflowDefined)
         SrcForMask =
             Builder.CreateGEP(Int8Ty, SrcForMask, Args.Mask, "over_boundary");
       else
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 1bad7a722da07a..dc9c2afeaa93a5 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -4307,14 +4307,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
     // GEP indexes are signed, and scaling an index isn't permitted to
     // signed-overflow, so we use the same semantics for our explicit
     // multiply.  We suppress this if overflow is not undefined behavior.
-    if (getLangOpts().isSignedOverflowDefined()) {
+    if (getLangOpts().PointerOverflowDefined) {
       Idx = Builder.CreateMul(Idx, numElements);
     } else {
       Idx = Builder.CreateNSWMul(Idx, numElements);
     }
 
     Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(),
-                                 !getLangOpts().isSignedOverflowDefined(),
+                                 !getLangOpts().PointerOverflowDefined,
                                  SignedIndices, E->getExprLoc());
 
   } else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
@@ -4404,7 +4404,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
     QualType arrayType = Array->getType();
     Addr = emitArraySubscriptGEP(
         *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
-        E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
+        E->getType(), !getLangOpts().PointerOverflowDefined, SignedIndices,
         E->getExprLoc(), &arrayType, E->getBase());
     EltBaseInfo = ArrayLV.getBaseInfo();
     EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
@@ -4414,7 +4414,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
     auto *Idx = EmitIdxAfterBase(/*Promote*/true);
     QualType ptrType = E->getBase()->getType();
     Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(),
-                                 !getLangOpts().isSignedOverflowDefined(),
+                                 !getLangOpts().PointerOverflowDefined,
                                  SignedIndices, E->getExprLoc(), &ptrType,
                                  E->getBase());
   }
@@ -4561,11 +4561,11 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
                 : llvm::ConstantInt::get(IntPtrTy, ConstLength);
         Idx = Builder.CreateAdd(LowerBoundVal, LengthVal, "lb_add_len",
                                 /*HasNUW=*/false,
-                                !getLangOpts().isSignedOverflowDefined());
+                                !getLangOpts().PointerOverflowDefined);
         if (Length && LowerBound) {
           Idx = Builder.CreateSub(
               Idx, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "idx_sub_1",
-              /*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
+              /*HasNUW=*/false, !getLangOpts().PointerOverflowDefined);
         }
       } else
         Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength + ConstLowerBound);
@@ -4591,7 +4591,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
             Length->getType()->hasSignedIntegerRepresentation());
         Idx = Builder.CreateSub(
             LengthVal, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "len_sub_1",
-            /*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined());
+            /*HasNUW=*/false, !getLangOpts().PointerOverflowDefined);
       } else {
         ConstLength = ConstLength.zextOrTrunc(PointerWidthInBits);
         --ConstLength;
@@ -4618,12 +4618,12 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
     // GEP indexes are signed, and scaling an index isn't permitted to
     // signed-overflow, so we use the same semantics for our explicit
     // multiply.  We suppress this if overflow is not undefined behavior.
-    if (getLangOpts().isSignedOverflowDefined())
+    if (getLangOpts().PointerOverflowDefined)
       Idx = Builder.CreateMul(Idx, NumElements);
     else
       Idx = Builder.CreateNSWMul(Idx, NumElements);
     EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(),
-                                   !getLangOpts().isSignedOverflowDefined(),
+                                   !getLangOpts().PointerOverflowDefined,
                                    /*signedIndices=*/false, E->getExprLoc());
   } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
     // If this is A[i] where A is an array, the frontend will have decayed the
@@ -4643,7 +4643,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
     // Propagate the alignment from the array itself to the result.
     EltPtr = emitArraySubscriptGEP(
         *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
-        ResultExprTy, !getLangOpts().isSignedOverflowDefined(),
+        ResultExprTy, !getLangOpts().PointerOverflowDefined,
         /*signedIndices=*/false, E->getExprLoc());
     BaseInfo = ArrayLV.getBaseInfo();
     TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
@@ -4652,7 +4652,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E,
         emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy,
                                 ResultExprTy, IsLowerBound);
     EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy,
-                                   !getLangOpts().isSignedOverflowDefined(),
+                                   !getLangOpts().PointerOverflowDefined,
                                    /*signedIndices=*/false, E->getExprLoc());
   }
 
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 090c4fb3ea39ee..32395391000ffb 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3037,7 +3037,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
       llvm::Value *numElts = CGF.getVLASize(vla).NumElts;
       if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
       llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
-      if (CGF.getLangOpts().isSignedOverflowDefined())
+      if (CGF.getLangOpts().PointerOverflowDefined)
         value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc");
       else
         value = CGF.EmitCheckedInBoundsGEP(
@@ -3048,7 +3048,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
     } else if (type->isFunctionType()) {
       llvm::Value *amt = Builder.getInt32(amount);
 
-      if (CGF.getLangOpts().isSignedOverflowDefined())
+      if (CGF.getLangOpts().PointerOverflowDefined)
         value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr");
       else
         value =
@@ -3060,7 +3060,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
     } else {
       llvm::Value *amt = Builder.getInt32(amount);
       llvm::Type *elemTy = CGF.ConvertTypeForMem(type);
-      if (CGF.getLangOpts().isSignedOverflowDefined())
+      if (CGF.getLangOpts().PointerOverflowDefined)
         value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr");
       else
         value = CGF.EmitCheckedInBoundsGEP(
@@ -3173,7 +3173,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
     llvm::Value *sizeValue =
       llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
 
-    if (CGF.getLangOpts().isSignedOverflowDefined())
+    if (CGF.getLangOpts().PointerOverflowDefined)
       value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr");
     else
       value = CGF.EmitCheckedInBoundsGEP(
@@ -4067,7 +4067,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
     // signed-overflow, so we use the same semantics for our explicit
     // multiply.  We suppress this if overflow is not undefined behavior.
     llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType());
-    if (CGF.getLangOpts().isSignedOverflowDefined()) {
+    if (CGF.getLangOpts().PointerOverflowDefined) {
       index = CGF.Builder.CreateMul(index, numElements, "vla.index");
       pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
     } else {
@@ -4088,7 +4088,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
   else
     elemTy = CGF.ConvertTypeForMem(elementType);
 
-  if (CGF.getLangOpts().isSignedOverflowDefined())
+  if (CGF.getLangOpts().PointerOverflowDefined)
     return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr");
 
   return CGF.EmitCheckedInBoundsGEP(
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index a0d6919c6dc8d0..3420472c0f75eb 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -575,6 +575,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
                                      options::OPT_fstrict_overflow, false);
         if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S))
           Add &= ~SanitizerKind::SignedIntegerOverflow;
+        if (Args.hasFlagNoClaim(options::OPT_fwrapv_pointer,
+                                options::OPT_fno_wrapv_pointer, S))
+          Add &= ~SanitizerKind::PointerOverflow;
       }
       Add &= Supported;
 
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index f8967890f722cf..8f5c38b38c2f8d 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -3106,12 +3106,19 @@ void tools::renderCommonIntegerOverflowOptions(const ArgList &Args,
                                                ArgStringList &CmdArgs) {
   // -fno-strict-overflow implies -fwrapv if it isn't disabled, but
   // -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
+  bool StrictOverflow = Args.hasFlag(options::OPT_fstrict_overflow,
+                                     options::OPT_fno_strict_overflow, true);
   if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
     if (A->getOption().matches(options::OPT_fwrapv))
       CmdArgs.push_back("-fwrapv");
-  } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
-                                      options::OPT_fno_strict_overflow)) {
-    if (A->getOption().matches(options::OPT_fno_strict_overflow))
-      CmdArgs.push_back("-fwrapv");
+  } else if (!StrictOverflow) {
+    CmdArgs.push_back("-fwrapv");
+  }
+  if (Arg *A = Args.getLastArg(options::OPT_fwrapv_pointer,
+                               options::OPT_fno_wrapv_pointer)) {
+    if (A->getOption().matches(options::OPT_fwrapv_pointer))
+      CmdArgs.push_back("-fwrapv-pointer");
+  } else if (!StrictOverflow) {
+    CmdArgs.push_back("-fwrapv-pointer");
   }
 }
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 39bed84536c6a3..2acb4e49dba70b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3721,6 +3721,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
   } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
     GenerateArg(Consumer, OPT_fwrapv);
   }
+  if (Opts.PointerOverflowDefined)
+    GenerateArg(Consumer, OPT_fwrapv_pointer);
 
   if (Opts.MSCompatibilityVersion != 0) {
     unsigned Major = Opts.MSCompatibilityVersion / 10000000;
@@ -4138,6 +4140,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
   }
   else if (Args.hasArg(OPT_fwrapv))
     Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
+  if (Args.hasArg(OPT_fwrapv_pointer))
+    Opts.PointerOverflowDefined = true;
 
   Opts.MSCompatibilityVersion = 0;
   if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ae40895980d90a..4920688dff398e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11787,7 +11787,7 @@ static std::optional<bool> isTautologicalBoundsCheck(Sema &S, const Expr *LHS,
                                                      const Expr *RHS,
                                                      BinaryOperatorKind Opc) {
   if (!LHS->getType()->isPointerType() ||
-      S.getLangOpts().isSignedOverflowDefined())
+      S.getLangOpts().PointerOverflowDefined)
     return std::nullopt;
 
   // Canonicalize to >= or < predicate.
diff --git a/clang/test/CodeGen/integer-overflow.c b/clang/test/CodeGen/integer-overflow.c
index 9e8cde8b33b16e..9f1eca7e314c26 100644
--- a/clang/test/CodeGen/integer-overflow.c
+++ b/clang/test/CodeGen/integer-overflow.c
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT
 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV
 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV
-// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB,CATCH_UB_POINTER
-// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow -fwrapv | FileCheck %s --check-prefixes=CATCH_UB,NOCATCH_UB_POINTER
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB
+// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow -fwrapv | FileCheck %s --check-prefixes=CATCH_UB
 // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER
 
 
@@ -57,15 +57,6 @@ void test1(void) {
   // TRAPV_HANDLER: foo(
   --a;
   
-  // -fwrapv should turn off inbounds for GEP's, PR9256
-  extern int* P;
-  ++P;
-  // DEFAULT: getelementptr inbounds nuw i32, ptr
-  // WRAPV: getelementptr i32, ptr
-  // TRAPV: getelementptr inbounds nuw i32, ptr
-  // CATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr
-  // NOCATCH_UB_POINTER: getelementptr i32, ptr
-
   // PR9350: char pre-increment never overflows.
   extern volatile signed char PR9350_char_inc;
   // DEFAULT: add i8 {{.*}}, 1
diff --git a/clang/test/Driver/clang_wrapv_opts.c b/clang/test/Driver/clang_wrapv_opts.c
index 826468e0678d0b..c0045b95639b31 100644
--- a/clang/test/Driver/clang_wrapv_opts.c
+++ b/clang/test/Driver/clang_wrapv_opts.c
@@ -1,11 +1,24 @@
 // RUN: %clang -### -S -fwrapv -fno-wrapv -fwrapv %s 2>&1 | FileCheck -check-prefix=CHECK1 %s
 // CHECK1: -fwrapv
 //
+// RUN: %clang -### -S -fwrapv-pointer -fno-wrapv-pointer -fwrapv-pointer %s 2>&1 | FileCheck -check-prefix=CHECK1-POINTER %s
+// CHECK1-POINTER: -fwrapv-pointer
+//
 // RUN: %clang -### -S -fstrict-overflow -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK2 %s
-// CHECK2: -fwrapv
+// CHECK2: -fwrapv{{.*}}-fwrapv-pointer
 //
 // RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s
 // CHECK3: -fwrapv
 //
-// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK4 %s
-// CHECK4-NOT: -fwrapv
+// RUN: %clang -### -S -fwrapv-pointer -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3-POINTER %s
+// CHECK3-POINTER: -fwrapv-pointer
+//
+// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK5 %s
+// CHECK5-NOT: -fwrapv
+// CHECK5: -fwrapv-pointer
+// CHECK5-NOT: -fwrapv
+//
+// RUN: %clang -### -S -fno-wrapv-pointer -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK5-POINTER %s
+// CHECK5-POINTER-NOT: -fwrapv-pointer
+// CHECK5-POINTER: -fwrapv
+// CHECK5-POINTER-NOT: -fwrapv-pointer
diff --git a/clang/test/Sema/tautological-pointer-comparison.c b/clang/test/Sema/tautological-pointer-comparison.c
index 1c5973b01a30d0..f2a944b5305e4e 100644
--- a/clang/test/Sema/tautological-pointer-comparison.c
+++ b/clang/test/Sema/tautological-pointer-comparison.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fwrapv -verify=fwrapv %s
+// RUN: %clang_cc1 -fsyntax-only -fwrapv-pointer -verify=fwrapv %s
 
 // fwrapv-no-diagnostics
 

Copy link

github-actions bot commented Jan 10, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@nikic nikic force-pushed the fwrapv-pointer branch 3 times, most recently from 1f3737d to b32e3e1 Compare January 10, 2025 16:21
@efriedma-quic
Copy link
Collaborator

I'm tempted to say we should just treat -fwrapv/-fwrapv-pointer/-fno-strict-overflow as aliases for each other. I don't think anyone using -fwrapv is going to be happy that we're turning on overflow optimizations.

@nikic nikic requested a review from AaronBallman January 13, 2025 10:13
@nikic
Copy link
Contributor Author

nikic commented Jan 13, 2025

I'm tempted to say we should just treat -fwrapv/-fwrapv-pointer/-fno-strict-overflow as aliases for each other. I don't think anyone using -fwrapv is going to be happy that we're turning on overflow optimizations.

Yeah, I'm not entirely sure this change is worthwhile either. My general thinking here was that we already have the -fno-strict-overflow flag, which works the same on GCC and Clang and disables all overflow optimization. If someone wants to disable pointer overflow optimization and they're using -fwrapv to do that, their code is already broken on GCC. So given that we already have an option that works the same for all compilers and compiler versions, it's best to go for consistency for the rest.

@nico
Copy link
Contributor

nico commented Jan 22, 2025

We (chromium) turned on fwrapv due to the pointer changes, and it had a bit of a perf hit. We'd probably switch to this, hoping it'd address the perf issues at least some.

Matching gcc's behavior for -f flags both compilers have also makes sense, IMHO.

GCC supports three flags related to overflow behavior:
 * `-fwrapv`: Makes signed integer overflow well-defined.
 * `-fwrapv-pointer`: Makes pointer overflow well-defined.
 * `-fno-strict-overflow`: Implies `-fwrapv -fwrapv-pointer`,
   making both signed integer overflow and pointer overflow
   well-defined.

Clang currently only supports `-fno-strict-overflow` and `-fwrapv`,
but not `-fwrapv-pointer`.

This PR proposes to introduce `-fwrapv-pointer` and adjust the
semantics of `-fwrapv` to match GCC.

This allows signed integer overflow and pointer overflow to be
controlled independently, while `-fno-strict-overflow` still
exists to control both at the same time (and that option is
consistent across GCC and Clang).
@carlocab
Copy link
Member

Matching gcc's behavior for -f flags both compilers have also makes sense, IMHO.

Agree with this, FWIW.

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like matching gcc's behavior makes sense for users but I am not sure about the timing for clang-20. This seems like the change in behavior could be impactful.

@nikic
Copy link
Contributor Author

nikic commented Jan 24, 2025

If we want to make this change, I think doing it for Clang 20 would be ideal, because it is related to the pointer overflow optimization changes in that release.

@AaronBallman
Copy link
Collaborator

I am a bit concerned about the behavioral change, but given the more aggressive optimizations in LLVM 20, I think it makes sense to get this into Clang 20 to see what the fallout is during early RCs. If there's negative impact, we can consider cherry-picking a revert from the branch. Matching GCC's behavior for the options seems like a defensible approach.

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look correct to me, but I'd love to hear from the codegen and sanitizer experts as to whether they agree with the changes and the timeline to land it for 20.

to use ``-fwrapv-pointer`` to only make pointer overflow well-defined, while
not affecting the behavior of signed integer overflow.

- The ``-fwrapv`` flag now only makes signed integer overflow well-defined,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curiously enough, we only ever documented the signed integer overflow behavior, not the pointer overflow: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fwrapv

Comment on lines 60 to 67
// -fwrapv should turn off inbounds for GEP's, PR9256
extern int* P;
++P;
// DEFAULT: getelementptr inbounds nuw i32, ptr
// WRAPV: getelementptr i32, ptr
// TRAPV: getelementptr inbounds nuw i32, ptr
// CATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr
// NOCATCH_UB_POINTER: getelementptr i32, ptr
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep the test but update the comment + expected results?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've restored the test. The intent here was to split off the pointer case into pointer-overflow.c, but there's no reason we can't have both...

//
// RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s
// CHECK3: -fwrapv
//
// RUN: %clang -### -S -fwrapv-pointer -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3-POINTER %s
// CHECK3-POINTER: -fwrapv-pointer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a NOT pattern for -fwrapv.

Perhaps use --implicit-check-not=-fwrap so that we don't need a NOT before and a NOT after the positive pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I've switched the last four tests to use --implicit-check-not.

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CC @llvm/clang-vendors : this changes the behavior of -fwrapv.

Internally, I expect it's going to be a bit painful to communicate to all our internal teams that they need to change their -fwrapv usage to -fno-strict-overflow, but if we think it's important to align with gcc in that respect, we can do it, I guess?


The implementation looks correct.

@@ -4311,14 +4311,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E,
// GEP indexes are signed, and scaling an index isn't permitted to
// signed-overflow, so we use the same semantics for our explicit
// multiply. We suppress this if overflow is not undefined behavior.
if (getLangOpts().isSignedOverflowDefined()) {
if (getLangOpts().PointerOverflowDefined) {
Idx = Builder.CreateMul(Idx, numElements);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a gap in the pointer-overflow sanitizer: we should trigger the sanitizer if the multiply overflows. Same issue pops up in a few other places. But you don't need to fix this in this patch, I guess.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #124358 .

Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be used by chromium and other users. There is some gap in sanitizer that is not so important.

LGTM, but other reviewers need to stamp as well.

//
// RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s
// RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s --implicit-check-not="-fwrapv-pointer"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing both -fno-strict-overflow and -fwrapv{-pointer}, perhaps add -Werror to ensure that we don't emit a unused option warning (which would happen if the Driver code forgot to claim an option).

// CHECK4: -fwrapv-pointer
//
// RUN: %clang -### -S -fno-wrapv-pointer -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK4-POINTER %s --implicit-check-not="-fwrapv-pointer"
// CHECK4-POINTER: -fwrapv
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might need "-fwrapv". Otherwise, IIUC even if the output is -fwrap-pointer, the check will pass. Because -fwrapv matches, and the remaining string will pass the --implicit-check-not check.

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@nikic nikic merged commit 1295aa2 into llvm:main Jan 28, 2025
9 checks passed
@nikic nikic deleted the fwrapv-pointer branch January 28, 2025 08:57
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jan 28, 2025

LLVM Buildbot has detected a new failure on builder openmp-offload-libc-amdgpu-runtime running on omp-vega20-1 while building clang at step 7 "Add check check-offload".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/73/builds/12566

Here is the relevant piece of the build log for the reference
Step 7 (Add check check-offload) failure: test (failure)
******************** TEST 'libomptarget :: amdgcn-amd-amdhsa :: mapping/declare_mapper_nested_mappers.cpp' FAILED ********************
Exit Code: 2

Command Output (stdout):
--
# RUN: at line 1
/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/clang++ -fopenmp    -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src  -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib  -fopenmp-targets=amdgcn-amd-amdhsa /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/mapping/declare_mapper_nested_mappers.cpp -o /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/mapping/Output/declare_mapper_nested_mappers.cpp.tmp -Xoffload-linker -lc -Xoffload-linker -lm /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a && /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/mapping/Output/declare_mapper_nested_mappers.cpp.tmp | /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/mapping/declare_mapper_nested_mappers.cpp
# executed command: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/clang++ -fopenmp -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib -fopenmp-targets=amdgcn-amd-amdhsa /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/mapping/declare_mapper_nested_mappers.cpp -o /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/mapping/Output/declare_mapper_nested_mappers.cpp.tmp -Xoffload-linker -lc -Xoffload-linker -lm /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# executed command: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/mapping/Output/declare_mapper_nested_mappers.cpp.tmp
# note: command had no output on stdout or stderr
# error: command failed with exit status: -11
# executed command: /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/mapping/declare_mapper_nested_mappers.cpp
# .---command stderr------------
# | FileCheck error: '<stdin>' is empty.
# | FileCheck command line:  /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-libc-amdgpu-runtime/llvm.src/offload/test/mapping/declare_mapper_nested_mappers.cpp
# `-----------------------------
# error: command failed with exit status: 2

--

********************


aarongable pushed a commit to chromium/chromium that referenced this pull request Jan 28, 2025
In gcc, -fwrapv only controls signed integer overflow, and
-fwrapv-pointer only controls pointer overflow.

In our current clang, -fwrapv controls both, but in a new
clang [1], clang is moving to match gcc.

-fno-strict-overflow controls both signed integer and
pointer overflow. Switch to that to get the same behavior for
new clang (and current clang) that we currently have, and to
also give gcc that behavior.

No intentional behavior change in clang builds. With current
clang, -fwrapv and -fno-strict-overflow should mean the same
thing.

Once we updated to new clang, we can consider using just
-fwrapv-pointer.

1: llvm/llvm-project#122486

Bug: 336282133,384391188,389103111
Change-Id: I6ace8efb4e547ec84ce069c097dce464b15d63ea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207309
Auto-Submit: Nico Weber <[email protected]>
Reviewed-by: Hans Wennborg <[email protected]>
Commit-Queue: Nico Weber <[email protected]>
Commit-Queue: Hans Wennborg <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412288}
aarongable pushed a commit to chromium/chromium that referenced this pull request Jan 28, 2025
This reverts commit dc86334.

Reason for revert:
LUCI Bisection has identified this change as the culprit of a build failure. See the analysis: https://ci.chromium.org/ui/p/chromium/bisection/compile-analysis/b/8724486005851749873

Sample failed build: https://ci.chromium.org/b/8724486005851749873

If this is a false positive, please report it at http://b.corp.google.com/createIssue?component=1199205&description=Analysis%3A+https%3A%2F%2Fchromium-review.googlesource.com%2Fc%2Fchromium%2Fsrc%2F%2B%2F6207309&format=PLAIN&priority=P3&title=Wrongly+blamed+https%3A%2F%2Fci.chromium.org%2Fui%2Fp%2Fchromium%2Fbisection%2Fcompile-analysis%2Fb%2F8724486005851749873&type=BUG

Original change's description:
> build: Use -fno-strict-overflow instead of -fwrapv
>
> In gcc, -fwrapv only controls signed integer overflow, and
> -fwrapv-pointer only controls pointer overflow.
>
> In our current clang, -fwrapv controls both, but in a new
> clang [1], clang is moving to match gcc.
>
> -fno-strict-overflow controls both signed integer and
> pointer overflow. Switch to that to get the same behavior for
> new clang (and current clang) that we currently have, and to
> also give gcc that behavior.
>
> No intentional behavior change in clang builds. With current
> clang, -fwrapv and -fno-strict-overflow should mean the same
> thing.
>
> Once we updated to new clang, we can consider using just
> -fwrapv-pointer.
>
> 1: llvm/llvm-project#122486
>
> Bug: 336282133,384391188,389103111
> Change-Id: I6ace8efb4e547ec84ce069c097dce464b15d63ea
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207309
> Auto-Submit: Nico Weber <[email protected]>
> Reviewed-by: Hans Wennborg <[email protected]>
> Commit-Queue: Nico Weber <[email protected]>
> Commit-Queue: Hans Wennborg <[email protected]>
> Cr-Commit-Position: refs/heads/main@{#1412288}
>

Bug: 336282133,384391188,389103111
Change-Id: I6b6d87fd75059dd782f8a3a16c30a6668e354bb6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6208248
Bot-Commit: [email protected] <[email protected]>
Owners-Override: [email protected] <[email protected]>
Commit-Queue: [email protected] <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412319}
aarongable pushed a commit to chromium/chromium that referenced this pull request Feb 7, 2025
…53-gba476d0b-1 / ad211ced81509462cdfe4c29ed10f97279a0acae-1 : d4bdd1ed551fed0c951eb47b4be2c79d7a02d181-1

Note: this increments the LLVM major version to 21.

Also use -fno-strict-overflow instead of -fwrapv, since the latter
no longer covers pointer overflow [1].

https://chromium.googlesource.com/external/github.com/llvm/llvm-project/+log/29ed6000..ba476d0b

https://chromium.googlesource.com/external/github.com/rust-lang/rust/+log/ad211ced8150..d4bdd1ed551f

Ran: ./tools/clang/scripts/upload_revision.py ba476d0b83dc8a4bbf066dc02a0f73ded27114f0

[1] llvm/llvm-project#122486

Binary-Size: Should be within the limits with new PGO profiles.
Bug: 389103111
Change-Id: I1eb3c31628b58c2d71e3690b967ffad5609d673d
Disable-Rts: True
Cq-Include-Trybots: chromium/try:chromeos-amd64-generic-cfi-thin-lto-rel
Cq-Include-Trybots: chromium/try:dawn-win10-x86-deps-rel
Cq-Include-Trybots: chromium/try:linux-chromeos-dbg
Cq-Include-Trybots: chromium/try:linux_chromium_cfi_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_chromeos_msan_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_msan_rel_ng
Cq-Include-Trybots: chromium/try:mac11-arm64-rel,mac_chromium_asan_rel_ng
Cq-Include-Trybots: chromium/try:ios-catalyst,win-asan,android-official
Cq-Include-Trybots: chromium/try:fuchsia-arm64-cast-receiver-rel
Cq-Include-Trybots: chromium/try:mac-official,linux-official
Cq-Include-Trybots: chromium/try:win-official,win32-official
Cq-Include-Trybots: chromium/try:win-arm64-rel
Cq-Include-Trybots: chromium/try:linux-swangle-try-x64,win-swangle-try-x86
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-arm64-dbg
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-arm64-rel
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-riscv64-dbg
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-riscv64-rel
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-x86-dbg
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-x86-rel
Cq-Include-Trybots: chromium/try:android-cronet-riscv64-dbg
Cq-Include-Trybots: chromium/try:android-cronet-riscv64-rel
Cq-Include-Trybots: chrome/try:iphone-device,ipad-device
Cq-Include-Trybots: chrome/try:linux-chromeos-chrome
Cq-Include-Trybots: chrome/try:win-chrome,win64-chrome,linux-chrome,mac-chrome
Cq-Include-Trybots: chrome/try:linux-pgo,mac-pgo,win32-pgo,win64-pgo
Cq-Include-Trybots: luci.chromium.try:linux-cast-x64-rel
Cq-Include-Trybots: chromium/try:android-rust-arm32-rel
Cq-Include-Trybots: chromium/try:android-rust-arm64-dbg
Cq-Include-Trybots: chromium/try:android-rust-arm64-rel
Cq-Include-Trybots: chromium/try:linux-rust-x64-dbg
Cq-Include-Trybots: chromium/try:linux-rust-x64-rel
Cq-Include-Trybots: chromium/try:mac-rust-x64-dbg
Cq-Include-Trybots: chromium/try:win-rust-x64-dbg
Cq-Include-Trybots: chromium/try:win-rust-x64-rel
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6233983
Reviewed-by: Nico Weber <[email protected]>
Auto-Submit: Hans Wennborg <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1417174}
devsnek pushed a commit to denoland/chromium_build that referenced this pull request Mar 3, 2025
In gcc, -fwrapv only controls signed integer overflow, and
-fwrapv-pointer only controls pointer overflow.

In our current clang, -fwrapv controls both, but in a new
clang [1], clang is moving to match gcc.

-fno-strict-overflow controls both signed integer and
pointer overflow. Switch to that to get the same behavior for
new clang (and current clang) that we currently have, and to
also give gcc that behavior.

No intentional behavior change in clang builds. With current
clang, -fwrapv and -fno-strict-overflow should mean the same
thing.

Once we updated to new clang, we can consider using just
-fwrapv-pointer.

1: llvm/llvm-project#122486

Bug: 336282133,384391188,389103111
Change-Id: I6ace8efb4e547ec84ce069c097dce464b15d63ea
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207309
Auto-Submit: Nico Weber <[email protected]>
Reviewed-by: Hans Wennborg <[email protected]>
Commit-Queue: Nico Weber <[email protected]>
Commit-Queue: Hans Wennborg <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412288}
NOKEYCHECK=True
GitOrigin-RevId: dc86334c39e93197a89a9201475db12f4b42c9c9
devsnek pushed a commit to denoland/chromium_build that referenced this pull request Mar 3, 2025
This reverts commit dc86334c39e93197a89a9201475db12f4b42c9c9.

Reason for revert:
LUCI Bisection has identified this change as the culprit of a build failure. See the analysis: https://ci.chromium.org/ui/p/chromium/bisection/compile-analysis/b/8724486005851749873

Sample failed build: https://ci.chromium.org/b/8724486005851749873

If this is a false positive, please report it at http://b.corp.google.com/createIssue?component=1199205&description=Analysis%3A+https%3A%2F%2Fchromium-review.googlesource.com%2Fc%2Fchromium%2Fsrc%2F%2B%2F6207309&format=PLAIN&priority=P3&title=Wrongly+blamed+https%3A%2F%2Fci.chromium.org%2Fui%2Fp%2Fchromium%2Fbisection%2Fcompile-analysis%2Fb%2F8724486005851749873&type=BUG

Original change's description:
> build: Use -fno-strict-overflow instead of -fwrapv
>
> In gcc, -fwrapv only controls signed integer overflow, and
> -fwrapv-pointer only controls pointer overflow.
>
> In our current clang, -fwrapv controls both, but in a new
> clang [1], clang is moving to match gcc.
>
> -fno-strict-overflow controls both signed integer and
> pointer overflow. Switch to that to get the same behavior for
> new clang (and current clang) that we currently have, and to
> also give gcc that behavior.
>
> No intentional behavior change in clang builds. With current
> clang, -fwrapv and -fno-strict-overflow should mean the same
> thing.
>
> Once we updated to new clang, we can consider using just
> -fwrapv-pointer.
>
> 1: llvm/llvm-project#122486
>
> Bug: 336282133,384391188,389103111
> Change-Id: I6ace8efb4e547ec84ce069c097dce464b15d63ea
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6207309
> Auto-Submit: Nico Weber <[email protected]>
> Reviewed-by: Hans Wennborg <[email protected]>
> Commit-Queue: Nico Weber <[email protected]>
> Commit-Queue: Hans Wennborg <[email protected]>
> Cr-Commit-Position: refs/heads/main@{#1412288}
>

Bug: 336282133,384391188,389103111
Change-Id: I6b6d87fd75059dd782f8a3a16c30a6668e354bb6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6208248
Bot-Commit: [email protected] <[email protected]>
Owners-Override: [email protected] <[email protected]>
Commit-Queue: [email protected] <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1412319}
NOKEYCHECK=True
GitOrigin-RevId: 86a302d2ce8c8ff36047f5700d7737fddb4e9c00
devsnek pushed a commit to denoland/chromium_build that referenced this pull request Mar 3, 2025
…53-gba476d0b-1 / ad211ced81509462cdfe4c29ed10f97279a0acae-1 : d4bdd1ed551fed0c951eb47b4be2c79d7a02d181-1

Note: this increments the LLVM major version to 21.

Also use -fno-strict-overflow instead of -fwrapv, since the latter
no longer covers pointer overflow [1].

https://chromium.googlesource.com/external/github.com/llvm/llvm-project/+log/29ed6000..ba476d0b

https://chromium.googlesource.com/external/github.com/rust-lang/rust/+log/ad211ced8150..d4bdd1ed551f

Ran: ./tools/clang/scripts/upload_revision.py ba476d0b83dc8a4bbf066dc02a0f73ded27114f0

[1] llvm/llvm-project#122486

Binary-Size: Should be within the limits with new PGO profiles.
Bug: 389103111
Change-Id: I1eb3c31628b58c2d71e3690b967ffad5609d673d
Disable-Rts: True
Cq-Include-Trybots: chromium/try:chromeos-amd64-generic-cfi-thin-lto-rel
Cq-Include-Trybots: chromium/try:dawn-win10-x86-deps-rel
Cq-Include-Trybots: chromium/try:linux-chromeos-dbg
Cq-Include-Trybots: chromium/try:linux_chromium_cfi_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_chromeos_msan_rel_ng
Cq-Include-Trybots: chromium/try:linux_chromium_msan_rel_ng
Cq-Include-Trybots: chromium/try:mac11-arm64-rel,mac_chromium_asan_rel_ng
Cq-Include-Trybots: chromium/try:ios-catalyst,win-asan,android-official
Cq-Include-Trybots: chromium/try:fuchsia-arm64-cast-receiver-rel
Cq-Include-Trybots: chromium/try:mac-official,linux-official
Cq-Include-Trybots: chromium/try:win-official,win32-official
Cq-Include-Trybots: chromium/try:win-arm64-rel
Cq-Include-Trybots: chromium/try:linux-swangle-try-x64,win-swangle-try-x86
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-arm64-dbg
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-arm64-rel
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-riscv64-dbg
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-riscv64-rel
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-x86-dbg
Cq-Include-Trybots: chromium/try:android-cronet-mainline-clang-x86-rel
Cq-Include-Trybots: chromium/try:android-cronet-riscv64-dbg
Cq-Include-Trybots: chromium/try:android-cronet-riscv64-rel
Cq-Include-Trybots: chrome/try:iphone-device,ipad-device
Cq-Include-Trybots: chrome/try:linux-chromeos-chrome
Cq-Include-Trybots: chrome/try:win-chrome,win64-chrome,linux-chrome,mac-chrome
Cq-Include-Trybots: chrome/try:linux-pgo,mac-pgo,win32-pgo,win64-pgo
Cq-Include-Trybots: luci.chromium.try:linux-cast-x64-rel
Cq-Include-Trybots: chromium/try:android-rust-arm32-rel
Cq-Include-Trybots: chromium/try:android-rust-arm64-dbg
Cq-Include-Trybots: chromium/try:android-rust-arm64-rel
Cq-Include-Trybots: chromium/try:linux-rust-x64-dbg
Cq-Include-Trybots: chromium/try:linux-rust-x64-rel
Cq-Include-Trybots: chromium/try:mac-rust-x64-dbg
Cq-Include-Trybots: chromium/try:win-rust-x64-dbg
Cq-Include-Trybots: chromium/try:win-rust-x64-rel
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6233983
Reviewed-by: Nico Weber <[email protected]>
Auto-Submit: Hans Wennborg <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1417174}
NOKEYCHECK=True
GitOrigin-RevId: 7c222671e7164bd6b726ef1d8d6e73403ad72559
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants