From: Reid Kleckner Date: Wed, 17 Jul 2013 20:46:03 +0000 (+0000) Subject: MS wide bitfield error check in Sema X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9a3ecb015448dad705829b683f2392cfda80fc13;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186536 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 495ba48d74..835151aa98 100644 --- a/include/clang/Sema/Sema.h +++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e0dab1c4f1..b860823ff6 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/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/test/SemaCXX/ms_wide_bitfield.cpp b/test/SemaCXX/ms_wide_bitfield.cpp new file mode 100644 index 0000000000..d917390ef1 --- /dev/null +++ b/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];