-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[clang] [ubsan] add __has_feature for UBSan checks #148310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] [ubsan] add __has_feature for UBSan checks #148310
Conversation
Created using spr 1.3.4 [skip ci]
Created using spr 1.3.4
|
@llvm/pr-subscribers-clang Author: Florian Mayer (fmayer) ChangesBefore, we could only condition code on whether any UBSan check is Full diff: https://github.com/llvm/llvm-project/pull/148310.diff 2 Files Affected:
diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def
index 14bff8a68846d..75b0072cc0cbe 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -54,6 +54,46 @@ FEATURE(memtag_globals,
FEATURE(xray_instrument, LangOpts.XRayInstrument)
FEATURE(undefined_behavior_sanitizer,
LangOpts.Sanitize.hasOneOf(SanitizerKind::Undefined))
+// These are all part of undefined_behavior_sanitizer:
+FEATURE(alignment_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Alignment))
+FEATURE(bool_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Bool))
+FEATURE(builtin_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Builtin))
+FEATURE(array_bounds_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::ArrayBounds))
+FEATURE(enum_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Enum))
+FEATURE(float_cast_overflow_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::FloatCastOverflow))
+FEATURE(integer_divide_by_zero_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::IntegerDivideByZero))
+FEATURE(nonnull_attribute_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::NonnullAttribute))
+FEATURE(null_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Null))
+FEATURE(object_size_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::ObjectSize))
+FEATURE(pointer_overflow_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::PointerOverflow))
+FEATURE(return_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Return))
+FEATURE(returns_nonnull_attribute_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::ReturnsNonnullAttribute))
+FEATURE(shift_base_sanitizer, LangOpts.Sanitize.has(SanitizerKind::ShiftBase))
+FEATURE(shift_exponent_sanitizer, LangOpts.Sanitize.has(SanitizerKind::ShiftExponent))
+FEATURE(shift_sanitizer,
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::Shift))
+FEATURE(signed_integer_overflow_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::SignedIntegerOverflow))
+FEATURE(unreachable_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Unreachable))
+FEATURE(vla_bound_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::VLABound))
+FEATURE(function_sanitizer,
+ LangOpts.Sanitize.has(SanitizerKind::Function))
+
FEATURE(realtime_sanitizer,
LangOpts.Sanitize.has(SanitizerKind::Realtime))
FEATURE(coverage_sanitizer, LangOpts.SanitizeCoverage)
diff --git a/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp b/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp
index 62e5316dde58e..8cebfb48fe1a8 100644
--- a/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp
+++ b/clang/test/Lexer/has_feature_undefined_behavior_sanitizer.cpp
@@ -1,5 +1,26 @@
// RUN: %clang -E -fsanitize=undefined %s -o - | FileCheck --check-prefix=CHECK-UBSAN %s
-// RUN: %clang -E -fsanitize=alignment %s -o - | FileCheck --check-prefix=CHECK-ALIGNMENT %s
+// RUN: %clang -E -fsanitize=alignment %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ALIGNMENT %s
+// RUN: %clang -E -fsanitize=bool %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-BOOL %s
+// RUN: %clang -E -fsanitize=builtin %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-BUILTIN %s
+// RUN: %clang -E -fsanitize=array-bounds %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ARRAY-BOUNDS %s
+// RUN: %clang -E -fsanitize=enum %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-ENUM %s
+// RUN: %clang -E -fsanitize=float-cast-overflow %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-FLOAT-CAST-OVERFLOW %s
+// RUN: %clang -E -fsanitize=integer-divide-by-zero %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-INTEGER-DIVIDE-BY-ZERO %s
+// RUN: %clang -E -fsanitize=nonnull-attribute %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-NONNULL-ATTRIBUTE %s
+// RUN: %clang -E -fsanitize=null %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-NULL %s
+// object-size is a no-op at O0.
+// RUN: %clang -E -O2 -fsanitize=object-size %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-OBJECT-SIZE %s
+// RUN: %clang -E -fsanitize=pointer-overflow %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-POINTER-OVERFLOW %s
+// RUN: %clang -E -fsanitize=return %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-RETURN %s
+// RUN: %clang -E -fsanitize=returns-nonnull-attribute %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-RETURNS-NONNULL-ATTRIBUTE %s
+// RUN: %clang -E -fsanitize=shift-base %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-SHIFT-BASE,CHECK-SHIFT %s
+// RUN: %clang -E -fsanitize=shift-exponent %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-SHIFT-EXPONENT,CHECK-SHIFT %s
+// RUN: %clang -E -fsanitize=shift %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-SHIFT %s
+// RUN: %clang -E -fsanitize=signed-integer-overflow %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-SIGNED-INTEGER-OVERFLOW %s
+// RUN: %clang -E -fsanitize=unreachable %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-UNREACHABLE %s
+// RUN: %clang -E -fsanitize=vla-bound %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-VLA-BOUND %s
+// RUN: %clang -E -fsanitize=function %s -o - | FileCheck --check-prefixes=CHECK-UBSAN,CHECK-FUNCTION %s
+
// RUN: %clang -E %s -o - | FileCheck --check-prefix=CHECK-NO-UBSAN %s
#if __has_feature(undefined_behavior_sanitizer)
@@ -8,6 +29,145 @@ int UBSanEnabled();
int UBSanDisabled();
#endif
+#if __has_feature(alignment_sanitizer)
+int AlignmentSanitizerEnabled();
+#else
+int AlignmentSanitizerDisabled();
+#endif
+
+#if __has_feature(bool_sanitizer)
+int BoolSanitizerEnabled();
+#else
+int BoolSanitizerDisabled();
+#endif
+
+#if __has_feature(builtin_sanitizer)
+int BuiltinSanitizerEnabled();
+#else
+int BuiltinSanitizerDisabled();
+#endif
+
+#if __has_feature(array_bounds_sanitizer)
+int ArrayBoundsSanitizerEnabled();
+#else
+int ArrayBoundsSanitizerDisabled();
+#endif
+
+#if __has_feature(enum_sanitizer)
+int EnumSanitizerEnabled();
+#else
+int EnumSanitizerDisabled();
+#endif
+
+#if __has_feature(float_cast_overflow_sanitizer)
+int FloatCastOverflowSanitizerEnabled();
+#else
+int FloatCastOverflowSanitizerDisabled();
+#endif
+
+#if __has_feature(integer_divide_by_zero_sanitizer)
+int IntegerDivideByZeroSanitizerEnabled();
+#else
+int IntegerDivideByZeroSanitizerDisabled();
+#endif
+
+#if __has_feature(nonnull_attribute_sanitizer)
+int NonnullAttributeSanitizerEnabled();
+#else
+int NonnullAttributeSanitizerDisabled();
+#endif
+
+#if __has_feature(null_sanitizer)
+int NullSanitizerEnabled();
+#else
+int NullSanitizerDisabled();
+#endif
+
+#if __has_feature(object_size_sanitizer)
+int ObjectSizeSanitizerEnabled();
+#else
+int ObjectSizeSanitizerDisabled();
+#endif
+
+#if __has_feature(pointer_overflow_sanitizer)
+int PointerOverflowSanitizerEnabled();
+#else
+int PointerOverflowSanitizerDisabled();
+#endif
+
+#if __has_feature(return_sanitizer)
+int ReturnSanitizerEnabled();
+#else
+int ReturnSanitizerDisabled();
+#endif
+
+#if __has_feature(returns_nonnull_attribute_sanitizer)
+int ReturnsNonnullAttributeSanitizerEnabled();
+#else
+int ReturnsNonnullAttributeSanitizerDisabled();
+#endif
+
+#if __has_feature(shift_base_sanitizer)
+int ShiftBaseSanitizerEnabled();
+#else
+int ShiftBaseSanitizerDisabled();
+#endif
+
+#if __has_feature(shift_exponent_sanitizer)
+int ShiftExponentSanitizerEnabled();
+#else
+int ShiftExponentSanitizerDisabled();
+#endif
+
+#if __has_feature(shift_sanitizer)
+int ShiftSanitizerEnabled();
+#else
+int ShiftSanitizerDisabled();
+#endif
+
+#if __has_feature(signed_integer_overflow_sanitizer)
+int SignedIntegerOverflowSanitizerEnabled();
+#else
+int SignedIntegerOverflowSanitizerDisabled();
+#endif
+
+#if __has_feature(unreachable_sanitizer)
+int UnreachableSanitizerEnabled();
+#else
+int UnreachableSanitizerDisabled();
+#endif
+
+#if __has_feature(vla_bound_sanitizer)
+int VLABoundSanitizerEnabled();
+#else
+int VLABoundSanitizerDisabled();
+#endif
+
+#if __has_feature(function_sanitizer)
+int FunctionSanitizerEnabled();
+#else
+int FunctionSanitizerDisabled();
+#endif
+
// CHECK-UBSAN: UBSanEnabled
-// CHECK-ALIGNMENT: UBSanEnabled
+// CHECK-ALIGNMENT: AlignmentSanitizerEnabled
+// CHECK-BOOL: BoolSanitizerEnabled
+// CHECK-BUILTIN: BuiltinSanitizerEnabled
+// CHECK-ARRAY-BOUNDS: ArrayBoundsSanitizerEnabled
+// CHECK-ENUM: EnumSanitizerEnabled
+// CHECK-FLOAT-CAST-OVERFLOW: FloatCastOverflowSanitizerEnabled
+// CHECK-INTEGER-DIVIDE-BY-ZERO: IntegerDivideByZeroSanitizerEnabled
+// CHECK-NONNULL-ATTRIBUTE: NonnullAttributeSanitizerEnabled
+// CHECK-NULL: NullSanitizerEnabled
+// CHECK-OBJECT-SIZE: ObjectSizeSanitizerEnabled
+// CHECK-POINTER-OVERFLOW: PointerOverflowSanitizerEnabled
+// CHECK-RETURN: ReturnSanitizerEnabled
+// CHECK-RETURNS-NONNULL-ATTRIBUTE: ReturnsNonnullAttributeSanitizerEnabled
+// CHECK-SHIFT-BASE: ShiftBaseSanitizerEnabled
+// CHECK-SHIFT-EXPONENT: ShiftExponentSanitizerEnabled
+// CHECK-SHIFT: ShiftSanitizerEnabled
+// CHECK-SIGNED-INTEGER-OVERFLOW: SignedIntegerOverflowSanitizerEnabled
+// CHECK-UNREACHABLE: UnreachableSanitizerEnabled
+// CHECK-VLA-BOUND: VLABoundSanitizerEnabled
+// CHECK-FUNCTION: FunctionSanitizerEnabled
// CHECK-NO-UBSAN: UBSanDisabled
|
|
Adding something like: would make this more easily adoptable by developers who need to support both older and newer clang versions, since they could then have: |
|
Why not Though this does seem a kind of haphazard solution to something like |
Created using spr 1.3.4
Good idea dropping the LangOpts, it's cleaner.
|
Created using spr 1.3.4 [skip ci]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#if (!__has_feature(undefined_behavior_sanitizer_finegrained_feature_checks) || __has_feature(bool_sanitizer)) && __has_feature(undefined_behavior_sanitizer)
FWIW, I think this would be easier to understand:
#if __has_feature(bool_sanitizer) || (!__has_feature(undefined_behavior_sanitizer_finegrained_feature_checks) && __has_feature(undefined_behavior_sanitizer))
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/46/builds/19969 Here is the relevant piece of the build log for the reference |
Reverts #148310 Some targets don't support the flags passed in the test
…" (#148322) Reverts llvm/llvm-project#148310 Some targets don't support the flags passed in the test
Before, we could only condition code on whether any UBSan check is
enabled. Add separate features for each of them, now we can do e.g.
__has_feature(array_bounds_sanitizer).