Skip to content
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

Revert "Revert "Revert "[clang][UBSan] Add implicit conversion check for bitfields""" #87562

Merged
merged 1 commit into from
Apr 3, 2024

Conversation

vitalybuka
Copy link
Collaborator

@vitalybuka vitalybuka commented Apr 3, 2024

@llvmbot llvmbot added clang Clang issues not falling into any other category compiler-rt clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen compiler-rt:ubsan Undefined behavior sanitizer compiler-rt:sanitizer labels Apr 3, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 3, 2024

@llvm/pr-subscribers-clang-driver
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-compiler-rt-sanitizer

@llvm/pr-subscribers-clang

Author: Vitaly Buka (vitalybuka)

Changes

Reverts llvm/llvm-project#87529

https://lab.llvm.org/buildbot/#/builders/37/builds/33262 is still broken


Patch is 43.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87562.diff

11 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (-7)
  • (modified) clang/docs/UndefinedBehaviorSanitizer.rst (+5-14)
  • (modified) clang/include/clang/Basic/Sanitizers.def (+10-10)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+2-35)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+32-225)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (-15)
  • (removed) clang/test/CodeGen/ubsan-bitfield-conversion.c (-61)
  • (removed) clang/test/CodeGenCXX/ubsan-bitfield-conversion.cpp (-94)
  • (modified) clang/test/Driver/fsanitize.c (+14-14)
  • (modified) compiler-rt/lib/ubsan/ubsan_handlers.cpp (+10-17)
  • (modified) compiler-rt/lib/ubsan/ubsan_handlers.h (-1)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e4c0e49ed6fc1c..8fc925350849cd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -198,10 +198,6 @@ Non-comprehensive list of changes in this release
 
 New Compiler Flags
 ------------------
-- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
-  sign change.
-- ``-fsanitize=implicit-integer-conversion`` a group that replaces the previous
-  group ``-fsanitize=implicit-conversion``.
 
 - ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-field-initializers``.
   This diagnostic can be disabled to make ``-Wmissing-field-initializers`` behave
@@ -215,9 +211,6 @@ Modified Compiler Flags
 - Added a new diagnostic flag ``-Wreturn-mismatch`` which is grouped under
   ``-Wreturn-type``, and moved some of the diagnostics previously controlled by
   ``-Wreturn-type`` under this new flag. Fixes #GH72116.
-- ``-fsanitize=implicit-conversion`` is now a group for both
-  ``-fsanitize=implicit-integer-conversion`` and
-  ``-fsanitize=implicit-bitfield-conversion``.
 
 - Added ``-Wcast-function-type-mismatch`` under the ``-Wcast-function-type``
   warning group. Moved the diagnostic previously controlled by
diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst
index 531d56e313826c..8f58c92bd2a163 100644
--- a/clang/docs/UndefinedBehaviorSanitizer.rst
+++ b/clang/docs/UndefinedBehaviorSanitizer.rst
@@ -148,11 +148,6 @@ Available checks are:
      Issues caught by this sanitizer are not undefined behavior,
      but are often unintentional.
   -  ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
-  -  ``-fsanitize=implicit-bitfield-conversion``: Implicit conversion from
-     integer of larger bit width to smaller bitfield, if that results in data
-     loss. This includes unsigned/signed truncations and sign changes, similarly
-     to how the ``-fsanitize=implicit-integer-conversion`` group works, but
-     explicitly for bitfields.
   -  ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
      parameter which is declared to never be null.
   -  ``-fsanitize=null``: Use of a null pointer or creation of a null
