[cfe-commits] r60628 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/Sema.h lib/Sema/SemaDecl.cpp test/Sema/bitfield.c
Anders Carlsson
andersca at mac.com
Sat Dec 6 12:33:04 PST 2008
Author: andersca
Date: Sat Dec 6 14:33:04 2008
New Revision: 60628
URL: http://llvm.org/viewvc/llvm-project?rev=60628&view=rev
Log:
Add diagnostics for bitfields.
Added:
cfe/trunk/test/Sema/bitfield.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=60628&r1=60627&r2=60628&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Dec 6 14:33:04 2008
@@ -1042,6 +1042,10 @@
"illegal initializer type %0")
DIAG(err_implicit_empty_initializer, ERROR,
"initializer for aggregate with no elements requires explicit braces")
+DIAG(err_bitfield_has_negative_width, ERROR,
+ "bit-field %0 has negative width")
+DIAG(err_bitfield_width_exceeds_type_size, ERROR,
+ "size of bit-field %0 exceeds size of its type (%1 bits)")
DIAG(err_redefinition_of_label, ERROR,
"redefinition of label '%0'")
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=60628&r1=60627&r2=60628&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sat Dec 6 14:33:04 2008
@@ -1384,8 +1384,14 @@
/// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
/// and reports the appropriate diagnostics. Returns false on success.
/// Can optionally return the value of the expression.
- bool VerifyIntegerConstantExpression(const Expr*E, llvm::APSInt *Result = 0);
+ bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
+ /// VerifyBitField - verifies that a bit field expression is an ICE and has
+ /// the correct width, and that the field type is valid.
+ /// Returns false on success.
+ bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+ QualType FieldTy, const Expr *BitWidth);
+
//===--------------------------------------------------------------------===//
// Extra semantic analysis beyond the C type system
private:
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=60628&r1=60627&r2=60628&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Dec 6 14:33:04 2008
@@ -2599,6 +2599,31 @@
return QualType();
}
+bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
+ QualType FieldTy, const Expr *BitWidth)
+{
+ // FIXME: 6.7.2.1p4 - verify the field type.
+
+ llvm::APSInt Value;
+ if (VerifyIntegerConstantExpression(BitWidth, &Value))
+ return true;
+
+ if (Value.isNegative()) {
+ Diag(FieldLoc, diag::err_bitfield_has_negative_width) << FieldName;
+ return true;
+ }
+
+ 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) {
+ Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) <<
+ FieldName << (unsigned)TypeSize;
+ return true;
+ }
+
+ return false;
+}
+
/// ActOnField - Each field of a struct/union/class is passed into this in order
/// to create a FieldDecl object for it.
Sema::DeclTy *Sema::ActOnField(Scope *S,
@@ -2611,25 +2636,11 @@
// FIXME: Unnamed fields can be handled in various different ways, for
// example, unnamed unions inject all members into the struct namespace!
-
- if (BitWidth) {
- // TODO: Validate.
- //printf("WARNING: BITFIELDS IGNORED!\n");
-
- // 6.7.2.1p3
- // 6.7.2.1p4
-
- } else {
- // Not a bitfield.
- // validate II.
-
- }
-
QualType T = GetTypeForDeclarator(D, S);
assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
bool InvalidDecl = false;
-
+
// C99 6.7.2.1p8: A member of a structure or union may have any type other
// than a variably modified type.
if (T->isVariablyModifiedType()) {
@@ -2643,6 +2654,17 @@
InvalidDecl = true;
}
}
+
+ if (BitWidth) {
+ if (VerifyBitField(Loc, II, T, BitWidth))
+ InvalidDecl = true;
+ } else {
+ // Not a bitfield.
+
+ // validate II.
+
+ }
+
// FIXME: Chain fielddecls together.
FieldDecl *NewFD;
@@ -2692,6 +2714,9 @@
// FIXME: Unnamed fields can be handled in various different ways, for
// example, unnamed unions inject all members into the struct namespace!
+ QualType T = GetTypeForDeclarator(D, S);
+ assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
+ bool InvalidDecl = false;
if (BitWidth) {
// TODO: Validate.
@@ -2707,10 +2732,6 @@
}
- QualType T = GetTypeForDeclarator(D, S);
- assert(!T.isNull() && "GetTypeForDeclarator() returned null type");
- bool InvalidDecl = false;
-
// C99 6.7.2.1p8: A member of a structure or union may have any type other
// than a variably modified type.
if (T->isVariablyModifiedType()) {
Added: cfe/trunk/test/Sema/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitfield.c?rev=60628&view=auto
==============================================================================
--- cfe/trunk/test/Sema/bitfield.c (added)
+++ cfe/trunk/test/Sema/bitfield.c Sat Dec 6 14:33:04 2008
@@ -0,0 +1,8 @@
+// RUN: clang %s -fsyntax-only -verify
+
+struct a {
+ int a : -1; // expected-error{{bit-field 'a' has negative width}}
+ int b : 33; // expected-error{{size of bit-field 'b' exceeds size of its type (32 bits)}}
+ int c : (1 + 0.25); // expected-error{{expression is not an integer constant expression}}
+ int d : (int)(1 + 0.25);
+};
More information about the cfe-commits
mailing list