summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
-rw-r--r--clang/test/SemaCXX/ms_wide_bitfield.cpp9
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];
OpenPOWER on IntegriCloud