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/SemaDecl.cpp | |
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/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 59 |
1 files changed, 40 insertions, 19 deletions
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()) { |