Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ New Compiler Flags
- New option ``-fno-sanitize-debug-trap-reasons`` added to disable emitting trap reasons into the debug info when compiling with trapping UBSan (e.g. ``-fsanitize-trap=undefined``).
- New option ``-fsanitize-debug-trap-reasons=`` added to control emitting trap reasons into the debug info when compiling with trapping UBSan (e.g. ``-fsanitize-trap=undefined``).
- New options for enabling allocation token instrumentation: ``-fsanitize=alloc-token``, ``-falloc-token-max=``, ``-fsanitize-alloc-token-fast-abi``, ``-fsanitize-alloc-token-extended``.
- New option for diagnosing division by zero with fixed point numbers (``-ffixed-point``): ``-fsanitize=fixed-point-divide-by-zero``, and a new group that includes it: ``-fsanitize=fixed-point``.
- The ``-resource-dir`` option is now displayed in the list of options shown by ``--help``.

Lanai Support
Expand Down
4 changes: 4 additions & 0 deletions clang/docs/UndefinedBehaviorSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ Available checks are:
- ``-fsanitize=enum``: Load of a value of an enumerated type which
is not in the range of representable values for that enumerated
type.
- ``-fsanitize=fixed-point-divide-by-zero``: Fixed point division by zero
(when compiling with ``-ffixed-point``).
- ``-fsanitize=float-cast-overflow``: Conversion to, from, or
between floating-point types which would overflow the
destination. Because the range of representable values for all
Expand Down Expand Up @@ -224,6 +226,8 @@ You can also use the following check groups:
``nullability-*`` group of checks.
- ``-fsanitize=undefined-trap``: Deprecated alias of
``-fsanitize=undefined``.
- ``-fsanitize=fixed-point``: Checks for undefined behavior with fixed point
values. Enables ``-fsanitize=fixed-point-divide-by-zero``.
- ``-fsanitize=implicit-integer-truncation``: Catches lossy integral
conversions. Enables ``implicit-signed-integer-truncation`` and
``implicit-unsigned-integer-truncation``.
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ FEATURE(array_bounds_sanitizer,
LangOpts.Sanitize.has(SanitizerKind::ArrayBounds))
FEATURE(enum_sanitizer,
LangOpts.Sanitize.has(SanitizerKind::Enum))
FEATURE(fixed_point_divide_by_zero_sanitizer,
LangOpts.Sanitize.has(SanitizerKind::FixedPointDivideByZero))
FEATURE(fixed_point_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::FixedPoint))
FEATURE(float_cast_overflow_sanitizer,
LangOpts.Sanitize.has(SanitizerKind::FloatCastOverflow))
FEATURE(integer_divide_by_zero_sanitizer,
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/Sanitizers.def
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ SANITIZER("array-bounds", ArrayBounds)
SANITIZER("bool", Bool)
SANITIZER("builtin", Builtin)
SANITIZER("enum", Enum)
SANITIZER("fixed-point-divide-by-zero", FixedPointDivideByZero)
SANITIZER_GROUP("fixed-point", FixedPoint, FixedPointDivideByZero)
SANITIZER("float-cast-overflow", FloatCastOverflow)
SANITIZER("float-divide-by-zero", FloatDivideByZero)
SANITIZER("function", Function)
Expand Down Expand Up @@ -149,7 +151,7 @@ SANITIZER("shadow-call-stack", ShadowCallStack)
// ABI or address space layout implications, and only catch undefined behavior.
SANITIZER_GROUP("undefined", Undefined,
Alignment | Bool | Builtin | ArrayBounds | Enum |
FloatCastOverflow |
FixedPoint | FloatCastOverflow |
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no standard fixed point type, so it should not be a part of "undefined"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is part of the N1169 extensions. See #43241 for example. (I'll write a more detailed PR message, but I wanted to make sure the tests pass first.)

IntegerDivideByZero | NonnullAttribute | Null | ObjectSize |
PointerOverflow | Return | ReturnsNonnullAttribute | Shift |
SignedIntegerOverflow | Unreachable | VLABound | Function)
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ enum VariableTypeDescriptorKind : uint16_t {
TK_Float = 0x0001,
/// An _BitInt(N) type.
TK_BitInt = 0x0002,
/// A fixed-point type.
TK_FixedPoint = 0x0003,
/// Any other type. The value representation is unspecified.
TK_Unknown = 0xffff
};
Expand Down Expand Up @@ -3570,8 +3572,8 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
///
/// followed by an array of i8 containing the type name with extra information
/// for BitInt. TypeKind is TK_Integer(0) for an integer, TK_Float(1) for a
/// floating point value, TK_BitInt(2) for BitInt and TK_Unknown(0xFFFF) for
/// anything else.
/// floating point value, TK_BitInt(2) for BitInt, TK_FixedPoint(3) for a
// fixed point value, and TK_Unknown(0xFFFF) for anything else.
llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
// Only emit each type's descriptor once.
if (llvm::Constant *C = CGM.getTypeDescriptorFromMap(T))
Expand Down Expand Up @@ -3603,6 +3605,8 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
} else if (T->isFloatingType()) {
TypeKind = TK_Float;
TypeInfo = getContext().getTypeSize(T);
} else if (T->isFixedPointType()) {
TypeKind = TK_FixedPoint;
}

