diff options
| author | Anders Carlsson <andersca@mac.com> | 2008-12-06 20:33:04 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2008-12-06 20:33:04 +0000 |
| commit | 5df391e5c7a39aae5b71277683c202db7283d250 (patch) | |
| tree | 0d46b18400adaf265d96b4599bbf6730067be65b /clang/lib/Sema | |
| parent | 45f4b8c0f2d543da9ca50f103258f9b4e6330635 (diff) | |
| download | bcm5719-llvm-5df391e5c7a39aae5b71277683c202db7283d250.tar.gz bcm5719-llvm-5df391e5c7a39aae5b71277683c202db7283d250.zip | |
Add diagnostics for bitfields.
llvm-svn: 60628
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 59 |
2 files changed, 47 insertions, 20 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index b396e1c185b..a9ad257e41b 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1384,8 +1384,14 @@ public: /// 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: diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e581b100dcc..0738f55ff2b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2599,6 +2599,31 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, 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 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, // 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 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, 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 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S, // 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 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S, } - 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()) { |