@@ -198,8 +193,8 @@ Available checks are:
      signed division overflow (``INT_MIN/-1``). Note that checks are still
      added even when ``-fwrapv`` is enabled. This sanitizer does not check for
      lossy implicit conversions performed before the computation (see
-     ``-fsanitize=implicit-integer-conversion``). Both of these two issues are handled
-     by ``-fsanitize=implicit-integer-conversion`` group of checks.
+     ``-fsanitize=implicit-conversion``). Both of these two issues are handled
+     by ``-fsanitize=implicit-conversion`` group of checks.
   -  ``-fsanitize=unreachable``: If control flow reaches an unreachable
      program point.
   -  ``-fsanitize=unsigned-integer-overflow``: Unsigned integer overflow, where
@@ -207,7 +202,7 @@ Available checks are:
      type. Unlike signed integer overflow, this is not undefined behavior, but
      it is often unintentional. This sanitizer does not check for lossy implicit
      conversions performed before such a computation
-     (see ``-fsanitize=implicit-integer-conversion``).
+     (see ``-fsanitize=implicit-conversion``).
   -  ``-fsanitize=vla-bound``: A variable-length array whose bound
      does not evaluate to a positive value.
   -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that it is of
@@ -229,15 +224,11 @@ You can also use the following check groups:
   -  ``-fsanitize=implicit-integer-arithmetic-value-change``: Catches implicit
      conversions that change the arithmetic value of the integer. Enables
      ``implicit-signed-integer-truncation`` and ``implicit-integer-sign-change``.
-  -  ``-fsanitize=implicit-integer-conversion``: Checks for suspicious
-     behavior of implicit integer conversions. Enables
+  -  ``-fsanitize=implicit-conversion``: Checks for suspicious
+     behavior of implicit conversions. Enables
      ``implicit-unsigned-integer-truncation``,
      ``implicit-signed-integer-truncation``, and
      ``implicit-integer-sign-change``.
-  -  ``-fsanitize=implicit-conversion``: Checks for suspicious
-     behavior of implicit conversions. Enables
-     ``implicit-integer-conversion``, and
-     ``implicit-bitfield-conversion``.
   -  ``-fsanitize=integer``: Checks for undefined or suspicious integer
      behavior (e.g. unsigned integer overflow).
      Enables ``signed-integer-overflow``, ``unsigned-integer-overflow``,
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index b228ffd07ee745..c2137e3f61f645 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -163,24 +163,24 @@ SANITIZER_GROUP("implicit-integer-arithmetic-value-change",
                 ImplicitIntegerArithmeticValueChange,
                 ImplicitIntegerSignChange | ImplicitSignedIntegerTruncation)
 
-SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
-                ImplicitIntegerArithmeticValueChange |
-                    ImplicitUnsignedIntegerTruncation)
+SANITIZER("objc-cast", ObjCCast)
 
-// Implicit bitfield sanitizers
-SANITIZER("implicit-bitfield-conversion", ImplicitBitfieldConversion)
+// FIXME:
+//SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
+//                ImplicitIntegerArithmeticValueChange |
+//                    ImplicitUnsignedIntegerTruncation)
+//SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
+//                ImplicitIntegerConversion)
 
 SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
-                ImplicitIntegerConversion |
-                    ImplicitBitfieldConversion)
+                ImplicitIntegerArithmeticValueChange |
+                    ImplicitUnsignedIntegerTruncation)
 
 SANITIZER_GROUP("integer", Integer,
-                ImplicitIntegerConversion | IntegerDivideByZero | Shift |
+                ImplicitConversion | IntegerDivideByZero | Shift |
                     SignedIntegerOverflow | UnsignedIntegerOverflow |
                     UnsignedShiftBase)
 
-SANITIZER("objc-cast", ObjCCast)
-
 SANITIZER("local-bounds", LocalBounds)
 SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
 
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 0c7f48fe00603d..54432353e7420d 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5580,44 +5580,11 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
       break;
     }
 