// Format the type name as if for a diagnostic, including quotes and
Expand Down
13 changes: 12 additions & 1 deletion clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4591,9 +4591,20 @@ Value *ScalarExprEmitter::EmitFixedPointBinOp(const BinOpInfo &op) {
Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
break;
case BO_DivAssign:
case BO_Div:
case BO_Div: {
SanitizerDebugLocation SanScope(&CGF,
{SanitizerKind::SO_FixedPointDivideByZero},
SanitizerHandler::DivremOverflow);
if (CGF.SanOpts.has(SanitizerKind::FixedPointDivideByZero)) {
Value *Zero = llvm::Constant::getNullValue(RHS->getType());
const std::pair<Value *, SanitizerKind::SanitizerOrdinal> Check = {
Builder.CreateICmpNE(RHS, Zero),
SanitizerKind::SO_FixedPointDivideByZero};
EmitBinOpCheck(Check, op);
}
Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
break;
}
case BO_ShlAssign:
case BO_Shl:
Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
Expand Down
16 changes: 16 additions & 0 deletions clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=builtin %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-BUILTIN %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=array-bounds %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ARRAY-BOUNDS %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=enum %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ENUM %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=fixed-point-divide-by-zero %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-FIXED-POINT-DIVIDE-BY-ZERO,CHECK-FIXED-POINT %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=fixed-point %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-FIXED-POINT %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=float-cast-overflow %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-FLOAT-CAST-OVERFLOW %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=integer-divide-by-zero %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-INTEGER-DIVIDE-BY-ZERO %s
// RUN: %clang -E -target x86_64-unknown-linux-gnu -fsanitize=nonnull-attribute %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-NONNULL-ATTRIBUTE %s
Expand Down Expand Up @@ -65,6 +67,18 @@ int EnumSanitizerEnabled();
int EnumSanitizerDisabled();
#endif

#if __has_feature(fixed_point_divide_by_zero_sanitizer)
int FixedPointDivideByZeroSanitizerEnabled();
#else
int FixedPointDivideByZeroSanitizerDisabled();
#endif

#if __has_feature(fixed_point_sanitizer)
int FixedPointSanitizerEnabled();
#else
int FixedPointSanitizerDisabled();
#endif

#if __has_feature(float_cast_overflow_sanitizer)
int FloatCastOverflowSanitizerEnabled();
#else
Expand Down Expand Up @@ -161,6 +175,8 @@ int FunctionSanitizerDisabled();
// CHECK-BUILTIN: BuiltinSanitizerEnabled
// CHECK-ARRAY-BOUNDS: ArrayBoundsSanitizerEnabled
// CHECK-ENUM: EnumSanitizerEnabled
// CHECK-FIXED-POINT-DIVIDE-BY-ZERO: FixedPointDivideByZeroSanitizerEnabled
// CHECK-FIXED-POINT: FixedPointSanitizerEnabled
// CHECK-FLOAT-CAST-OVERFLOW: FloatCastOverflowSanitizerEnabled
// CHECK-INTEGER-DIVIDE-BY-ZERO: IntegerDivideByZeroSanitizerEnabled
// CHECK-NONNULL-ATTRIBUTE: NonnullAttributeSanitizerEnabled
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/ubsan/ubsan_checks.inc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ UBSAN_CHECK(UnsignedIntegerOverflow, "unsigned-integer-overflow",
UBSAN_CHECK(IntegerDivideByZero, "integer-divide-by-zero",
"integer-divide-by-zero")
UBSAN_CHECK(FloatDivideByZero, "float-divide-by-zero", "float-divide-by-zero")
UBSAN_CHECK(FixedPointDivideByZero, "fixed-point-divide-by-zero",
"fixed-point-divide-by-zero")
UBSAN_CHECK(InvalidBuiltin, "invalid-builtin-use", "invalid-builtin-use")
UBSAN_CHECK(InvalidObjCCast, "invalid-objc-cast", "invalid-objc-cast")
UBSAN_CHECK(ImplicitUnsignedIntegerTruncation,
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/ubsan/ubsan_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ static void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS,
ET = ErrorType::SignedIntegerOverflow;
else if (Data->Type.isIntegerTy())
ET = ErrorType::IntegerDivideByZero;
else if (Data->Type.isFixedPointTy())
ET = ErrorType::FixedPointDivideByZero;
else
ET = ErrorType::FloatDivideByZero;

Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/ubsan/ubsan_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class TypeDescriptor {
/// of the type for the signed _BitInt(N) type stored after zero bit after
/// TypeName as 32-bit unsigned integer.
TK_BitInt = 0x0002,
/// A fixed-point type. The value representation is currently empty.
TK_FixedPoint = 0x0003,
/// Any other type. The value representation is unspecified.
TK_Unknown = 0xffff
};
Expand Down Expand Up @@ -164,6 +166,8 @@ class TypeDescriptor {
CHECK(isFloatTy());
return TypeInfo;
}

bool isFixedPointTy() const { return getKind() == TK_FixedPoint; }
};

/// \brief An opaque handle to a value.
Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/test/ubsan/TestCases/FixedPoint/divide-by-zero.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clangxx -DOP="0.0R / 0" -ffixed-point -fsanitize=fixed-point-divide-by-zero %s -o %t1 && %run %t1 2>&1 | FileCheck %s
// RUN: %clangxx -DOP="0.5R / 0" -ffixed-point -fsanitize=fixed-point-divide-by-zero %s -o %t2 && %run %t2 2>&1 | FileCheck %s
// RUN: %clangxx -DOP="0.0R / 0.0R" -ffixed-point -fsanitize=fixed-point-divide-by-zero %s -o %t3 && %run %t3 2>&1 | FileCheck %s
// RUN: %clangxx -DOP="0.5R / 0.0R" -ffixed-point -fsanitize=fixed-point-divide-by-zero %s -o %t4 && %run %t4 2>&1 | FileCheck %s
// RUN: %clangxx -fsanitize=undefined -DOP="_Fract a = 0.5R; a /= 0" -ffixed-point -fsanitize=fixed-point-divide-by-zero %s -o %t5 && %run %t5 2>&1 | FileCheck %s

int main() {
// CHECK: divide-by-zero.cpp:[[@LINE+1]]:3: runtime error: division by zero
OP;
}
Loading