diff options
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 12 | ||||
| -rw-r--r-- | clang/test/SemaCXX/ms_wide_bitfield.cpp | 9 |
3 files changed, 18 insertions, 7 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 495ba48d749..835151aa983 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e0dab1c4f1c..b860823ff62 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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 { diff --git a/clang/test/SemaCXX/ms_wide_bitfield.cpp b/clang/test/SemaCXX/ms_wide_bitfield.cpp new file mode 100644 index 00000000000..d917390ef14 --- /dev/null +++ b/clang/test/SemaCXX/ms_wide_bitfield.cpp @@ -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]; |