-    // TODO: Can we de-duplicate this code with the corresponding code in
-    // CGExprScalar, similar to the way EmitCompoundAssignmentLValue works?
-    RValue RV;
-    llvm::Value *Previous = nullptr;
-    QualType SrcType = E->getRHS()->getType();
-    // Check if LHS is a bitfield, if RHS contains an implicit cast expression
-    // we want to extract that value and potentially (if the bitfield sanitizer
-    // is enabled) use it to check for an implicit conversion.
-    if (E->getLHS()->refersToBitField()) {
-      llvm::Value *RHS =
-          EmitWithOriginalRHSBitfieldAssignment(E, Previous, &SrcType);
-      RV = RValue::get(RHS);
-    } else
-      RV = EmitAnyExpr(E->getRHS());
-
+    RValue RV = EmitAnyExpr(E->getRHS());
     LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);
-
     if (RV.isScalar())
       EmitNullabilityCheck(LV, RV.getScalarVal(), E->getExprLoc());
-
-    if (LV.isBitField()) {
-      llvm::Value *Result = nullptr;
-      // If bitfield sanitizers are enabled we want to use the result
-      // to check whether a truncation or sign change has occurred.
-      if (SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
-        EmitStoreThroughBitfieldLValue(RV, LV, &Result);
-      else
-        EmitStoreThroughBitfieldLValue(RV, LV);
-
-      // If the expression contained an implicit conversion, make sure
-      // to use the value before the scalar conversion.
-      llvm::Value *Src = Previous ? Previous : RV.getScalarVal();
-      QualType DstType = E->getLHS()->getType();
-      EmitBitfieldConversionCheck(Src, SrcType, Result, DstType,
-                                  LV.getBitFieldInfo(), E->getExprLoc());
-    } else
-      EmitStoreThroughLValue(RV, LV);
-
+    EmitStoreThroughLValue(RV, LV);
     if (getLangOpts().OpenMP)
       CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
                                                                 E->getLHS());
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index a4ab8a11b867fa..397b4977acc3e9 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -15,7 +15,6 @@
 #include "CGDebugInfo.h"
 #include "CGObjCRuntime.h"
 #include "CGOpenMPRuntime.h"
-#include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "ConstantEmitter.h"
@@ -309,7 +308,6 @@ class ScalarExprEmitter
                                 llvm::Type *DstTy, SourceLocation Loc);
 
   /// Known implicit conversion check kinds.
-  /// This is used for bitfield conversion checks as well.
   /// Keep in sync with the enum of the same name in ubsan_handlers.h
   enum ImplicitConversionCheckKind : unsigned char {
     ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
@@ -1105,21 +1103,6 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
                 {Src, Dst});
 }
 
-static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
-                                             const char *Name,
-                                             CGBuilderTy &Builder) {
-  bool VSigned = VType->isSignedIntegerOrEnumerationType();
-  llvm::Type *VTy = V->getType();
-  if (!VSigned) {
-    // If the value is unsigned, then it is never negative.
-    return llvm::ConstantInt::getFalse(VTy->getContext());
-  }
-  llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
-  return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
-                            llvm::Twine(Name) + "." + V->getName() +
-                                ".negativitycheck");
-}
-
 // Should be called within CodeGenFunction::SanitizerScope RAII scope.
 // Returns 'i1 false' when the conversion Src -> Dst changed the sign.
 static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
@@ -1144,12 +1127,30 @@ EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
   assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
          "either the widths should be different, or the signednesses.");
 
+  // NOTE: zero value is considered to be non-negative.
+  auto EmitIsNegativeTest = [&Builder](Value *V, QualType VType,
+                                       const char *Name) -> Value * {
+    // Is this value a signed type?
+    bool VSigned = VType->isSignedIntegerOrEnumerationType();
+    llvm::Type *VTy = V->getType();
+    if (!VSigned) {
+      // If the value is unsigned, then it is never negative.
+      // FIXME: can we encounter non-scalar VTy here?
+      return llvm::ConstantInt::getFalse(VTy->getContext());
+    }
+    // Get the zero of the same type with which we will be comparing.
+    llvm::Constant *Zero = llvm::ConstantInt::get(VTy, 0);
+    // %V.isnegative = icmp slt %V, 0
+    // I.e is %V *strictly* less than zero, does it have negative value?
+    return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT, V, Zero,
+                              llvm::Twine(Name) + "." + V->getName() +
+                                  ".negativitycheck");
+  };
+
   // 1. Was the old Value negative?
