Skip to content

Commit 038731c

Browse files
authored
[ubsan] Remove -fsanitizer=vptr from -fsanitizer=undefined (#121115)
This makes `undefined` more consistent. `vptr` check adds additional constraints: 1. trap is off, or silently disabled 2. rtti is no, or compilation error 3. c++abi, or linking error So it's not obvious if `-fsanitizer=undefined` will have it on. https://discourse.llvm.org/t/rfc-remove-vptr-from-undefined/83830
1 parent 75270e3 commit 038731c

File tree

6 files changed

+101
-38
lines changed

6 files changed

+101
-38
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,8 @@ Moved checkers
388388
Sanitizers
389389
----------
390390

391+
- ``-fsanitize=vptr`` is no longer a part of ``-fsanitize=undefined``.
392+
391393
Python Binding Changes
392394
----------------------
393395
- Added ``Type.get_methods``, a binding for ``clang_visitCXXMethods``, which

clang/docs/UndefinedBehaviorSanitizer.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,14 @@ Available checks are:
214214
the wrong dynamic type, or that its lifetime has not begun or has ended.
215215
Incompatible with ``-fno-rtti``. Link must be performed by ``clang++``, not
216216
``clang``, to make sure C++-specific parts of the runtime library and C++
217-
standard libraries are present.
217+
standard libraries are present. The check is not a part of the ``undefined``
218+
group. Also it does not support ``-fsanitize-trap=vptr``.
218219

219220
You can also use the following check groups:
220221
- ``-fsanitize=undefined``: All of the checks listed above other than
221222
``float-divide-by-zero``, ``unsigned-integer-overflow``,
222-
``implicit-conversion``, ``local-bounds`` and the ``nullability-*`` group
223-
of checks.
223+
``implicit-conversion``, ``local-bounds``, ``vptr`` and the
224+
``nullability-*`` group of checks.
224225
- ``-fsanitize=undefined-trap``: Deprecated alias of
225226
``-fsanitize=undefined``.
226227
- ``-fsanitize=implicit-integer-truncation``: Catches lossy integral

clang/include/clang/Basic/Sanitizers.def

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ SANITIZER_GROUP("undefined", Undefined,
152152
FloatCastOverflow |
153153
IntegerDivideByZero | NonnullAttribute | Null | ObjectSize |
154154
PointerOverflow | Return | ReturnsNonnullAttribute | Shift |
155-
SignedIntegerOverflow | Unreachable | VLABound | Function |
156-
Vptr)
155+
SignedIntegerOverflow | Unreachable | VLABound | Function)
157156

158157
// -fsanitize=undefined-trap is an alias for -fsanitize=undefined.
159158
SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined)

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ static const SanitizerMask NeedsUbsanRt =
3030
SanitizerKind::Undefined | SanitizerKind::Integer |
3131
SanitizerKind::LocalBounds | SanitizerKind::ImplicitConversion |
3232
SanitizerKind::Nullability | SanitizerKind::CFI |
33-
SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
33+
SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast |
34+
SanitizerKind::Vptr;
3435
static const SanitizerMask NeedsUbsanCxxRt =
3536
SanitizerKind::Vptr | SanitizerKind::CFI;
3637
static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
@@ -53,23 +54,25 @@ static const SanitizerMask SupportsCoverage =
5354
SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero |
5455
SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack |
5556
SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI |
56-
SanitizerKind::NumericalStability;
57+
SanitizerKind::NumericalStability | SanitizerKind::Vptr;
5758
static const SanitizerMask RecoverableByDefault =
5859
SanitizerKind::Undefined | SanitizerKind::Integer |
5960
SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
60-
SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
61+
SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast |
62+
SanitizerKind::Vptr;
6163
static const SanitizerMask Unrecoverable =
6264
SanitizerKind::Unreachable | SanitizerKind::Return;
6365
static const SanitizerMask AlwaysRecoverable = SanitizerKind::KernelAddress |
6466
SanitizerKind::KernelHWAddress |
6567
SanitizerKind::KCFI;
6668
static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
6769
static const SanitizerMask TrappingSupported =
68-
(SanitizerKind::Undefined & ~SanitizerKind::Vptr) | SanitizerKind::Integer |
70+
SanitizerKind::Undefined | SanitizerKind::Integer |
6971
SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
7072
SanitizerKind::LocalBounds | SanitizerKind::CFI |
7173
SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
72-
static const SanitizerMask MergeDefault = SanitizerKind::Undefined;
74+
static const SanitizerMask MergeDefault =
75+
SanitizerKind::Undefined | SanitizerKind::Vptr;
7376
static const SanitizerMask TrappingDefault =
7477
SanitizerKind::CFI | SanitizerKind::LocalBounds;
7578
static const SanitizerMask CFIClasses =
@@ -195,8 +198,8 @@ static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds,
195198
{"dfsan_abilist.txt", SanitizerKind::DataFlow},
196199
{"cfi_ignorelist.txt", SanitizerKind::CFI},
197200
{"ubsan_ignorelist.txt",
198-
SanitizerKind::Undefined | SanitizerKind::Integer |
199-
SanitizerKind::Nullability |
201+
SanitizerKind::Undefined | SanitizerKind::Vptr |
202+
SanitizerKind::Integer | SanitizerKind::Nullability |
200203
SanitizerKind::FloatDivideByZero}};
201204

