Skip to content

Commit 8a5a1b7

Browse files
authored
Revert "Revert "[clang][UBSan] Add implicit conversion check for bitfields"" (#87529)
Reverts #87518 Revert is not needed as the regression was fixed with 1189e87. I assumed the crash and warning are different issues, but according to https://lab.llvm.org/buildbot/#/builders/240/builds/26629 fixing warning resolves the crash.
1 parent a94a3cd commit 8a5a1b7

File tree

11 files changed

+493
-73
lines changed

11 files changed

+493
-73
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ Non-comprehensive list of changes in this release
198198

199199
New Compiler Flags
200200
------------------
201+
- ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and
202+
sign change.
203+
- ``-fsanitize=implicit-integer-conversion`` a group that replaces the previous
204+
group ``-fsanitize=implicit-conversion``.
201205

202206
- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-field-initializers``.
203207
This diagnostic can be disabled to make ``-Wmissing-field-initializers`` behave
@@ -211,6 +215,9 @@ Modified Compiler Flags
211215
- Added a new diagnostic flag ``-Wreturn-mismatch`` which is grouped under
212216
``-Wreturn-type``, and moved some of the diagnostics previously controlled by
213217
``-Wreturn-type`` under this new flag. Fixes #GH72116.
218+
- ``-fsanitize=implicit-conversion`` is now a group for both
219+
``-fsanitize=implicit-integer-conversion`` and
220+
``-fsanitize=implicit-bitfield-conversion``.
214221

215222
- Added ``-Wcast-function-type-mismatch`` under the ``-Wcast-function-type``
216223
warning group. Moved the diagnostic previously controlled by

clang/docs/UndefinedBehaviorSanitizer.rst

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ Available checks are:
148148
Issues caught by this sanitizer are not undefined behavior,
149149
but are often unintentional.
150150
- ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
151+
- ``-fsanitize=implicit-bitfield-conversion``: Implicit conversion from
152+
integer of larger bit width to smaller bitfield, if that results in data
153+
loss. This includes unsigned/signed truncations and sign changes, similarly
154+
to how the ``-fsanitize=implicit-integer-conversion`` group works, but
155+
explicitly for bitfields.
151156
- ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
152157
parameter which is declared to never be null.
153158
- ``-fsanitize=null``: Use of a null pointer or creation of a null
@@ -193,16 +198,16 @@ Available checks are:
193198
signed division overflow (``INT_MIN/-1``). Note that checks are still
194199
added even when ``-fwrapv`` is enabled. This sanitizer does not check for
195200
lossy implicit conversions performed before the computation (see
196-
``-fsanitize=implicit-conversion``). Both of these two issues are handled
197-
by ``-fsanitize=implicit-conversion`` group of checks.
201+
``-fsanitize=implicit-integer-conversion``). Both of these two issues are handled
202+
by ``-fsanitize=implicit-integer-conversion`` group of checks.
198203
- ``-fsanitize=unreachable``: If control flow reaches an unreachable
199204
program point.
200205
- ``-fsanitize=unsigned-integer-overflow``: Unsigned integer overflow, where
201206
the result of an unsigned integer computation cannot be represented in its
202207
type. Unlike signed integer overflow, this is not undefined behavior, but
203208
it is often unintentional. This sanitizer does not check for lossy implicit
204209
conversions performed before such a computation
205-
(see ``-fsanitize=implicit-conversion``).
210+
(see ``-fsanitize=implicit-integer-conversion``).
206211
- ``-fsanitize=vla-bound``: A variable-length array whose bound
207212
does not evaluate to a positive value.
208213
- ``-fsanitize=vptr``: Use of an object whose vptr indicates that it is of
@@ -224,11 +229,15 @@ You can also use the following check groups:
224229
- ``-fsanitize=implicit-integer-arithmetic-value-change``: Catches implicit
225230
conversions that change the arithmetic value of the integer. Enables
226231
``implicit-signed-integer-truncation`` and ``implicit-integer-sign-change``.
227-
- ``-fsanitize=implicit-conversion``: Checks for suspicious
228-
behavior of implicit conversions. Enables
232+
- ``-fsanitize=implicit-integer-conversion``: Checks for suspicious
233+
behavior of implicit integer conversions. Enables
229234
``implicit-unsigned-integer-truncation``,
230235
``implicit-signed-integer-truncation``, and
231236
``implicit-integer-sign-change``.
237+
- ``-fsanitize=implicit-conversion``: Checks for suspicious
238+
behavior of implicit conversions. Enables
239+
``implicit-integer-conversion``, and
240+
``implicit-bitfield-conversion``.
232241
- ``-fsanitize=integer``: Checks for undefined or suspicious integer
233242
behavior (e.g. unsigned integer overflow).
234243
Enables ``signed-integer-overflow``, ``unsigned-integer-overflow``,

clang/include/clang/Basic/Sanitizers.def

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,24 @@ SANITIZER_GROUP("implicit-integer-arithmetic-value-change",
163163
ImplicitIntegerArithmeticValueChange,
164164
ImplicitIntegerSignChange | ImplicitSignedIntegerTruncation)
165165

166-
SANITIZER("objc-cast", ObjCCast)
166+
SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
167+
ImplicitIntegerArithmeticValueChange |
168+
ImplicitUnsignedIntegerTruncation)
167169

168-
// FIXME:
169-
//SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion,
170-
// ImplicitIntegerArithmeticValueChange |
171-
// ImplicitUnsignedIntegerTruncation)
172-
//SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
173-
// ImplicitIntegerConversion)
170+
// Implicit bitfield sanitizers
171+
SANITIZER("implicit-bitfield-conversion", ImplicitBitfieldConversion)
174172

175173
SANITIZER_GROUP("implicit-conversion", ImplicitConversion,
176-
ImplicitIntegerArithmeticValueChange |
177-
ImplicitUnsignedIntegerTruncation)
174+
ImplicitIntegerConversion |
175+
ImplicitBitfieldConversion)
178176

179177
SANITIZER_GROUP("integer", Integer,
180-
ImplicitConversion | IntegerDivideByZero | Shift |
178+
ImplicitIntegerConversion | IntegerDivideByZero | Shift |
181179
SignedIntegerOverflow | UnsignedIntegerOverflow |
182180
UnsignedShiftBase)
183181

182+
SANITIZER("objc-cast", ObjCCast)
183+
184184
SANITIZER("local-bounds", LocalBounds)
185185
SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
186186

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5580,11 +5580,44 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
55805580
break;
55815581
}
55825582

5583-
RValue RV = EmitAnyExpr(E->getRHS());
5583+
// TODO: Can we de-duplicate this code with the corresponding code in
5584+
// CGExprScalar, similar to the way EmitCompoundAssignmentLValue works?
5585+
RValue RV;
5586+
llvm::Value *Previous = nullptr;
5587+
QualType SrcType = E->getRHS()->getType();
5588+
// Check if LHS is a bitfield, if RHS contains an implicit cast expression
5589+
// we want to extract that value and potentially (if the bitfield sanitizer
5590+
// is enabled) use it to check for an implicit conversion.
5591+
if (E->getLHS()->refersToBitField()) {
5592+
llvm::Value *RHS =
5593+
EmitWithOriginalRHSBitfieldAssignment(E, Previous, &SrcType);
5594+
RV = RValue::get(RHS);
5595+
} else
5596+
RV = EmitAnyExpr(E->getRHS());
5597+
55845598
LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);
5599+
55855600
if (RV.isScalar())
55865601
EmitNullabilityCheck(LV, RV.getScalarVal(), E->getExprLoc());
5587-
EmitStoreThroughLValue(RV, LV);
5602+
5603+
if (LV.isBitField()) {
5604+
llvm::Value *Result = nullptr;
5605+
// If bitfield sanitizers are enabled we want to use the result
5606+
// to check whether a truncation or sign change has occurred.
5607+
if (SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
5608+
EmitStoreThroughBitfieldLValue(RV, LV, &Result);
5609+
else
5610+
EmitStoreThroughBitfieldLValue(RV, LV);
5611+
5612+
// If the expression contained an implicit conversion, make sure
5613+
// to use the value before the scalar conversion.
5614+
llvm::Value *Src = Previous ? Previous : RV.getScalarVal();
5615+
QualType DstType = E->getLHS()->getType();
5616+
EmitBitfieldConversionCheck(Src, SrcType, Result, DstType,
5617+
LV.getBitFieldInfo(), E->getExprLoc());
5618+
} else
5619+
EmitStoreThroughLValue(RV, LV);
5620+
55885621
if (getLangOpts().OpenMP)
55895622
CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
55905623
E->getLHS());

0 commit comments

Comments
 (0)