-  llvm::Value *SrcIsNegative =
-      EmitIsNegativeTestHelper(Src, SrcType, "src", Builder);
+  llvm::Value *SrcIsNegative = EmitIsNegativeTest(Src, SrcType, "src");
   // 2. Is the new Value negative?
-  llvm::Value *DstIsNegative =
-      EmitIsNegativeTestHelper(Dst, DstType, "dst", Builder);
+  llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst");
   // 3. Now, was the 'negativity status' preserved during the conversion?
   //    NOTE: conversion from negative to zero is considered to change the sign.
   //    (We want to get 'false' when the conversion changed the sign)
@@ -1244,136 +1245,6 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
                 {Src, Dst});
 }
 
-// Should be called within CodeGenFunction::SanitizerScope RAII scope.
-// Returns 'i1 false' when the truncation Src -> Dst was lossy.
-static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
-                 std::pair<llvm::Value *, SanitizerMask>>
-EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
-                                  QualType DstType, CGBuilderTy &Builder) {
-  bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
-  bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
-
-  ScalarExprEmitter::ImplicitConversionCheckKind Kind;
-  if (!SrcSigned && !DstSigned)
-    Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
-  else
-    Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
-
-  llvm::Value *Check = nullptr;
-  // 1. Extend the truncated value back to the same width as the Src.
-  Check = Builder.CreateIntCast(Dst, Src->getType(), DstSigned, "bf.anyext");
-  // 2. Equality-compare with the original source value
-  Check = Builder.CreateICmpEQ(Check, Src, "bf.truncheck");
-  // If the comparison result is 'i1 false', then the truncation was lossy.
-
-  return std::make_pair(
-      Kind, std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
-}
-
-// Should be called within CodeGenFunction::SanitizerScope RAII scope.
-// Returns 'i1 false' when the conversion Src -> Dst changed the sign.
-static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
-                 std::pair<llvm::Value *, SanitizerMask>>
-EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst,
-                                  QualType DstType, CGBuilderTy &Builder) {
-  // 1. Was the old Value negative?
-  llvm::Value *SrcIsNegative =
-      EmitIsNegativeTestHelper(Src, SrcType, "bf.src", Builder);
-  // 2. Is the new Value negative?
-  llvm::Value *DstIsNegative =
-      EmitIsNegativeTestHelper(Dst, DstType, "bf.dst", Builder);
-  // 3. Now, was the 'negativity status' preserved during the conversion?
-  //    NOTE: conversion from negative to zero is considered to change the sign.
-  //    (We want to get 'false' when the conversion changed the sign)
-  //    So we should just equality-compare the negativity statuses.
-  llvm::Value *Check = nullptr;
-  Check =
-      Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "bf.signchangecheck");
-  // If the comparison result is 'false', then the conversion changed the sign.
-  return std::make_pair(
-      ScalarExprEmitter::ICCK_IntegerSignChange,
-      std::make_pair(Check, SanitizerKind::ImplicitBitfieldConversion));
-}
-
-void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
-                                                  Value *Dst, QualType DstType,
-                                                  const CGBitFieldInfo &Info,
-                                                  SourceLocation Loc) {
-
-  if (!SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
-    return;
-
-  // We only care about int->int conversions here.
-  // We ignore conversions to/from pointer and/or bool.
-  if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType,
-                                                                       DstType))
-    return;
-
-  if (DstType->isBooleanType() || SrcType->isBooleanType())
-    return;
-
-  // This should be truncation of integral types.
-  assert(isa<llvm::IntegerType>(Src->getType()) &&
-         isa<llvm::IntegerType>(Dst->getType()) && "non-integer llvm type");
-
-  // TODO: Calculate src width to avoid emitting code
-  // for unecessary cases.
-  unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits();
-  unsigned DstBits = Info.Size;
-
-  bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
-  bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
-
-  CodeGenFunction::SanitizerScope SanScope(this);
-
-  std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
-            std::pair<llvm::Value *, SanitizerMask>>
-      Check;
-
-  // Truncation
-  bool EmitTruncation = DstBits < SrcBits;
-  // If Dst is signed and Src unsigned, we want to be more specific
-  // about the CheckKind we emit, in this case we want to emit
-  // ICCK_SignedIntegerTruncationOrSignChange.
-  bool EmitTruncationFromUnsignedToSigned =
-      EmitTruncation && DstSigned && !SrcSigned;
-  // Sign change
-  bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
-  bool BothUnsigned = !SrcSigned && !DstSigned;
-  bool LargerSigned = (DstBits > SrcBits) && DstSigned;
-  // We can avoid emitting sign change checks in some obvious cases
-  //   1. If Src and Dst have the same signedness and size
-  //   2. If both are unsigned sign check is unecessary!
-  //   3. If Dst is signed and bigger than Src, either
-  //      sign-extension or zero-extension will make sure
-  //      the sign remains.
-  bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
-
-  if (EmitTruncation)
-    Check =
-        EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
-  else if (EmitSignChange) {
-    assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
-           "either the widths should be different, or the signednesses.");
-    Check =
-        EmitBitfieldSignChangeCheckHelper(Src, SrcType, Dst, DstType, Builder);
-  } else
-    return;
-
-  ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
-  if (EmitTruncationFromUnsignedToSigned)
-    CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
-
-  llvm::Constant *StaticArgs[] = {
-      EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(SrcType),
-      EmitCheckTypeDescriptor(DstType),
-      llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
-      llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)};
-
-  EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs,
-            {Src, Dst});
-}
-
 Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
                                          QualType DstType, llvm::Type *SrcTy,
                                          llvm::Type *DstTy,
