mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 17:36:05 +00:00
Fix assertions and bad warnings on extremely wide bit-fields.
We used to produce a bogus warning if the width couldn't be represented in 32 bits, and assert if it couldn't be represented in 64 bits.
This commit is contained in:
parent
a72f11ee20
commit
8e923ec2a8
@ -5649,9 +5649,8 @@ def err_incorrect_number_of_vector_initializers : Error<
|
||||
def warn_bitfield_width_exceeds_type_width: Warning<
|
||||
"width of bit-field %0 (%1 bits) exceeds the width of its type; value will "
|
||||
"be truncated to %2 bit%s2">, InGroup<BitFieldWidth>;
|
||||
def warn_anon_bitfield_width_exceeds_type_width : Warning<
|
||||
"width of anonymous bit-field (%0 bits) exceeds width of its type; value "
|
||||
"will be truncated to %1 bit%s1">, InGroup<BitFieldWidth>;
|
||||
def err_bitfield_too_wide : Error<
|
||||
"%select{bit-field %1|anonymous bit-field}0 is too wide (%2 bits)">;
|
||||
def warn_bitfield_too_small_for_enum : Warning<
|
||||
"bit-field %0 is not wide enough to store all enumerators of %1">,
|
||||
InGroup<BitFieldEnumConversion>, DefaultIgnore;
|
||||
|
@ -16432,6 +16432,13 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
|
||||
<< Value.toString(10);
|
||||
}
|
||||
|
||||
// The size of the bit-field must not exceed our maximum permitted object
|
||||
// size.
|
||||
if (Value.getActiveBits() > ConstantArrayType::getMaxSizeBits(Context)) {
|
||||
return Diag(FieldLoc, diag::err_bitfield_too_wide)
|
||||
<< !FieldName << FieldName << Value.toString(10);
|
||||
}
|
||||
|
||||
if (!FieldTy->isDependentType()) {
|
||||
uint64_t TypeStorageSize = Context.getTypeSize(FieldTy);
|
||||
uint64_t TypeWidth = Context.getIntWidth(FieldTy);
|
||||
@ -16449,25 +16456,21 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
|
||||
CStdConstraintViolation ? TypeWidth : TypeStorageSize;
|
||||
if (FieldName)
|
||||
return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width)
|
||||
<< FieldName << (unsigned)Value.getZExtValue()
|
||||
<< FieldName << Value.toString(10)
|
||||
<< !CStdConstraintViolation << DiagWidth;
|
||||
|
||||
return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_width)
|
||||
<< (unsigned)Value.getZExtValue() << !CStdConstraintViolation
|
||||
<< Value.toString(10) << !CStdConstraintViolation
|
||||
<< DiagWidth;
|
||||
}
|
||||
|
||||
// Warn on types where the user might conceivably expect to get all
|
||||
// specified bits as value bits: that's all integral types other than
|
||||
// 'bool'.
|
||||
if (BitfieldIsOverwide && !FieldTy->isBooleanType()) {
|
||||
if (FieldName)
|
||||
Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width)
|
||||
<< FieldName << (unsigned)Value.getZExtValue()
|
||||
<< (unsigned)TypeWidth;
|
||||
else
|
||||
Diag(FieldLoc, diag::warn_anon_bitfield_width_exceeds_type_width)
|
||||
<< (unsigned)Value.getZExtValue() << (unsigned)TypeWidth;
|
||||
if (BitfieldIsOverwide && !FieldTy->isBooleanType() && FieldName) {
|
||||
Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width)
|
||||
<< FieldName << Value.toString(10)
|
||||
<< (unsigned)TypeWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,12 @@ struct Test1 {
|
||||
CHECK_SIZE(Test1, 2);
|
||||
CHECK_ALIGN(Test1, 1);
|
||||
|
||||
struct Test1a {
|
||||
char : 9; // no warning (there's no value to truncate here)
|
||||
};
|
||||
CHECK_SIZE(Test1a, 2);
|
||||
CHECK_ALIGN(Test1a, 1);
|
||||
|
||||
struct Test2 {
|
||||
char c : 16; // expected-warning {{width of bit-field 'c' (16 bits) exceeds the width of its type; value will be truncated to 8 bits}}
|
||||
};
|
||||
@ -28,3 +34,16 @@ struct Test4 {
|
||||
CHECK_SIZE(Test4, 8);
|
||||
CHECK_ALIGN(Test4, 8);
|
||||
|
||||
struct Test5 {
|
||||
char c : 0x100000001; // expected-warning {{width of bit-field 'c' (4294967297 bits) exceeds the width of its type; value will be truncated to 8 bits}}
|
||||
};
|
||||
// Size and align don't really matter here, just make sure we don't crash.
|
||||
CHECK_SIZE(Test5, 1);
|
||||
CHECK_ALIGN(Test5, 1);
|
||||
|
||||
struct Test6 {
|
||||
char c : (unsigned __int128)0xffffffffffffffff + 2; // expected-error {{bit-field 'c' is too wide (18446744073709551617 bits)}}
|
||||
};
|
||||
// Size and align don't really matter here, just make sure we don't crash.
|
||||
CHECK_SIZE(Test6, 1);
|
||||
CHECK_ALIGN(Test6, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user