202205
for (auto BL : Ignorelists) {

clang/test/Driver/fsanitize.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
// CHECK-UNDEFINED-MERGE5: "-fsanitize-merge=alignment,null"
6464

6565
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
66-
// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
66+
// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
6767

6868
// RUN: %clang --target=x86_64-apple-darwin10 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-DARWIN
6969
// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
@@ -78,7 +78,7 @@
7878
// CHECK-UNDEFINED-WIN64-MINGW: "--dependent-lib={{[^"]*}}libclang_rt.ubsan_standalone{{(-x86_64)?}}.a"
7979
// CHECK-UNDEFINED-WIN-CXX: "--dependent-lib={{[^"]*}}ubsan_standalone_cxx{{[^"]*}}.lib"
8080
// CHECK-UNDEFINED-MSVC-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
81-
// CHECK-UNDEFINED-WIN64-MINGW-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr),?){19}"}}
81+
// CHECK-UNDEFINED-WIN64-MINGW-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
8282

8383
// RUN: %clang --target=i386-pc-win32 -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COVERAGE-WIN32
8484
// CHECK-COVERAGE-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone{{(-i386)?}}.lib"
@@ -148,10 +148,11 @@
148148
// RUN: %clang -fsanitize=shift -fno-sanitize=shift-base %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSANITIZE-SHIFT-PARTIAL
149149
// CHECK-FSANITIZE-SHIFT-PARTIAL: "-fsanitize=shift-exponent"
150150

151-
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=vptr -fsanitize-trap=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-TRAP-UNDEF
152-
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=vptr -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-TRAP-UNDEF
151+
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=vptr -fsanitize-trap=vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-TRAP-UNDEF
153152
// CHECK-VPTR-TRAP-UNDEF: error: invalid argument '-fsanitize=vptr' not allowed with '-fsanitize-trap=undefined'
154153

154+
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=vptr -fsanitize-undefined-trap-on-error %s -###
155+
155156
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=vptr -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-NO-RTTI
156157
// CHECK-VPTR-NO-RTTI: '-fsanitize=vptr' not allowed with '-fno-rtti'
157158

@@ -411,7 +412,7 @@
411412
// RUN: %clang --target=x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
412413
// RUN: %clang --target=x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=thread -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
413414
// RUN: %clang --target=x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover=all -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
414-
// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
415+
// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){16}"}}
415416
// CHECK-NO-RECOVER-UBSAN-NOT: sanitize-recover
416417

417418
// RUN: %clang --target=x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=object-size,shift-base -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-RECOVER
@@ -624,7 +625,7 @@
624625
// CHECK-ASAN-IOS: -fsanitize=address
625626

626627
// RUN: %clang --target=i386-pc-openbsd -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-OPENBSD
627-
// CHECK-UBSAN-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
628+
// CHECK-UBSAN-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
628629

629630
// RUN: not %clang --target=i386-pc-openbsd -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-OPENBSD
630631
// CHECK-ASAN-OPENBSD: unsupported option '-fsanitize=address' for target 'i386-pc-openbsd'
@@ -1066,7 +1067,7 @@
10661067
// CHECK-UBSAN-FUNCTION-TARGET-DAG: error: unsupported option '-fsanitize=function' for target 'x86_64-sie-ps5'
10671068
// CHECK-UBSAN-FUNCTION-MEXECUTE-ONLY-DAG: error: invalid argument '-fsanitize=function' not allowed with '-mexecute-only'
10681069
// CHECK-UBSAN-FUNCTION-MPURE-CODE-DAG: error: invalid argument '-fsanitize=function' not allowed with '-mpure-code'
1069-
// CHECK-UBSAN-UNDEFINED-VPTR: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound|vptr),?){18}"}}
1070+
// CHECK-UBSAN-UNDEFINED-VPTR: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound),?){17}"}}
10701071

10711072
// * Test BareMetal toolchain sanitizer support *
10721073

@@ -1165,7 +1166,7 @@
11651166

11661167
// -fsanitize-skip-hot-cutoff=undefined=0.5
11671168
// RUN: %clang -Werror --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-skip-hot-cutoff=undefined=0.5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SKIP-HOT-CUTOFF1
1168-
// CHECK-SKIP-HOT-CUTOFF1: "-fsanitize-skip-hot-cutoff={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr)=0.5(0*),?){19}"}}
1169+
// CHECK-SKIP-HOT-CUTOFF1: "-fsanitize-skip-hot-cutoff={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function)=0.5(0*),?){18}"}}
11691170

11701171
// No-op: no sanitizers are specified
11711172
// RUN: %clang -Werror --target=x86_64-linux-gnu -fsanitize-skip-hot-cutoff=undefined=0.5 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SKIP-HOT-CUTOFF2
@@ -1174,19 +1175,19 @@
11741175

11751176
// Enable undefined, then cancel out integer using a cutoff of 0.0
11761177
// RUN: %clang -Werror --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-skip-hot-cutoff=undefined=0.5,integer=0.0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SKIP-HOT-CUTOFF3
1177-
// CHECK-SKIP-HOT-CUTOFF3: "-fsanitize-skip-hot-cutoff={{((unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr)=0.5(0*),?){15}"}}
1178+
// CHECK-SKIP-HOT-CUTOFF3: "-fsanitize-skip-hot-cutoff={{((unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function)=0.5(0*),?){14}"}}
11781179

11791180
// Enable undefined, then cancel out integer using a cutoff of 0.0, then re-enable signed-integer-overflow
11801181
// RUN: %clang -Werror --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-skip-hot-cutoff=undefined=0.5,integer=0.0,signed-integer-overflow=0.7 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SKIP-HOT-CUTOFF4
1181-
// CHECK-SKIP-HOT-CUTOFF4: "-fsanitize-skip-hot-cutoff={{((signed-integer-overflow|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr)=0.[57]0*,?){16}"}}
1182+
// CHECK-SKIP-HOT-CUTOFF4: "-fsanitize-skip-hot-cutoff={{((signed-integer-overflow|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function)=0.[57]0*,?){15}"}}
11821183

11831184
// Check that -fsanitize-skip-hot-cutoff=undefined=0.4 does not widen the set of -fsanitize=integer checks.
11841185
// RUN: %clang -Werror --target=x86_64-linux-gnu -fsanitize=integer -fsanitize-skip-hot-cutoff=undefined=0.4 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SKIP-HOT-CUTOFF5
11851186
// CHECK-SKIP-HOT-CUTOFF5: "-fsanitize-skip-hot-cutoff={{((integer-divide-by-zero|shift-base|shift-exponent|signed-integer-overflow)=0.40*,?){4}"}}
11861187

11871188
// No-op: it's allowed for the user to specify a cutoff of 0.0, though the argument is not passed along by the driver.
11881189
// RUN: %clang -Werror --target=x86_64-linux-gnu -fsanitize=undefined -fsanitize-skip-hot-cutoff=undefined=0.0 %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SKIP-HOT-CUTOFF6
1189-
// CHECK-SKIP-HOT-CUTOFF6: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function|vptr),?){19}"}}
1190+
// CHECK-SKIP-HOT-CUTOFF6: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
11901191
// CHECK-SKIP-HOT-CUTOFF6-NOT: "-fsanitize-skip-hot-cutoff"
11911192

11921193
// Invalid: bad sanitizer

0 commit comments

Comments
 (0)