@@ -2749,8 +2620,6 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
   llvm::PHINode *atomicPHI = nullptr;
   llvm::Value *value;
   llvm::Value *input;
-  llvm::Value *Previous = nullptr;
-  QualType SrcType = E->getType();
 
   int amount = (isInc ? 1 : -1);
   bool isSubtraction = !isInc;
@@ -2839,8 +2708,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
              "base or promoted) will be signed, or the bitwidths will match.");
     }
     if (CGF.SanOpts.hasOneOf(
-            SanitizerKind::ImplicitIntegerArithmeticValueChange |
-            SanitizerKind::ImplicitBitfieldConversion) &&
+            SanitizerKind::ImplicitIntegerArithmeticValueChange) &&
         canPerformLossyDemotionCheck) {
       // While `x += 1` (for `x` with width less than int) is modeled as
       // promotion+arithmetics+demotion, and we can catch lossy demotion with
@@ -2851,26 +2719,13 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
       // the increment/decrement in the wider type, and finally
       // perform the demotion. This will catch lossy demotions.
 
-      // We have a special case for bitfields defined using all the bits of the
-      // type. In this case we need to do the same trick as for the integer
-      // sanitizer checks, i.e., promotion -> increment/decrement -> demotion.
-
       value = EmitScalarConversion(value, type, promotedType, E->getExprLoc());
       Value *amt = llvm::ConstantInt::get(value->getType(), amount, true);
       value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec");
       // Do pass non-default ScalarConversionOpts so tha...
[truncated]

@vitalybuka vitalybuka merged commit 029e1d7 into main Apr 3, 2024
12 of 13 checks passed
@vitalybuka vitalybuka deleted the revert-87529-revert-87518-revert-75481-main branch April 3, 2024 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen 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 compiler-rt:sanitizer compiler-rt:ubsan Undefined behavior sanitizer compiler-rt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants