|
15 | 15 | #include "CGDebugInfo.h"
|
16 | 16 | #include "CGObjCRuntime.h"
|
17 | 17 | #include "CGOpenMPRuntime.h"
|
| 18 | +#include "CGRecordLayout.h" |
18 | 19 | #include "CodeGenFunction.h"
|
19 | 20 | #include "CodeGenModule.h"
|
20 | 21 | #include "ConstantEmitter.h"
|
@@ -324,6 +325,25 @@ class ScalarExprEmitter
|
324 | 325 | void EmitIntegerSignChangeCheck(Value *Src, QualType SrcType, Value *Dst,
|
325 | 326 | QualType DstType, SourceLocation Loc);
|
326 | 327 |
|
| 328 | + /// Emit a check that an [implicit] truncation of a bitfield does not |
| 329 | + /// discard any bits. It is not UB, so we use the value after truncation. |
| 330 | + void EmitBitfieldTruncationCheck(Value *Src, QualType SrcType, Value *Dst, |
| 331 | + QualType DstType, const CGBitFieldInfo &Info, |
| 332 | + SourceLocation Loc); |
| 333 | + |
| 334 | + /// Emit a check that an [implicit] conversion of a bitfield does not change |
| 335 | + /// the sign of the value. It is not UB, so we use the value after conversion. |
| 336 | + /// NOTE: Src and Dst may be the exact same value! (point to the same thing) |
| 337 | + void EmitBitfieldSignChangeCheck(Value *Src, QualType SrcType, Value *Dst, |
| 338 | + QualType DstType, const CGBitFieldInfo &Info, |
| 339 | + SourceLocation Loc); |
| 340 | + |
| 341 | + /// Emit a check that an [implicit] conversion of a bitfield. It is not UB, |
| 342 | + /// so we use the value after conversion. |
| 343 | + void EmitBitfieldConversionCheck(Value *Src, QualType SrcType, Value *Dst, |
| 344 | + QualType DstType, const CGBitFieldInfo &Info, |
| 345 | + SourceLocation Loc); |
| 346 | + |
327 | 347 | /// Emit a conversion from the specified type to the specified destination
|
328 | 348 | /// type, both of which are LLVM scalar types.
|
329 | 349 | struct ScalarConversionOpts {
|
@@ -1239,6 +1259,221 @@ void ScalarExprEmitter::EmitIntegerSignChangeCheck(Value *Src, QualType SrcType,
|
1239 | 1259 | {Src, Dst});
|
1240 | 1260 | }
|
1241 | 1261 |
|
| 1262 | +// Should be called within CodeGenFunction::SanitizerScope RAII scope. |
| 1263 | +// Returns 'i1 false' when the truncation Src -> Dst was lossy. |
| 1264 | +static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, |
| 1265 | + std::pair<llvm::Value *, SanitizerMask>> |
| 1266 | +EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, |
| 1267 | + QualType DstType, CGBuilderTy &Builder) { |
| 1268 | + |
| 1269 | + llvm::Type *SrcTy = Src->getType(); |
| 1270 | + llvm::Type *DstTy = Dst->getType(); |
| 1271 | + (void)SrcTy; // Only used in assert() |
| 1272 | + (void)DstTy; // Only used in assert() |
| 1273 | + |
| 1274 | + // This should be truncation of integral types. |
| 1275 | + assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && |
| 1276 | + "non-integer llvm type"); |
| 1277 | + |
| 1278 | + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); |
| 1279 | + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); |
| 1280 | + |
| 1281 | + ScalarExprEmitter::ImplicitConversionCheckKind Kind; |
| 1282 | + SanitizerMask Mask; |
| 1283 | + if (!SrcSigned && !DstSigned) { |
| 1284 | + Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation; |
| 1285 | + Mask = SanitizerKind::ImplicitUnsignedIntegerTruncation; |
| 1286 | + } else { |
| 1287 | + Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation; |
| 1288 | + Mask = SanitizerKind::ImplicitSignedIntegerTruncation; |
| 1289 | + } |
| 1290 | + |
| 1291 | + // Since Src already has the same type as Dst, we don't have |
| 1292 | + // to sign extend or truncate the Src value. |
| 1293 | + llvm::Value *CheckV = Builder.CreateICmpEQ(Dst, Src, "bf.truncheck"); |
| 1294 | + // If the comparison result is 'i1 false', then the truncation was lossy. |
| 1295 | + |
| 1296 | + return std::make_pair(Kind, std::make_pair(CheckV, Mask)); |
| 1297 | +} |
| 1298 | + |
| 1299 | +void ScalarExprEmitter::EmitBitfieldTruncationCheck( |
| 1300 | + Value *Src, QualType SrcType, Value *Dst, QualType DstType, |
| 1301 | + const CGBitFieldInfo &Info, SourceLocation Loc) { |
| 1302 | + |
| 1303 | + if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)) |
| 1304 | + return; |
| 1305 | + |
| 1306 | + // TODO: Calculate src width to avoid emitting code |
| 1307 | + // for unecessary cases. |
| 1308 | + unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits(); |
| 1309 | + unsigned BitfieldWidth = Info.Size; |
| 1310 | + // This must be truncation. Else we do not care. |
| 1311 | + if (SrcBits <= BitfieldWidth) |
| 1312 | + return; |
| 1313 | + |
| 1314 | + // If the integer sign change sanitizer is enabled, |
| 1315 | + // and we are truncating from larger unsigned type to smaller signed type, |
| 1316 | + // let that next sanitizer deal with it. |
| 1317 | + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); |
| 1318 | + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); |
| 1319 | + if (CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange) && |
| 1320 | + (!SrcSigned && DstSigned)) |
| 1321 | + return; |
| 1322 | + |
| 1323 | + CodeGenFunction::SanitizerScope SanScope(&CGF); |
| 1324 | + |
| 1325 | + std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, |
| 1326 | + std::pair<llvm::Value *, SanitizerMask>> |
| 1327 | + Check = EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType, |
| 1328 | + Builder); |
| 1329 | + // If the comparison result is 'i1 false', then the truncation was lossy. |
| 1330 | + |
| 1331 | + llvm::Constant *StaticArgs[] = { |
| 1332 | + CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), |
| 1333 | + CGF.EmitCheckTypeDescriptor(DstType), |
| 1334 | + llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first), |
| 1335 | + llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)}; |
| 1336 | + CGF.EmitCheck(Check.second, SanitizerHandler::ImplicitConversion, StaticArgs, |
| 1337 | + {Src, Dst}); |
| 1338 | +} |
| 1339 | + |
| 1340 | +// Should be called within CodeGenFunction::SanitizerScope RAII scope. |
| 1341 | +// Returns 'i1 false' when the conversion Src -> Dst changed the sign. |
| 1342 | +static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, |
| 1343 | + std::pair<llvm::Value *, SanitizerMask>> |
| 1344 | +EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, |
| 1345 | + unsigned SrcBits, Value *Dst, |
| 1346 | + QualType DstType, unsigned DstBits, |
| 1347 | + CGBuilderTy &Builder) { |
| 1348 | + llvm::Type *SrcTy = Src->getType(); |
| 1349 | + llvm::Type *DstTy = Dst->getType(); |
| 1350 | + (void)SrcTy; // Only used in assert() |
| 1351 | + (void)DstTy; // Only used in assert() |
| 1352 | + |
| 1353 | + // This should be truncation of integral types. |
| 1354 | + assert(isa<llvm::IntegerType>(SrcTy) && isa<llvm::IntegerType>(DstTy) && |
| 1355 | + "non-integer llvm type"); |
| 1356 | + |
| 1357 | + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); |
| 1358 | + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); |
| 1359 | + |
| 1360 | + assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) && |
| 1361 | + "either the widths should be different, or the signednesses."); |
| 1362 | + |
| 1363 | + // 1. Was the old Value negative? |
| 1364 | + llvm::Value *SrcIsNegative = |
| 1365 | + EmitIsNegativeTestHelper(Src, SrcType, "bf.src", Builder); |
| 1366 | + // 2. Is the new Value negative? |
| 1367 | + llvm::Value *DstIsNegative = |
| 1368 | + EmitIsNegativeTestHelper(Dst, DstType, "bf.dst", Builder); |
| 1369 | + // 3. Now, was the 'negativity status' preserved during the conversion? |
| 1370 | + // NOTE: conversion from negative to zero is considered to change the sign. |
| 1371 | + // (We want to get 'false' when the conversion changed the sign) |
| 1372 | + // So we should just equality-compare the negativity statuses. |
| 1373 | + llvm::Value *Check = nullptr; |
| 1374 | + Check = |
| 1375 | + Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative, "bf.signchangecheck"); |
| 1376 | + // If the comparison result is 'false', then the conversion changed the sign. |
| 1377 | + return std::make_pair( |
| 1378 | + ScalarExprEmitter::ICCK_IntegerSignChange, |
| 1379 | + std::make_pair(Check, SanitizerKind::ImplicitIntegerSignChange)); |
| 1380 | +} |
| 1381 | + |
| 1382 | +void ScalarExprEmitter::EmitBitfieldSignChangeCheck( |
| 1383 | + Value *Src, QualType SrcType, Value *Dst, QualType DstType, |
| 1384 | + const CGBitFieldInfo &Info, SourceLocation Loc) { |
| 1385 | + |
| 1386 | + if (!CGF.SanOpts.has(SanitizerKind::ImplicitIntegerSignChange)) |
| 1387 | + return; |
| 1388 | + |
| 1389 | + bool SrcSigned = SrcType->isSignedIntegerOrEnumerationType(); |
| 1390 | + bool DstSigned = DstType->isSignedIntegerOrEnumerationType(); |
| 1391 | + unsigned SrcBits = ConvertType(SrcType)->getScalarSizeInBits(); |
| 1392 | + unsigned DstBits = Info.Size; |
| 1393 | + |
| 1394 | + // Now, we do not need to emit the check in *all* of the cases. |
| 1395 | + // We can avoid emitting it in some obvious cases where it would have been |
| 1396 | + // dropped by the opt passes (instcombine) always anyways. |
| 1397 | + // If it's a cast between effectively the same type, no check. |
| 1398 | + // NOTE: this is *not* equivalent to checking the canonical types. |
| 1399 | + if (SrcSigned == DstSigned && SrcBits == DstBits) |
| 1400 | + return; |
| 1401 | + // At least one of the values needs to have signed type. |
| 1402 | + // If both are unsigned, then obviously, neither of them can be negative. |
| 1403 | + if (!SrcSigned && !DstSigned) |
| 1404 | + return; |
| 1405 | + // If the conversion is to *larger* *signed* type, then no check is needed. |
| 1406 | + // Because either sign-extension happens (so the sign will remain), |
| 1407 | + // or zero-extension will happen (the sign bit will be zero.) |
| 1408 | + if ((DstBits > SrcBits) && DstSigned) |
| 1409 | + return; |
| 1410 | + if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) && |
| 1411 | + (SrcBits > DstBits) && SrcSigned) { |
| 1412 | + // If the signed integer truncation sanitizer is enabled, |
| 1413 | + // and this is a truncation from signed type, then no check is needed. |
| 1414 | + // Because here sign change check is interchangeable with truncation check. |
| 1415 | + return; |
| 1416 | + } |
| 1417 | + // That's it. We can't rule out any more cases with the data we have. |
| 1418 | + |
| 1419 | + CodeGenFunction::SanitizerScope SanScope(&CGF); |
| 1420 | + |
| 1421 | + std::pair<ScalarExprEmitter::ImplicitConversionCheckKind, |
| 1422 | + std::pair<llvm::Value *, SanitizerMask>> |
| 1423 | + Check; |
| 1424 | + |
| 1425 | + // Each of these checks needs to return 'false' when an issue was detected. |
| 1426 | + ImplicitConversionCheckKind CheckKind; |
| 1427 | + llvm::SmallVector<std::pair<llvm::Value *, SanitizerMask>, 2> Checks; |
| 1428 | + // So we can 'and' all the checks together, and still get 'false', |
| 1429 | + // if at least one of the checks detected an issue. |
| 1430 | + |
| 1431 | + Check = EmitBitfieldSignChangeCheckHelper(Src, SrcType, SrcBits, Dst, DstType, |
| 1432 | + DstBits, Builder); |
| 1433 | + CheckKind = Check.first; |
| 1434 | + Checks.emplace_back(Check.second); |
| 1435 | + |
| 1436 | + if (CGF.SanOpts.has(SanitizerKind::ImplicitSignedIntegerTruncation) && |
| 1437 | + (SrcBits > DstBits) && !SrcSigned && DstSigned) { |
| 1438 | + // If the signed integer truncation sanitizer was enabled, |
| 1439 | + // and we are truncating from larger unsigned type to smaller signed type, |
| 1440 | + // let's handle the case we skipped in that check. |
| 1441 | + Check = |
| 1442 | + EmitBitfieldTruncationCheckHelper(Src, SrcType, Dst, DstType, Builder); |
| 1443 | + CheckKind = ICCK_SignedIntegerTruncationOrSignChange; |
| 1444 | + Checks.emplace_back(Check.second); |
| 1445 | + // If the comparison result is 'i1 false', then the truncation was lossy. |
| 1446 | + } |
| 1447 | + |
| 1448 | + llvm::Constant *StaticArgs[] = { |
| 1449 | + CGF.EmitCheckSourceLocation(Loc), CGF.EmitCheckTypeDescriptor(SrcType), |
| 1450 | + CGF.EmitCheckTypeDescriptor(DstType), |
| 1451 | + llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind), |
| 1452 | + llvm::ConstantInt::get(Builder.getInt32Ty(), Info.Size)}; |
| 1453 | + // EmitCheck() will 'and' all the checks together. |
| 1454 | + CGF.EmitCheck(Checks, SanitizerHandler::ImplicitConversion, StaticArgs, |
| 1455 | + {Src, Dst}); |
| 1456 | +} |
| 1457 | + |
| 1458 | +void ScalarExprEmitter::EmitBitfieldConversionCheck( |
| 1459 | + Value *Src, QualType SrcType, Value *Dst, QualType DstType, |
| 1460 | + const CGBitFieldInfo &Info, SourceLocation Loc) { |
| 1461 | + |
| 1462 | + if (!CGF.SanOpts.hasOneOf(SanitizerKind::ImplicitConversion)) |
| 1463 | + return; |
| 1464 | + |
| 1465 | + // We only care about int->int conversions here. |
| 1466 | + // We ignore conversions to/from pointer and/or bool. |
| 1467 | + if (!PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(SrcType, |
| 1468 | + DstType)) |
| 1469 | + return; |
| 1470 | + |
| 1471 | + assert(!DstType->isBooleanType() && "we should not get here with booleans."); |
| 1472 | + |
| 1473 | + EmitBitfieldTruncationCheck(Src, SrcType, Dst, DstType, Info, Loc); |
| 1474 | + EmitBitfieldSignChangeCheck(Src, SrcType, Dst, DstType, Info, Loc); |
| 1475 | +} |
| 1476 | + |
1242 | 1477 | Value *ScalarExprEmitter::EmitScalarCast(Value *Src, QualType SrcType,
|
1243 | 1478 | QualType DstType, llvm::Type *SrcTy,
|
1244 | 1479 | llvm::Type *DstTy,
|
@@ -2848,9 +3083,12 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
|
2848 | 3083 | }
|
2849 | 3084 |
|
2850 | 3085 | // Store the updated result through the lvalue.
|
2851 |
| - if (LV.isBitField()) |
| 3086 | + if (LV.isBitField()) { |
| 3087 | + Value *Src = value; |
2852 | 3088 | CGF.EmitStoreThroughBitfieldLValue(RValue::get(value), LV, &value);
|
2853 |
| - else |
| 3089 | + EmitBitfieldConversionCheck(Src, E->getType(), value, E->getType(), |
| 3090 | + LV.getBitFieldInfo(), E->getExprLoc()); |
| 3091 | + } else |
2854 | 3092 | CGF.EmitStoreThroughLValue(RValue::get(value), LV);
|
2855 | 3093 |
|
2856 | 3094 | // If this is a postinc, return the value read from memory, otherwise use the
|
@@ -3375,9 +3613,17 @@ LValue ScalarExprEmitter::EmitCompoundAssignLValue(
|
3375 | 3613 | // specially because the result is altered by the store, i.e., [C99 6.5.16p1]
|
3376 | 3614 | // 'An assignment expression has the value of the left operand after the
|
3377 | 3615 | // assignment...'.
|
3378 |
| - if (LHSLV.isBitField()) |
| 3616 | + if (LHSLV.isBitField()) { |
| 3617 | + Value *Src = Result; |
| 3618 | + QualType SrcType = E->getRHS()->getType(); |
| 3619 | + QualType DstType = E->getLHS()->getType(); |
| 3620 | + if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getRHS())) { |
| 3621 | + SrcType = ICE->getSubExpr()->getType(); |
| 3622 | + } |
3379 | 3623 | CGF.EmitStoreThroughBitfieldLValue(RValue::get(Result), LHSLV, &Result);
|
3380 |
| - else |
| 3624 | + EmitBitfieldConversionCheck(Src, SrcType, Result, DstType, |
| 3625 | + LHSLV.getBitFieldInfo(), E->getExprLoc()); |
| 3626 | + } else |
3381 | 3627 | CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV);
|
3382 | 3628 |
|
3383 | 3629 | if (CGF.getLangOpts().OpenMP)
|
@@ -4513,7 +4759,15 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
|
4513 | 4759 | // 'An assignment expression has the value of the left operand after
|
4514 | 4760 | // the assignment...'.
|
4515 | 4761 | if (LHS.isBitField()) {
|
| 4762 | + Value *Src = RHS; |
| 4763 | + QualType SrcType = E->getRHS()->getType(); |
| 4764 | + QualType DstType = E->getLHS()->getType(); |
| 4765 | + if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E->getRHS())) { |
| 4766 | + SrcType = ICE->getSubExpr()->getType(); |
| 4767 | + } |
4516 | 4768 | CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
|
| 4769 | + EmitBitfieldConversionCheck(Src, SrcType, RHS, DstType, |
| 4770 | + LHS.getBitFieldInfo(), E->getExprLoc()); |
4517 | 4771 | } else {
|
4518 | 4772 | CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
|
4519 | 4773 | CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
|
|
0 commit comments