https://github.com/Zonotora updated https://github.com/llvm/llvm-project/pull/75481
>From b23f9855820196f7ee5741d81f7c408a641a96fd Mon Sep 17 00:00:00 2001 From: Zonotora <zonot...@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 <zonot...@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 <zonot...@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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits