diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 30 | ||||
-rw-r--r-- | test/Sema/bitfield.c | 6 |
3 files changed, 32 insertions, 10 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b07b3320c0..b9639f0aea 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -285,6 +285,8 @@ def err_static_out_of_line : Error< def err_typedef_not_bitfield : Error<"typedef member %0 cannot be a bit-field">; def err_not_integral_type_bitfield : Error< "bit-field %0 has non-integral type %1">; +def err_not_integral_type_anon_bitfield : Error< + "anonymous bit-field has non-integral type %0">; def err_member_initialization : Error< "%0 can only be initialized if it is a static const integral data member">; def err_member_function_initialization : Error< @@ -835,9 +837,13 @@ def err_implicit_empty_initializer : Error< "initializer for aggregate with no elements requires explicit braces">; def err_bitfield_has_negative_width : Error< "bit-field %0 has negative width (%1)">; +def err_anon_bitfield_has_negative_width : Error< + "anonymous bit-field has negative width (%0)">; def err_bitfield_has_zero_width : Error<"bit-field %0 has zero width">; def err_bitfield_width_exceeds_type_size : Error< "size of bit-field %0 exceeds size of its type (%1 bits)">; +def err_anon_bitfield_width_exceeds_type_size : Error< + "size of anonymous bitfield exceeds size of its type (%0 bits)">; def err_redefinition_of_label : Error<"redefinition of label '%0'">; def err_undeclared_label_use : Error<"use of undeclared label '%0'">; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 64fcddd92d..716219c034 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3528,16 +3528,21 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD) { Consumer.HandleTagDeclDefinition(Tag); } +// Note that FieldName may be null for anonymous bitfields. bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, QualType FieldTy, const Expr *BitWidth) { + // C99 6.7.2.1p4 - verify the field type. // C++ 9.6p3: A bit-field shall have integral or enumeration type. if (!FieldTy->isDependentType() && !FieldTy->isIntegralType()) { // Handle incomplete types with specific error. if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete)) return true; - return Diag(FieldLoc, diag::err_not_integral_type_bitfield) - << FieldName << FieldTy << BitWidth->getSourceRange(); + if (FieldName) + return Diag(FieldLoc, diag::err_not_integral_type_bitfield) + << FieldName << FieldTy << BitWidth->getSourceRange(); + return Diag(FieldLoc, diag::err_not_integral_type_anon_bitfield) + << FieldTy << BitWidth->getSourceRange(); } // If the bit-width is type- or value-dependent, don't try to check @@ -3553,16 +3558,23 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, if (Value == 0 && FieldName) return Diag(FieldLoc, diag::err_bitfield_has_zero_width) << FieldName; - if (Value.isSigned() && Value.isNegative()) - return Diag(FieldLoc, diag::err_bitfield_has_negative_width) - << FieldName << Value.toString(10); + if (Value.isSigned() && Value.isNegative()) { + if (FieldName) + return Diag(FieldLoc, diag::err_bitfield_has_negative_width) + << FieldName << Value.toString(10); + return Diag(FieldLoc, diag::err_anon_bitfield_has_negative_width) + << Value.toString(10); + } if (!FieldTy->isDependentType()) { uint64_t TypeSize = Context.getTypeSize(FieldTy); - // FIXME: We won't need the 0 size once we check that the field type is valid. - if (TypeSize && Value.getZExtValue() > TypeSize) - return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) - << FieldName << (unsigned)TypeSize; + if (Value.getZExtValue() > TypeSize) { + if (FieldName) + return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) + << FieldName << (unsigned)TypeSize; + return Diag(FieldLoc, diag::err_anon_bitfield_width_exceeds_type_size) + << (unsigned)TypeSize; + } } return false; diff --git a/test/Sema/bitfield.c b/test/Sema/bitfield.c index 0022b4d62f..7a7f96c752 100644 --- a/test/Sema/bitfield.c +++ b/test/Sema/bitfield.c @@ -19,5 +19,9 @@ struct a { enum e0 f : 1; // expected-error {{field has incomplete type 'enum e0'}} int g : (_Bool)1; + + // PR4017 + char : 10; // expected-error {{size of anonymous bitfield exceeds size of its type (8 bits)}} + unsigned : -2; // expected-error {{anonymous bit-field has negative width (-2)}} + float : 12; // expected-error {{anonymous bit-field has non-integral type 'float'}} }; - |