MS wide bitfield error check in Sema

cl.exe treats wide bitfields as an error. This patch causes them to be
an error if IsMsStruct is true, as it is in straight C.

Patch by Warren Hunt!

Reviewers: eli.friedman

Differential Revision: http://llvm-reviews.chandlerc.com/D1125

llvm-svn: 186536
This commit is contained in:
Reid Kleckner 2013-07-17 20:46:03 +00:00
parent ee6d650f91
commit 736bc98f9c
3 changed files with 18 additions and 7 deletions

View File

@ -7286,8 +7286,8 @@ public:
/// Returns false on success.
/// Can optionally return whether the bit-field is of width 0
ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
QualType FieldTy, Expr *BitWidth,
bool *ZeroWidth = 0);
QualType FieldTy, bool IsMsStruct,
Expr *BitWidth, bool *ZeroWidth = 0);
enum CUDAFunctionTarget {
CFT_Device,

View File

@ -10575,8 +10575,8 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
// Note that FieldName may be null for anonymous bitfields.
ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
IdentifierInfo *FieldName,
QualType FieldTy, Expr *BitWidth,
bool *ZeroWidth) {
QualType FieldTy, bool IsMsStruct,
Expr *BitWidth, bool *ZeroWidth) {
// Default to true; that shouldn't confuse checks for emptiness
if (ZeroWidth)
*ZeroWidth = true;
@ -10625,7 +10625,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
if (!FieldTy->isDependentType()) {
uint64_t TypeSize = Context.getTypeSize(FieldTy);
if (Value.getZExtValue() > TypeSize) {
if (!getLangOpts().CPlusPlus) {
if (!getLangOpts().CPlusPlus || IsMsStruct) {
if (FieldName)
return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
<< FieldName << (unsigned)Value.getZExtValue()
@ -10843,7 +10843,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
bool ZeroWidth = false;
// If this is declared as a bit-field, check the bit-field.
if (!InvalidDecl && BitWidth) {
BitWidth = VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth).take();
BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
&ZeroWidth).take();
if (!BitWidth) {
InvalidDecl = true;
BitWidth = 0;
@ -11024,7 +11025,8 @@ Decl *Sema::ActOnIvar(Scope *S,
if (BitWidth) {
// 6.7.2.1p3, 6.7.2.1p4
BitWidth = VerifyBitField(Loc, II, T, BitWidth).take();
BitWidth =
VerifyBitField(Loc, II, T, /*IsMsStruct=*/false, BitWidth).take();
if (!BitWidth)
D.setInvalidType();
} else {

View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -mms-bitfields -verify %s 2>&1
struct A {
char a : 9; // expected-error{{size of bit-field 'a' (9 bits) exceeds size of its type (8 bits)}}
int b : 33; // expected-error{{size of bit-field 'b' (33 bits) exceeds size of its type (32 bits)}}
bool c : 9; // expected-error{{size of bit-field 'c' (9 bits) exceeds size of its type (8 bits)}}
};
int a[sizeof(A) == 1 ? 1 : -1];