[clang] [compiler-rt] [clang][UBSan] Add implicit conversion check for bitfields (PR #75481)
Axel Lundberg via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 13 12:28:23 PST 2024
https://github.com/Zonotora updated https://github.com/llvm/llvm-project/pull/75481
>From b23f9855820196f7ee5741d81f7c408a641a96fd Mon Sep 17 00:00:00 2001
From: Zonotora <Zonotora at hotmail.com>
Date: Sat, 16 Dec 2023 19:33:21 +0100
Subject: [PATCH 1/3] [clang] Extract negativity check lambda to function
---
clang/lib/CodeGen/CGExprScalar.cpp | 47 ++++++++++++++++--------------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index aa805f291d1757..559b1aa7c51023 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1097,6 +1097,27 @@ void ScalarExprEmitter::EmitIntegerTruncationCheck(Value *Src, QualType SrcType,
{Src, Dst});
}
+static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
+ const char *Name,
+ CGBuilderTy &Builder) {
+ // NOTE: zero value is considered to be non-negative.
+ // 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");
+};
+
// Should be called within CodeGenFunction::SanitizerScope RAII scope.
// Returns 'i1 false' when the conversion Src -> Dst changed the sign.
static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
@@ -1121,30 +1142,12 @@ 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 = EmitIsNegativeTest(Src, SrcType, "src");
+ llvm::Value *SrcIsNegative =
+ EmitIsNegativeTestHelper(Src, SrcType, "src", Builder);
// 2. Is the new Value negative?
- llvm::Value *DstIsNegative = EmitIsNegativeTest(Dst, DstType, "dst");
+ llvm::Value *DstIsNegative =
+ EmitIsNegativeTestHelper(Dst, DstType, "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)
>From bc5fe858dc5f7d52b5c032c9b60a385098932f00 Mon Sep 17 00:00:00 2001
From: Zonotora <Zonotora at hotmail.com>
Date: Sat, 16 Dec 2023 19:36:04 +0100
Subject: [PATCH 2/3] [clang][UBSan] Add implicit conversion check for
bitfields
This patch implements the implicit truncation and implicit
sign change checks for bitfields.
---
clang/docs/ReleaseNotes.rst | 25 ++
clang/docs/UndefinedBehaviorSanitizer.rst | 47 ++-
clang/include/clang/Basic/Sanitizers.def | 34 +-
clang/lib/CodeGen/CGExpr.cpp | 37 +-
clang/lib/CodeGen/CGExprScalar.cpp | 332 +++++++++++++++++-
clang/lib/CodeGen/CodeGenFunction.h | 14 +
.../test/CodeGen/ubsan-bitfield-conversion.c | 32 ++
compiler-rt/lib/ubsan/ubsan_handlers.cpp | 64 +++-
compiler-rt/lib/ubsan/ubsan_handlers.h | 12 +
compiler-rt/lib/ubsan/ubsan_interface.inc | 2 +
10 files changed, 558 insertions(+), 41 deletions(-)
create mode 100644 clang/test/CodeGen/ubsan-bitfield-conversion.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e12a802e2e9ede..eb9aebfd7d25f0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -122,6 +122,26 @@ Non-comprehensive list of changes in this release
New Compiler Flags
------------------
+- ``-fsanitize=implicit-unsigned-bitfield-truncation`` catches implicit
+ unsigned conversions involving bitfields.
+- ``-fsanitize=implicit-signed-bitfield-truncation`` catches implicit
+ signed conversions involving bitfields.
+- ``-fsanitize=implicit-bitfield-sign-change`` catches implicit
+ conversions involving bitfields that result in a sign change.
+- ``-fsanitize=implicit-bitfield-truncation`` a group to include both
+ ``-fsanitize=implicit-unsigned-bitfield-truncation`` and
+ ``-fsanitize=implicit-signed-bitfield-truncation``.
+- ``-fsanitize=implicit-bitfield-arithmetic-value-change`` a group to
+ include both ``implicit-signed-bitfield-truncation`` and
+ ``implicit-bitfield-sign-change``.
+- ``-fsanitize=implicit-bitfield-conversion`` a group to include
+ ``-fsanitize=implicit-unsigned-bitfield-truncation``,
+ ``-fsanitize=implicit-signed-bitfield-truncation`` and
+ ``implicit-bitfield-sign-change``.
+- ``-fsanitize=implicit-integer-conversion`` a group to include
+ ``-fsanitize=implicit-unsigned-integer-truncation``,
+ ``-fsanitize=implicit-signed-integer-truncation`` and
+ ``implicit-integer-sign-change``.
.. _target_os_detail:
@@ -139,6 +159,11 @@ Deprecated Compiler Flags
Modified Compiler Flags
-----------------------
+- ``-fsanitize=implicit-conversion`` is now a group for both
+ ``-fsanitize=implicit-integer-conversion`` and
+ ``-fsanitize=implicit-bitfield-conversion``. Hence,
+ ``-fsanitize=implicit-integer-conversion`` has replaced what previously
+ was ``-fsanitize=implicit-conversion``.
Removed Compiler Flags
-------------------------
diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst
index b8ad3804f18903..856cb726eb4467 100644
--- a/clang/docs/UndefinedBehaviorSanitizer.rst
+++ b/clang/docs/UndefinedBehaviorSanitizer.rst
@@ -148,6 +148,23 @@ 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-unsigned-bitfield-truncation``,
+ ``-fsanitize=implicit-signed-bitfield-truncation``: Implicit conversion from
+ integer of larger bit width to smaller bitfield, if that results in data
+ loss. That is, if the demoted value, after casting back to the original
+ width, is not equal to the original value before the downcast.
+ The ``-fsanitize=implicit-unsigned-bitfield-truncation`` handles conversions
+ between two ``unsigned`` types, while
+ ``-fsanitize=implicit-signed-bitfield-truncation`` handles the rest of the
+ conversions - when either one, or both of the types are signed.
+ Issues caught by these sanitizers are not undefined behavior,
+ but are often unintentional.
+ - ``-fsanitize=implicit-bitfield-sign-change``: Implicit conversion from
+ integer of larger bit width to smaller bitfield, if that changes the
+ sign of the value. That is, if the original value was negative and the
+ new value is positive (or zero), or the original value was positive,
+ and the new value is negative. Issues caught by this sanitizer are not
+ undefined behavior, but are often unintentional.
- ``-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
@@ -192,8 +209,8 @@ Available checks are:
This includes all the checks covered by ``-ftrapv``, as well as checks for
signed division overflow (``INT_MIN/-1``), but not checks for
lossy implicit conversions performed before the computation
- (see ``-fsanitize=implicit-conversion``). Both of these two issues are
- handled by ``-fsanitize=implicit-conversion`` group of checks.
+ (see ``-fsanitize=implicit-integer-conversion``). Both of these two issues are
+ handled by ``-fsanitize=implicit-integer-conversion`` group of checks.
- ``-fsanitize=unreachable``: If control flow reaches an unreachable
program point.
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer overflow, where
@@ -201,7 +218,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-conversion``).
+ (see ``-fsanitize=implicit-integer-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
@@ -213,8 +230,9 @@ Available checks are:
You can also use the following check groups:
- ``-fsanitize=undefined``: All of the checks listed above other than
``float-divide-by-zero``, ``unsigned-integer-overflow``,
- ``implicit-conversion``, ``local-bounds`` and the ``nullability-*`` group
- of checks.
+ ``implicit-integer-conversion``, ``implicit-bitfield-conversion``,
+ ``implicit-conversion``, ``local-bounds`` and the ``nullability-*``
+ group of checks.
- ``-fsanitize=undefined-trap``: Deprecated alias of
``-fsanitize=undefined``.
- ``-fsanitize=implicit-integer-truncation``: Catches lossy integral
@@ -223,11 +241,26 @@ 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-conversion``: Checks for suspicious
- behavior of implicit conversions. Enables
+ - ``-fsanitize=implicit-integer-conversion``: Checks for suspicious
+ behavior of implicit integer conversions. Enables
``implicit-unsigned-integer-truncation``,
``implicit-signed-integer-truncation``, and
``implicit-integer-sign-change``.
+ - ``-fsanitize=implicit-bitfield-truncation``: Catches lossy bitfield
+ conversions. Enables ``implicit-signed-bitfield-truncation`` and
+ ``implicit-unsigned-bitfield-truncation``.
+ - ``-fsanitize=implicit-bitfield-arithmetic-value-change``: Catches implicit
+ conversions that change the arithmetic value of the bitfield. Enables
+ ``implicit-signed-bitfield-truncation`` and ``implicit-bitfield-sign-change``.
+ - ``-fsanitize=implicit-bitfield-conversion``: Checks for suspicious
+ behavior of implicit bitfield conversions. Enables
+ ``implicit-unsigned-bitfield-truncation``,
+ ``implicit-signed-bitfield-truncation``, and
+ ``implicit-bitfield-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 c2137e3f61f645..53f151a4ee681e 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -163,24 +163,38 @@ SANITIZER_GROUP("implicit-integer-arithmetic-value-change",
ImplicitIntegerArithmeticValueChange,
ImplicitIntegerSignChange | ImplicitSignedIntegerTruncation)
-SANITIZER("objc-cast", ObjCCast)
+SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
+ ImplicitIntegerArithmeticValueChange |
+ ImplicitUnsignedIntegerTruncation)
+
+// Implicit bitfield sanitizers
+SANITIZER("implicit-unsigned-bitfield-truncation", ImplicitUnsignedBitfieldTruncation)
+SANITIZER("implicit-signed-bitfield-truncation", ImplicitSignedBitfieldTruncation)
+SANITIZER_GROUP("implicit-bitfield-truncation", ImplicitBitfieldTruncation,
+ ImplicitUnsignedBitfieldTruncation |
+ ImplicitSignedBitfieldTruncation)
+
+SANITIZER("implicit-bitfield-sign-change", ImplicitBitfieldSignChange)
-// FIXME:
-//SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
-// ImplicitIntegerArithmeticValueChange |
-// ImplicitUnsignedIntegerTruncation)
-//SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
-// ImplicitIntegerConversion)
+SANITIZER_GROUP("implicit-bitfield-arithmetic-value-change",
+ ImplicitBitfieldArithmeticValueChange,
+ ImplicitBitfieldSignChange | ImplicitSignedBitfieldTruncation)
+
+SANITIZER_GROUP("implicit-bitfield-conversion", ImplicitBitfieldConversion,
+ ImplicitBitfieldArithmeticValueChange |
+ ImplicitUnsignedBitfieldTruncation)
SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
- ImplicitIntegerArithmeticValueChange |
- ImplicitUnsignedIntegerTruncation)
+ ImplicitIntegerConversion |
+ ImplicitBitfieldConversion)
SANITIZER_GROUP("integer", Integer,
- ImplicitConversion | IntegerDivideByZero | Shift |
+ ImplicitIntegerConversion | 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 4a2f3caad6588c..04ec7dae9b2fa2 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5570,11 +5570,44 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
break;
}
- RValue RV = EmitAnyExpr(E->getRHS());
+ llvm::Value *Previous = nullptr;
+ RValue RV;
+ QualType SrcType = E->getRHS()->getType();
+ // If LHS refers to a bitfield we want to retrieve the value before
+ // implicit conversion between the bitfield type and the RHS type
+ // and evaluate RHS without integer sanitizer checks (if passed)
+ if (auto *ICE = RetrieveImplicitCastExprForBitfieldSanitizer(E)) {
+ SrcType = ICE->getSubExpr()->getType();
+ Previous = EmitScalarExpr(ICE->getSubExpr());
+ // Pass default ScalarConversionOpts so that sanitizer check is
+ // not emitted here
+ llvm::Value *RHS = EmitScalarConversion(Previous, SrcType, ICE->getType(),
+ ICE->getExprLoc());
+ RV = RValue::get(RHS);
+ }
+
+ if (!Previous)
+ RV = EmitAnyExpr(E->getRHS());
+
LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);
+
if (RV.isScalar())
EmitNullabilityCheck(LV, RV.getScalarVal(), E->getExprLoc());
- EmitStoreThroughLValue(RV, LV);
+
+ // Passing a pointer EmitStoreThroughBitfieldLValue will emit the result
+ // If sanitizer checks are not used, we do not use the result
+ // Hence, use EmitStoreThroughLValue instead
+ if (SanOpts.hasOneOf(SanitizerKind::ImplicitBitfieldConversion) &&
+ LV.isBitField() && RV.isScalar()) {
+ llvm::Value *Src = Previous ? Previous : RV.getScalarVal();
+ QualType DstType = E->getLHS()->getType();
+ llvm::Value *Result;
+ EmitStoreThroughBitfieldLValue(RV, LV, &Result);
+ EmitBitfieldConversionCheck(Src, SrcType, Result, DstType,
+ LV.getBitFieldInfo(), E->getExprLoc());
+ } else
+ 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 559b1aa7c51023..e823131c0ac955 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -15,6 +15,7 @@
#include "CGDebugInfo.h"
#include "CGObjCRuntime.h"
#include "CGOpenMPRuntime.h"
+#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "ConstantEmitter.h"
@@ -304,6 +305,7 @@ 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.
@@ -324,6 +326,19 @@ class ScalarExprEmitter
void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
QualType DstType, SourceLocation Loc);
+ /// Emit a check that an [implicit] truncation of a bitfield does not
+ /// discard any bits. It is not UB, so we use the value after truncation.
+ void EmitBitfieldTruncationCheck(Value *Src, QualType SrcType, Value *Dst,
+ QualType DstType, const CGBitFieldInfo &Info,
+ SourceLocation Loc);
+
+ /// Emit a check that an [implicit] conversion of a bitfield does not change
+ /// the sign of the value. It is not UB, so we use the value after conversion.
+ /// NOTE: Src and Dst may be the exact same value! (point to the same thing)
+ void EmitBitfieldSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
+ QualType DstType, const CGBitFieldInfo &Info,
+ SourceLocation Loc);
+
/// Emit a conversion from the specified type to the specified destination
/// type, both of which are LLVM scalar types.
struct ScalarConversionOpts {
@@ -1035,7 +1050,7 @@ EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst,
}
llvm::Value *Check = nullptr;
- // 1. Extend the truncated value back to the same width as the Src.
+ // 1. Convert the Dst back to the same type as Src.
Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned, "anyext");
// 2. Equality-compare with the original source value
Check = Builder.CreateICmpEQ(Check, Src, "truncheck");
@@ -1116,7 +1131,7 @@ static llvm::Value *EmitIsNegativeTestHelper(Value *V, QualType VType,
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.
@@ -1242,6 +1257,228 @@ 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) {
+
+ llvm::Type *SrcTy = Src->getType();
+ llvm::Type *DstTy = Dst->getType();
+ (void)SrcTy; // Only used in assert()
+ (void)DstTy; // Only used in assert()
+
+ // This should be truncation of integral types.
+ assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
+ "non-integer llvm type");
+
+ bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
+ bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
+
+ ScalarExprEmitter::ImplicitConversionCheckKind Kind;
+ SanitizerMask Mask;
+ if (!SrcSigned && !DstSigned) {
+ Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
+ Mask = SanitizerKind::ImplicitUnsignedBitfieldTruncation;
+ } else {
+ Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
+ Mask = SanitizerKind::ImplicitSignedBitfieldTruncation;
+ }
+
+ llvm::Value *Check = nullptr;
+ // 1. Extend the truncated value back to the same width as the Src.
+ Check = Builder.CreateIntCast(Dst, SrcTy, 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, Mask));
+}
+
+void ScalarExprEmitter::EmitBitfieldTruncationCheck(
+ Value *Src, QualType SrcType, Value *Dst, QualType DstType,
+ const CGBitFieldInfo &Info, SourceLocation Loc) {
+
+ if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitBitfieldTruncation))
+ return;
+
+ // TODO: Calculate src width to avoid emitting code
+ // for unecessary cases.
+ unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits();
+ unsigned DstBits = Info.Size;
+ // This must be truncation. Else we do not care.
+ if (SrcBits <= DstBits)
+ return;
+
+ // If the bitfield sign change sanitizer is enabled,
+ // and we are truncating from larger unsigned type to smaller signed type,
+ // let that next sanitizer deal with it.
+ bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
+ bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
+ if (CGF.SanOpts.has(SanitizerKind::ImplicitBitfieldSignChange) &&
+ (!SrcSigned && DstSigned))
+ return;
+
+ CodeGenFunction::SanitizerScope SanScope(&CGF);
+
+ std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
+ std::pair<llvm::Value *, SanitizerMask>>
+ Check = EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType,
+ Builder);
+ // If the comparison result is 'i1 false', then the truncation was lossy.
+
+ llvm::Constant *StaticArgs[] = {
+ CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
+ CGF.EmitCheckTypeDescriptor(DstType),
+ llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
+ llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)};
+ CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitBitfieldConversion,
+ StaticArgs, {Src, Dst});
+}
+
+// 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,
+ unsigned SrcBits, Value *Dst,
+ QualType DstType, unsigned DstBits,
+ CGBuilderTy &Builder) {
+ llvm::Type *SrcTy = Src->getType();
+ llvm::Type *DstTy = Dst->getType();
+ (void)SrcTy; // Only used in assert()
+ (void)DstTy; // Only used in assert()
+
+ // This should be truncation of integral types.
+ assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) &&
+ "non-integer llvm type");
+
+ bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
+ bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
+ (void)SrcSigned; // Only used in assert()
+ (void)DstSigned; // Only used in assert()
+
+ assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
+ "either the widths should be different, or the signednesses.");
+
+ // 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::ImplicitBitfieldSignChange));
+}
+
+void ScalarExprEmitter::EmitBitfieldSignChangeCheck(
+ Value *Src, QualType SrcType, Value *Dst, QualType DstType,
+ const CGBitFieldInfo &Info, SourceLocation Loc) {
+
+ if (!CGF.SanOpts.has(SanitizerKind::ImplicitBitfieldSignChange))
+ return;
+
+ bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType();
+ bool DstSigned = DstType->isSignedIntegerOrEnumerationType();
+ unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits();
+ unsigned DstBits = Info.Size;
+
+ // Now, we do not need to emit the check in *all* of the cases.
+ // We can avoid emitting it in some obvious cases where it would have been
+ // dropped by the opt passes (instcombine) always anyways.
+ // If it's a cast between effectively the same type, no check.
+ // NOTE: this is *not* equivalent to checking the canonical types.
+ if (SrcSigned == DstSigned && SrcBits == DstBits)
+ return;
+ // At least one of the values needs to have signed type.
+ // If both are unsigned, then obviously, neither of them can be negative.
+ if (!SrcSigned && !DstSigned)
+ return;
+ // If the conversion is to *larger* *signed* type, then no check is needed.
+ // Because either sign-extension happens (so the sign will remain),
+ // or zero-extension will happen (the sign bit will be zero.)
+ if ((DstBits > SrcBits) && DstSigned)
+ return;
+ if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedBitfieldTruncation) &&
+ (SrcBits > DstBits) && SrcSigned) {
+ // If the signed integer truncation sanitizer is enabled,
+ // and this is a truncation from signed type, then no check is needed.
+ // Because here sign change check is interchangeable with truncation check.
+ return;
+ }
+ // That's it. We can't rule out any more cases with the data we have.
+
+ CodeGenFunction::SanitizerScope SanScope(&CGF);
+
+ std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
+ std::pair<llvm::Value *, SanitizerMask>>
+ Check;
+
+ // Each of these checks needs to return 'false' when an issue was detected.
+ ImplicitConversionCheckKind CheckKind;
+ llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks;
+ // So we can 'and' all the checks together, and still get 'false',
+ // if at least one of the checks detected an issue.
+
+ Check = EmitBitfieldSignChangeCheckHelper(Src, SrcType, SrcBits, Dst, DstType,
+ DstBits, Builder);
+ CheckKind = Check.first;
+ Checks.emplace_back(Check.second);
+
+ if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedBitfieldTruncation) &&
+ (SrcBits > DstBits) && !SrcSigned && DstSigned) {
+ // If the signed integer truncation sanitizer was enabled,
+ // and we are truncating from larger unsigned type to smaller signed type,
+ // let's handle the case we skipped in that check.
+ Check =
+ EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder);
+ CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
+ Checks.emplace_back(Check.second);
+ // If the comparison result is 'i1 false', then the truncation was lossy.
+ }
+
+ llvm::Constant *StaticArgs[] = {
+ CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType),
+ CGF.EmitCheckTypeDescriptor(DstType),
+ llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
+ llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)};
+ // EmitCheck() will 'and' all the checks together.
+ CGF.EmitCheck(Checks, SanitizerHandler::ImplicitBitfieldConversion,
+ StaticArgs, {Src, Dst});
+}
+
+void CodeGenFunction::EmitBitfieldConversionCheck(Value *Src, QualType SrcType,
+ Value *Dst, QualType DstType,
+ const CGBitFieldInfo &Info,
+ SourceLocation Loc) {
+
+ if (!SanOpts.hasOneOf(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;
+
+ ScalarExprEmitter Scalar(*this);
+ Scalar.EmitBitfieldTruncationCheck(Src, SrcType, Dst, DstType, Info, Loc);
+ Scalar.EmitBitfieldSignChangeCheck(Src, SrcType, Dst, DstType, Info, Loc);
+}
+
Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
QualType DstType, llvm::Type *SrcTy,
llvm::Type *DstTy,
@@ -2560,6 +2797,8 @@ 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;
@@ -2648,7 +2887,8 @@ 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::ImplicitIntegerArithmeticValueChange |
+ SanitizerKind::ImplicitBitfieldArithmeticValueChange) &&
canPerformLossyDemotionCheck) {
// While `x += 1` (for `x` with width less than int) is modeled as
// promotion+arithmetics+demotion, and we can catch lossy demotion with
@@ -2659,13 +2899,27 @@ 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 that sanitizer check is
- // emitted.
+ // emitted if LV is not a bitfield, otherwise the bitfield sanitizer
+ // checks will take care of the conversion.
+ ScalarConversionOpts Opts;
+ if (!LV.isBitField())
+ Opts = ScalarConversionOpts(CGF.SanOpts);
+ else if (CGF.SanOpts.hasOneOf(
+ SanitizerKind::ImplicitBitfieldArithmeticValueChange)) {
+ Previous = value;
+ SrcType = promotedType;
+ }
+
value = EmitScalarConversion(value, promotedType, type, E->getExprLoc(),
- ScalarConversionOpts(CGF.SanOpts));
+ Opts);
// Note that signed integer inc/dec with width less than int can't
// overflow because of promotion rules; we're just eliding a few steps
@@ -2850,9 +3104,12 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
}
// Store the updated result through the lvalue.
- if (LV.isBitField())
+ if (LV.isBitField()) {
+ Value *Src = Previous ? Previous : value;
CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
- else
+ CGF.EmitBitfieldConversionCheck(Src, SrcType, value, E->getType(),
+ LV.getBitFieldInfo(), E->getExprLoc());
+ } else
CGF.EmitStoreThroughLValue(RValue::get(value), LV);
// If this is a postinc, return the value read from memory, otherwise use the
@@ -3357,8 +3614,15 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
// Convert the result back to the LHS type,
// potentially with Implicit Conversion sanitizer check.
- Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc,
- ScalarConversionOpts(CGF.SanOpts));
+ // If LHSLV is a bitfield, use default ScalarConversionOpts
+ // to avoid emit any implicit integer checks
+ Value *Previous = nullptr;
+ if (LHSLV.isBitField()) {
+ Previous = Result;
+ Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc);
+ } else
+ Result = EmitScalarConversion(Result, PromotionTypeCR, LHSTy, Loc,
+ ScalarConversionOpts(CGF.SanOpts));
if (atomicPHI) {
llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
@@ -3377,9 +3641,14 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
// specially because the result is altered by the store, i.e., [C99 6.5.16p1]
// 'An assignment expression has the value of the left operand after the
// assignment...'.
- if (LHSLV.isBitField())
+ if (LHSLV.isBitField()) {
+ Value *Src = Previous ? Previous : Result;
+ QualType SrcType = E->getRHS()->getType();
+ QualType DstType = E->getLHS()->getType();
CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
- else
+ CGF.EmitBitfieldConversionCheck(Src, SrcType, Result, DstType,
+ LHSLV.getBitFieldInfo(), E->getExprLoc());
+ } else
CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
if (CGF.getLangOpts().OpenMP)
@@ -4487,6 +4756,24 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,
E->getExprLoc());
}
+ImplicitCastExpr *CodeGenFunction::RetrieveImplicitCastExprForBitfieldSanitizer(
+ const BinaryOperator *E) {
+ if (E->getLHS()->refersToBitField() &&
+ (SanOpts.hasOneOf(SanitizerKind::ImplicitConversion |
+ SanitizerKind::ImplicitBitfieldConversion))) {
+ // Check if there is an implicit conversion, and visit the sub expr
+ // like VisitCastExpr but without integer sanitizer checks,
+ // then emit scalar conversion with bitfield information
+ if (auto *ICE = dyn_cast<ImplicitCastExpr>(E->getRHS())) {
+ CastKind Kind = ICE->getCastKind();
+ if (Kind == CK_IntegralCast) {
+ return ICE;
+ }
+ }
+ }
+ return nullptr;
+}
+
Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
bool Ignore = TestAndClearIgnoreResultAssign();
@@ -4515,7 +4802,23 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
case Qualifiers::OCL_None:
// __block variables need to have the rhs evaluated first, plus
// this should improve codegen just a little.
- RHS = Visit(E->getRHS());
+ Value *Previous = nullptr;
+ QualType SrcType = E->getRHS()->getType();
+ // If LHS refers to a bitfield we want to retrieve the value before
+ // implicit conversion between the bitfield type and the RHS type
+ // and evaluate RHS without integer sanitizer checks (if passed)
+ if (auto *ICE = CGF.RetrieveImplicitCastExprForBitfieldSanitizer(E)) {
+ SrcType = ICE->getSubExpr()->getType();
+ Previous = Visit(ICE->getSubExpr());
+ // Pass default ScalarConversionOpts so that sanitizer check is
+ // not emitted here
+ RHS = EmitScalarConversion(Previous, SrcType, ICE->getType(),
+ ICE->getExprLoc());
+ }
+
+ if (!Previous)
+ RHS = Visit(E->getRHS());
+
LHS = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
// Store the value into the LHS. Bit-fields are handled specially
@@ -4523,7 +4826,12 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
// 'An assignment expression has the value of the left operand after
// the assignment...'.
if (LHS.isBitField()) {
+ // Use the value returned before conversion
+ Value *Src = Previous ? Previous : RHS;
+ QualType DstType = E->getLHS()->getType();
CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
+ CGF.EmitBitfieldConversionCheck(Src, SrcType, RHS, DstType,
+ LHS.getBitFieldInfo(), E->getExprLoc());
} else {
CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index caa6a327550baa..13484e6d67f8f2 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -120,6 +120,7 @@ enum TypeEvaluationKind {
SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0) \
SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0) \
SANITIZER_CHECK(ImplicitConversion, implicit_conversion, 0) \
+ SANITIZER_CHECK(ImplicitBitfieldConversion, implicit_bitfield_conversion, 0) \
SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0) \
SANITIZER_CHECK(InvalidObjCCast, invalid_objc_cast, 0) \
SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0) \
@@ -2697,6 +2698,19 @@ class CodeGenFunction : public CodeGenTypeCache {
/// expression and compare the result against zero, returning an Int1Ty value.
llvm::Value *EvaluateExprAsBool(const Expr *E);
+ /// Retrieve the implicit cast expression of the rhs in a binary operator
+ /// expression This is used for implicit bitfield conversion checks, which
+ /// must compare with the value before truncation
+ ImplicitCastExpr *
+ RetrieveImplicitCastExprForBitfieldSanitizer(const BinaryOperator *E);
+
+ /// Emit a check that an [implicit] conversion of a bitfield. It is not UB,
+ /// so we use the value after conversion.
+ void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType,
+ llvm::Value *Dst, QualType DstType,
+ const CGBitFieldInfo &Info,
+ SourceLocation Loc);
+
/// EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void EmitIgnoredExpr(const Expr *E);
diff --git a/clang/test/CodeGen/ubsan-bitfield-conversion.c b/clang/test/CodeGen/ubsan-bitfield-conversion.c
new file mode 100644
index 00000000000000..ab346370d24c2e
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-bitfield-conversion.c
@@ -0,0 +1,32 @@
+// RUN: %clang -fsanitize=implicit-bitfield-conversion -target x86_64-linux -S -emit-llvm -o - %s | FileCheck %s
+//
+typedef struct _xx {
+ int x1:3;
+ char x2:2;
+} xx, *pxx;
+
+xx vxx;
+
+// CHECK-LABEL: define{{.*}} void @foo1
+void foo1(int x) {
+ vxx.x1 = x;
+ // CHECK: call void @__ubsan_handle_implicit_bitfield_conversion
+}
+
+// CHECK-LABEL: define{{.*}} void @foo2
+void foo2(int x) {
+ vxx.x2 = x;
+ // CHECK: call void @__ubsan_handle_implicit_bitfield_conversion
+}
+
+// CHECK-LABEL: define{{.*}} void @foo3
+void foo3() {
+ vxx.x1++;
+ // CHECK: call void @__ubsan_handle_implicit_bitfield_conversion
+}
+
+// CHECK-LABEL: define{{.*}} void @foo4
+void foo4(int x) {
+ vxx.x1 += x;
+ // CHECK: call void @__ubsan_handle_implicit_bitfield_conversion
+}
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cpp b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
index 0f16507d5d88f1..2c0fa40009519c 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.cpp
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.cpp
@@ -551,19 +551,15 @@ void __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data,
Die();
}
-static void handleImplicitConversion(ImplicitConversionData *Data,
- ReportOptions Opts, ValueHandle Src,
- ValueHandle Dst) {
- SourceLocation Loc = Data->Loc.acquire();
- ErrorType ET = ErrorType::GenericUB;
-
- const TypeDescriptor &SrcTy = Data->FromType;
- const TypeDescriptor &DstTy = Data->ToType;
+static ErrorType getImplicitConversionError(const TypeDescriptor &SrcTy,
+ const TypeDescriptor &DstTy,
+ unsigned char Kind) {
+ ErrorType ET = ErrorType::GenericUB;
bool SrcSigned = SrcTy.isSignedIntegerTy();
bool DstSigned = DstTy.isSignedIntegerTy();
- switch (Data->Kind) {
+ switch (Kind) {
case ICCK_IntegerTruncation: { // Legacy, no longer used.
// Let's figure out what it should be as per the new types, and upgrade.
// If both types are unsigned, then it's an unsigned truncation.
@@ -588,6 +584,19 @@ static void handleImplicitConversion(ImplicitConversionData *Data,
ET = ErrorType::ImplicitSignedIntegerTruncationOrSignChange;
break;
}
+ return ET;
+}
+
+static void handleImplicitConversion(ImplicitConversionData *Data,
+ ReportOptions Opts, ValueHandle Src,
+ ValueHandle Dst) {
+
+ SourceLocation Loc = Data->Loc.acquire();
+ const TypeDescriptor &SrcTy = Data->FromType;
+ const TypeDescriptor &DstTy = Data->ToType;
+ bool SrcSigned = SrcTy.isSignedIntegerTy();
+ bool DstSigned = DstTy.isSignedIntegerTy();
+ ErrorType ET = getImplicitConversionError(SrcTy, DstTy, Data->Kind);
if (ignoreReport(Loc, Opts, ET))
return;
@@ -595,7 +604,6 @@ static void handleImplicitConversion(ImplicitConversionData *Data,
ScopedReport R(Opts, Loc, ET);
// FIXME: is it possible to dump the values as hex with fixed width?
-
Diag(Loc, DL_Error, ET,
"implicit conversion from type %0 of value %1 (%2-bit, %3signed) to "
"type %4 changed the value to %5 (%6-bit, %7signed)")
@@ -604,6 +612,30 @@ static void handleImplicitConversion(ImplicitConversionData *Data,
<< DstTy.getIntegerBitWidth() << (DstSigned ? "" : "un");
}
+static void
+handleImplicitBitfieldConversion(ImplicitBitfieldConversionData *Data,
+ ReportOptions Opts, ValueHandle Src,
+ ValueHandle Dst) {
+ SourceLocation Loc = Data->Loc.acquire();
+ const TypeDescriptor &SrcTy = Data->FromType;
+ const TypeDescriptor &DstTy = Data->ToType;
+ bool SrcSigned = SrcTy.isSignedIntegerTy();
+ bool DstSigned = DstTy.isSignedIntegerTy();
+ ErrorType ET = getImplicitConversionError(SrcTy, DstTy, Data->Kind);
+
+ if (ignoreReport(Loc, Opts, ET))
+ return;
+
+ ScopedReport R(Opts, Loc, ET);
+ // FIXME: is it possible to dump the values as hex with fixed width?
+ Diag(Loc, DL_Error, ET,
+ "implicit conversion from type %0 of value %1 (%2-bit, %3signed) to "
+ "type %4 changed the value to %5 (%6-bit bitfield, %7signed)")
+ << SrcTy << Value(SrcTy, Src) << SrcTy.getIntegerBitWidth()
+ << (SrcSigned ? "" : "un") << DstTy << Value(DstTy, Dst)
+ << Data->BitfieldBits << (DstSigned ? "" : "un");
+}
+
void __ubsan::__ubsan_handle_implicit_conversion(ImplicitConversionData *Data,
ValueHandle Src,
ValueHandle Dst) {
@@ -617,6 +649,18 @@ void __ubsan::__ubsan_handle_implicit_conversion_abort(
Die();
}
+void __ubsan::__ubsan_handle_implicit_bitfield_conversion(
+ ImplicitBitfieldConversionData *Data, ValueHandle Src, ValueHandle Dst) {
+ GET_REPORT_OPTIONS(false);
+ handleImplicitBitfieldConversion(Data, Opts, Src, Dst);
+}
+void __ubsan::__ubsan_handle_implicit_bitfield_conversion_abort(
+ ImplicitBitfieldConversionData *Data, ValueHandle Src, ValueHandle Dst) {
+ GET_REPORT_OPTIONS(true);
+ handleImplicitBitfieldConversion(Data, Opts, Src, Dst);
+ Die();
+}
+
static void handleInvalidBuiltin(InvalidBuiltinData *Data, ReportOptions Opts) {
SourceLocation Loc = Data->Loc.acquire();
ErrorType ET = ErrorType::InvalidBuiltin;
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.h b/compiler-rt/lib/ubsan/ubsan_handlers.h
index 3bd5046de3d7d1..c734e6cd262d21 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.h
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -153,6 +153,18 @@ struct ImplicitConversionData {
RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src,
ValueHandle Dst)
+struct ImplicitBitfieldConversionData {
+ SourceLocation Loc;
+ const TypeDescriptor &FromType;
+ const TypeDescriptor &ToType;
+ /* ImplicitConversionCheckKind */ unsigned char Kind;
+ unsigned int BitfieldBits;
+};
+
+/// \brief Implict bitfield conversion that changed the value.
+RECOVERABLE(implicit_bitfield_conversion, ImplicitBitfieldConversionData *Data,
+ ValueHandle Src, ValueHandle Dst)
+
/// Known builtin check kinds.
/// Keep in sync with the enum of the same name in CodeGenFunction.h
enum BuiltinCheckKind : unsigned char {
diff --git a/compiler-rt/lib/ubsan/ubsan_interface.inc b/compiler-rt/lib/ubsan/ubsan_interface.inc
index cb27feb5d7e99b..3078cef40236a7 100644
--- a/compiler-rt/lib/ubsan/ubsan_interface.inc
+++ b/compiler-rt/lib/ubsan/ubsan_interface.inc
@@ -25,6 +25,8 @@ INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion)
INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort)
+INTERFACE_FUNCTION(__ubsan_handle_implicit_bitfield_conversion)
+INTERFACE_FUNCTION(__ubsan_handle_implicit_bitfield_conversion_abort)
INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin)
INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin_abort)
INTERFACE_FUNCTION(__ubsan_handle_invalid_objc_cast)
>From 5c3fd873cd988fc34ed9c2ee1d462455ac7cbbd8 Mon Sep 17 00:00:00 2001
From: Zonotora <Zonotora at hotmail.com>
Date: Tue, 13 Feb 2024 21:23:01 +0100
Subject: [PATCH 3/3] [clang][UBSan] Update testcases
Update testcases due to new -fsanitize options regarding bitfields
---
.../catch-alignment-assumption-array.c | 4 +-
...mption-attribute-align_value-on-lvalue.cpp | 2 +-
...tion-attribute-align_value-on-paramvar.cpp | 2 +-
...ibute-alloc_align-on-function-variable.cpp | 2 +-
...tion-attribute-alloc_align-on-function.cpp | 2 +-
...-assume_aligned-on-function-two-params.cpp | 2 +-
...n-attribute-assume_aligned-on-function.cpp | 2 +-
...on-builtin_assume_aligned-polymorphism.cpp | 2 +-
...n_assume_aligned-three-params-variable.cpp | 2 +-
...on-builtin_assume_aligned-three-params.cpp | 2 +-
...tion-builtin_assume_aligned-two-params.cpp | 2 +-
.../catch-alignment-assumption-openmp.cpp | 2 +-
...d-nonzero-offset-when-nullptr-is-defined.c | 2 +-
.../catch-nullptr-and-nonzero-offset.c | 34 ++++++-------
.../CodeGen/catch-pointer-overflow-volatile.c | 2 +-
clang/test/CodeGen/catch-pointer-overflow.c | 16 +++---
clang/test/CodeGen/catch-undef-behavior.c | 50 +++++++++----------
clang/test/Driver/fsanitize.c | 28 +++++------
18 files changed, 79 insertions(+), 79 deletions(-)
diff --git a/clang/test/CodeGen/catch-alignment-assumption-array.c b/clang/test/CodeGen/catch-alignment-assumption-array.c
index 8a39355c0ba017..0510269d926be8 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-array.c
+++ b/clang/test/CodeGen/catch-alignment-assumption-array.c
@@ -21,10 +21,10 @@ void *caller(void) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 1, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 1, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
- // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[ARRAYDECAY]], i64 1) ]
+ // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[ARRAYDECAY]], i64 1) ]
// CHECK-NEXT: ret ptr %[[ARRAYDECAY]]
// CHECK-NEXT: }
return __builtin_assume_aligned(str, 1);
diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
index f038f472f00fd1..e0cd07749389bd 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
@@ -29,7 +29,7 @@ char **load_from_ac_struct(struct ac_struct *x) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[A]], i64 4294967296) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
index bd3c7555ca1477..5f1f7751f747fe 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
@@ -21,7 +21,7 @@ char **passthrough(__attribute__((align_value(0x100000000))) char **x) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-SANITIZE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[X_RELOADED]], i64 4294967296) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
index bf5a150b58909f..7367066197c8bb 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
@@ -83,7 +83,7 @@ passthrough(char **x, unsigned long alignment) {
// CHECK-SANITIZE-TRAP-NEXT: [[TMP3:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
// CHECK-SANITIZE-TRAP-NEXT: br i1 [[MASKCOND]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize !2
// CHECK-SANITIZE-TRAP: trap:
-// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23) #[[ATTR3:[0-9]+]], !nosanitize !2
+// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24) #[[ATTR3:[0-9]+]], !nosanitize !2
// CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize !2
// CHECK-SANITIZE-TRAP: cont:
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 [[TMP1]]) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
index 60a94c1067f512..2fce59527b48ab 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
@@ -80,7 +80,7 @@ passthrough(char **x, unsigned long alignment) {
// CHECK-SANITIZE-TRAP-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[CALL]] to i64, !nosanitize !2
// CHECK-SANITIZE-TRAP-NEXT: br i1 [[MASKCOND]], label [[CONT:%.*]], label [[TRAP:%.*]], !nosanitize !2
// CHECK-SANITIZE-TRAP: trap:
-// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23) #[[ATTR3:[0-9]+]], !nosanitize !2
+// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24) #[[ATTR3:[0-9]+]], !nosanitize !2
// CHECK-SANITIZE-TRAP-NEXT: unreachable, !nosanitize !2
// CHECK-SANITIZE-TRAP: cont:
// CHECK-SANITIZE-TRAP-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[CALL]], i64 128) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
index 3114bfa8e87023..52ea8882d8bc13 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
@@ -33,7 +33,7 @@ char **caller(char **x) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 42){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 42){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[X_RETURNED]], i64 4294967296, i64 42) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp b/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
index 6c31fb26532bf0..4a3adf90bc7331 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
@@ -33,7 +33,7 @@ char **caller(char **x) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 128, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 128, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-SANITIZE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[X_RETURNED]], i64 128) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp
index a5b969d3cbc0c0..9cd0e80759c869 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp
@@ -47,7 +47,7 @@ void *f(C *c) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 8, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 8, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT1]]:
// CHECK-SANITIZE-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[CAST_RESULT]], i64 8) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
index 7ee9906e7c56df..64f1d647868b15 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
@@ -24,7 +24,7 @@ void *caller(char **x, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 %[[OFFSET_RELOADED]]){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[X_RELOADED]], i64 4294967296, i64 %[[OFFSET_RELOADED]]) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
index f5294f99dde428..76e5c170e9b2a9 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
@@ -21,7 +21,7 @@ void *caller(char **x) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 42){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 42){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[X_RELOADED]], i64 4294967296, i64 42) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
index 7022653d06cb68..5f53816276ee21 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
@@ -20,7 +20,7 @@ void *caller(char **x) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[X_RELOADED]], i64 4294967296) ]
diff --git a/clang/test/CodeGen/catch-alignment-assumption-openmp.cpp b/clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
index 30ebeee2c18d7c..5bab2feea05adc 100644
--- a/clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
+++ b/clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
@@ -20,7 +20,7 @@ void func(char *data) {
// CHECK-SANITIZE: [[HANDLER_ALIGNMENT_ASSUMPTION]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_alignment_assumption_abort(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_alignment_assumption(ptr @[[LINE_100_ALIGNMENT_ASSUMPTION]], i64 %[[PTRINT_DUP]], i64 4294967296, i64 0){{.*}}, !nosanitize
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 23){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 24){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr %[[DATA_RELOADED]], i64 4294967296) ]
diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c
index 39ede01d6e3b83..631d43f9ffff18 100644
--- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c
+++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset-when-nullptr-is-defined.c
@@ -54,7 +54,7 @@ char *add_unsigned(char *base, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
diff --git a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
index 015102940890a5..0e39eb6ecf8cf9 100644
--- a/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
+++ b/clang/test/CodeGen/catch-nullptr-and-nonzero-offset.c
@@ -69,7 +69,7 @@ char *var_var(char *base, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -96,7 +96,7 @@ char *var_zero(char *base) {
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_200]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_200]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-C-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE-C: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -125,7 +125,7 @@ char *var_one(char *base) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_300]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_300]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -154,7 +154,7 @@ char *var_allones(char *base) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_400]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_400]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -188,7 +188,7 @@ char *nullptr_var(unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_500]], i64 0, i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_500]], i64 0, i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -204,7 +204,7 @@ char *nullptr_zero(void) {
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_600]], i64 0, i64 0)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_600]], i64 0, i64 0)
- // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-C-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE-C: [[CONT]]:
// CHECK-NEXT: ret ptr null
@@ -222,7 +222,7 @@ char *nullptr_one_BAD(void) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_700]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 1) to i64))
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr null, i64 1)
@@ -240,7 +240,7 @@ char *nullptr_allones_BAD(void) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_800]], i64 0, i64 ptrtoint (ptr getelementptr inbounds (i8, ptr null, i64 -1) to i64))
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr null, i64 -1)
@@ -275,7 +275,7 @@ char *one_var(unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_900]], i64 1, i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_900]], i64 1, i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -291,7 +291,7 @@ char *one_zero(void) {
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1000]], i64 1, i64 1)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1000]], i64 1, i64 1)
- // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-C-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE-C: [[CONT]]:
// CHECK-NEXT: ret ptr inttoptr (i64 1 to ptr)
@@ -310,7 +310,7 @@ char *one_one_OK(void) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1100]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1) to i64), i64 1), i64 1))
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 1)
@@ -329,7 +329,7 @@ char *one_allones_BAD(void) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1200]], i64 1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1) to i64), i64 1), i64 1))
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 1 to ptr), i64 -1)
@@ -364,7 +364,7 @@ char *allones_var(unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1300]], i64 -1, i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1300]], i64 -1, i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -380,7 +380,7 @@ char *allones_zero_OK(void) {
// CHECK-SANITIZE-C: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1400]], i64 -1, i64 -1)
// CHECK-SANITIZE-RECOVER-C-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1400]], i64 -1, i64 -1)
- // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-C-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-C-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE-C: [[CONT]]:
// CHECK-NEXT: ret ptr inttoptr (i64 -1 to ptr)
@@ -399,7 +399,7 @@ char *allones_one_BAD(void) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1500]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1) to i64), i64 -1), i64 -1))
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 1)
@@ -418,7 +418,7 @@ char *allones_allones_OK(void) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1600]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1))
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1600]], i64 -1, i64 add (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1) to i64), i64 -1), i64 -1))
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr inttoptr (i64 -1 to ptr), i64 -1)
@@ -462,7 +462,7 @@ char *void_ptr(void *base, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_1700]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_1700]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
diff --git a/clang/test/CodeGen/catch-pointer-overflow-volatile.c b/clang/test/CodeGen/catch-pointer-overflow-volatile.c
index 4b0653a0ae59ec..c69ec41c23afac 100644
--- a/clang/test/CodeGen/catch-pointer-overflow-volatile.c
+++ b/clang/test/CodeGen/catch-pointer-overflow-volatile.c
@@ -42,7 +42,7 @@ char *volatile_ptr(char *volatile base, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
diff --git a/clang/test/CodeGen/catch-pointer-overflow.c b/clang/test/CodeGen/catch-pointer-overflow.c
index 899af73bd81e00..7c5c70cffc99cf 100644
--- a/clang/test/CodeGen/catch-pointer-overflow.c
+++ b/clang/test/CodeGen/catch-pointer-overflow.c
@@ -49,7 +49,7 @@ char *add_unsigned(char *base, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_100]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -86,7 +86,7 @@ char *sub_unsigned(char *base, unsigned long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_200]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_200]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -125,7 +125,7 @@ char *add_signed(char *base, signed long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_300]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_300]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -165,7 +165,7 @@ char *sub_signed(char *base, signed long offset) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_400]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_400]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: ret ptr %[[ADD_PTR]]
@@ -193,7 +193,7 @@ char *postinc(char *base) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_500]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_500]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: store ptr %[[ADD_PTR]], ptr %[[BASE_ADDR]], align 8
@@ -224,7 +224,7 @@ char *postdec(char *base) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_600]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_600]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: store ptr %[[ADD_PTR]], ptr %[[BASE_ADDR]], align 8
@@ -255,7 +255,7 @@ char *preinc(char *base) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_700]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_700]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: store ptr %[[ADD_PTR]], ptr %[[BASE_ADDR]], align 8
@@ -286,7 +286,7 @@ char *predec(char *base) {
// CHECK-SANITIZE: [[HANDLER_POINTER_OVERFLOW]]:
// CHECK-SANITIZE-NORECOVER-NEXT: call void @__ubsan_handle_pointer_overflow_abort(ptr @[[LINE_800]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
// CHECK-SANITIZE-RECOVER-NEXT: call void @__ubsan_handle_pointer_overflow(ptr @[[LINE_800]], i64 %[[BASE_RELOADED_INT]], i64 %[[COMPUTED_GEP]])
- // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 19){{.*}}, !nosanitize
+ // CHECK-SANITIZE-TRAP-NEXT: call void @llvm.ubsantrap(i8 20){{.*}}, !nosanitize
// CHECK-SANITIZE-UNREACHABLE-NEXT: unreachable, !nosanitize
// CHECK-SANITIZE: [[CONT]]:
// CHECK-NEXT: store ptr %[[ADD_PTR]], ptr %[[BASE_ADDR]], align 8
diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c
index af37ef9e8565b1..2943212693533c 100644
--- a/clang/test/CodeGen/catch-undef-behavior.c
+++ b/clang/test/CodeGen/catch-undef-behavior.c
@@ -44,7 +44,7 @@ void foo(void) {
// CHECK-UBSAN: %[[ARG:.*]] = ptrtoint {{.*}} %[[PTR]] to i64
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_100]], i64 %[[ARG]])
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW:#[0-9]+]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23) [[NR_NUW:#[0-9]+]]
// CHECK-TRAP-NEXT: unreachable
#line 100
u.i=1;
@@ -61,7 +61,7 @@ int bar(int *a) {
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_200]], i64 %[[PTRINT]])
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23) [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable
#line 200
@@ -97,7 +97,7 @@ int lsh_overflow(int a, int b) {
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_shift_out_of_bounds(ptr @[[LINE_300]], i64 %[[ARG1]], i64 %[[ARG2]])
// CHECK-UBSAN-NOT: call void @__ubsan_handle_shift_out_of_bounds
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 20) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 21) [[NR_NUW]]
// CHECK-TRAP: unreachable
// CHECK-TRAP-NOT: call void @llvm.ubsantrap
@@ -116,7 +116,7 @@ int rsh_inbounds(int a, int b) {
// CHECK-UBSAN-NEXT: %[[ARG2:.*]] = zext
// CHECK-UBSAN-NEXT: call void @__ubsan_handle_shift_out_of_bounds(ptr @[[LINE_400]], i64 %[[ARG1]], i64 %[[ARG2]])
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 20) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 21) [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable
// CHECK-COMMON: %[[RET:.*]] = ashr i32 {{.*}}, %[[RHS]]
@@ -129,7 +129,7 @@ int rsh_inbounds(int a, int b) {
int load(int *p) {
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_500]], i64 %{{.*}})
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23) [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable
#line 500
return *p;
@@ -139,7 +139,7 @@ int load(int *p) {
void store(int *p, int q) {
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_600]], i64 %{{.*}})
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23) [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable
#line 600
*p = q;
@@ -151,7 +151,7 @@ struct S { int k; };
int *member_access(struct S *p) {
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_700]], i64 %{{.*}})
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23) [[NR_NUW]]
// CHECK-TRAP-NEXT: unreachable
#line 700
return &p->k;
@@ -289,7 +289,7 @@ signed char fp16_char_overflow(__fp16 *p) {
// CHECK-COMMON-LABEL: @float_float_overflow
float float_float_overflow(double f) {
// CHECK-UBSAN-NOT: call {{.*}} @__ubsan_handle_float_cast_overflow(
- // CHECK-TRAP-NOT: call {{.*}} @llvm.ubsantrap(i8 19) [[NR_NUW]]
+ // CHECK-TRAP-NOT: call {{.*}} @llvm.ubsantrap(i8 20) [[NR_NUW]]
// CHECK-COMMON: }
return f;
}
@@ -326,7 +326,7 @@ _Bool sour_bool(_Bool *p) {
// CHECK-UBSAN: call void @__ubsan_handle_load_invalid_value(ptr {{.*}}, i64 {{.*}})
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 10) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 11) [[NR_NUW]]
// CHECK-TRAP: unreachable
return *p;
}
@@ -339,7 +339,7 @@ int *ret_nonnull(int *a) {
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_return
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 17) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 18) [[NR_NUW]]
// CHECK-TRAP: unreachable
return a;
}
@@ -352,7 +352,7 @@ void call_decl_nonnull(int *a) {
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) [[NR_NUW]]
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17) [[NR_NUW]]
// CHECK-TRAP: unreachable
decl_nonnull(a);
}
@@ -363,12 +363,12 @@ extern void *memcpy(void *, const void *, unsigned long) __attribute__((nonnull(
void call_memcpy_nonnull(void *p, void *q, int sz) {
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON-NOT: call
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON-NOT: call
// CHECK-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %0, ptr align 1 %1, i64 %conv, i1 false)
@@ -379,19 +379,19 @@ void call_memcpy_nonnull(void *p, void *q, int sz) {
void call_memcpy(long *p, short *q, int sz) {
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON: and i64 %[[#]], 7, !nosanitize
// CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(ptr @[[LINE_1600]]
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23)
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON: and i64 %[[#]], 1, !nosanitize
// CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23)
// CHECK-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %0, ptr align 2 %1, i64 %conv, i1 false)
@@ -408,12 +408,12 @@ void call_memcpy_inline(long *p, short *q) {
// CHECK-COMMON: and i64 %[[#]], 7, !nosanitize
// CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23)
// CHECK-COMMON: and i64 %[[#]], 1, !nosanitize
// CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23)
// CHECK-COMMON: call void @llvm.memcpy.inline.p0.p0.i64(ptr align 8 %0, ptr align 2 %1, i64 2, i1 false)
__builtin_memcpy_inline(p, q, 2);
@@ -425,11 +425,11 @@ extern void *memmove(void *, const void *, unsigned long) __attribute__((nonnull
void call_memmove_nonnull(void *p, void *q, int sz) {
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
memmove(p, q, sz);
}
@@ -437,19 +437,19 @@ void call_memmove_nonnull(void *p, void *q, int sz) {
void call_memmove(long *p, short *q, int sz) {
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON: and i64 %[[#]], 7, !nosanitize
// CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23)
// CHECK-COMMON: icmp ne ptr {{.*}}, null
// CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 17)
// CHECK-COMMON: and i64 %[[#]], 1, !nosanitize
// CHECK-COMMON: icmp eq i64 %[[#]], 0, !nosanitize
// CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(
- // CHECK-TRAP: call void @llvm.ubsantrap(i8 22)
+ // CHECK-TRAP: call void @llvm.ubsantrap(i8 23)
// CHECK-COMMON: call void @llvm.memmove.p0.p0.i64(ptr align 8 %0, ptr align 2 %1, i64 %conv, i1 false)
memmove(p, q, sz);
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index 1671825042c323..571f79a6e7f70d 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -35,20 +35,20 @@
// RUN: %clang --target=%itanium_abi_triple -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER -implicit-check-not="-fsanitize-address-use-after-scope"
// CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change|unsigned-shift-base),?){9}"}}
-// RUN: %clang -fsanitize=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-RECOVER
-// RUN: %clang -fsanitize=implicit-conversion -fsanitize-recover=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-RECOVER
-// RUN: %clang -fsanitize=implicit-conversion -fno-sanitize-recover=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-NORECOVER
-// RUN: %clang -fsanitize=implicit-conversion -fsanitize-trap=implicit-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-conversion,CHECK-implicit-conversion-TRAP
-// CHECK-implicit-conversion: "-fsanitize={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-RECOVER: "-fsanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-RECOVER-NOT: "-fno-sanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-RECOVER-NOT: "-fsanitize-trap={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-NORECOVER-NOT: "-fno-sanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}} // ???
-// CHECK-implicit-conversion-NORECOVER-NOT: "-fsanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-NORECOVER-NOT: "-fsanitize-trap={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-TRAP: "-fsanitize-trap={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-TRAP-NOT: "-fsanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
-// CHECK-implicit-conversion-TRAP-NOT: "-fno-sanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// RUN: %clang -fsanitize=implicit-integer-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-integer-conversion,CHECK-implicit-integer-conversion-RECOVER
+// RUN: %clang -fsanitize=implicit-integer-conversion -fsanitize-recover=implicit-integer-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-integer-conversion,CHECK-implicit-integer-conversion-RECOVER
+// RUN: %clang -fsanitize=implicit-integer-conversion -fno-sanitize-recover=implicit-integer-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-integer-conversion,CHECK-implicit-integer-conversion-NORECOVER
+// RUN: %clang -fsanitize=implicit-integer-conversion -fsanitize-trap=implicit-integer-conversion %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-integer-conversion,CHECK-implicit-integer-conversion-TRAP
+// CHECK-implicit-integer-conversion: "-fsanitize={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-RECOVER: "-fsanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-RECOVER-NOT: "-fno-sanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-RECOVER-NOT: "-fsanitize-trap={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-NORECOVER-NOT: "-fno-sanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}} // ???
+// CHECK-implicit-integer-conversion-NORECOVER-NOT: "-fsanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-NORECOVER-NOT: "-fsanitize-trap={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-TRAP: "-fsanitize-trap={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-TRAP-NOT: "-fsanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
+// CHECK-implicit-integer-conversion-TRAP-NOT: "-fno-sanitize-recover={{((implicit-unsigned-integer-truncation|implicit-signed-integer-truncation|implicit-integer-sign-change),?){3}"}}
// RUN: %clang -fsanitize=implicit-integer-arithmetic-value-change %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-integer-arithmetic-value-change,CHECK-implicit-integer-arithmetic-value-change-RECOVER
// RUN: %clang -fsanitize=implicit-integer-arithmetic-value-change -fsanitize-recover=implicit-integer-arithmetic-value-change %s -### 2>&1 | FileCheck %s --check-prefixes=CHECK-implicit-integer-arithmetic-value-change,CHECK-implicit-integer-arithmetic-value-change-RECOVER
More information about the cfe-commits
mailing list