diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-28 22:36:06 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-28 22:36:06 +0000 |
commit | 10982ea3f9e11da2311b6b47d6bad2dd63bdff9d (patch) | |
tree | 9b1f73c9682d8d24f0fcdac7937dbc819ff31952 /clang/lib/Sema | |
parent | 669064a772092f8588c22bf06ae669ecb3c2eb62 (diff) | |
download | bcm5719-llvm-10982ea3f9e11da2311b6b47d6bad2dd63bdff9d.tar.gz bcm5719-llvm-10982ea3f9e11da2311b6b47d6bad2dd63bdff9d.zip |
Diagnose __builtin_offsetof expressions that refer to bit-fields
llvm-svn: 102548
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6d5749b0e8d..a23f32afa04 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6718,10 +6718,20 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd)); - // FIXME: C99 Verify that MemberDecl isn't a bitfield. - + // C99 7.17p3: + // (If the specified member is a bit-field, the behavior is undefined.) + // + // We diagnose this as an error. + if (MemberDecl->getBitWidth()) { + Diag(OC.LocEnd, diag::err_offsetof_bitfield) + << MemberDecl->getDeclName() + << SourceRange(BuiltinLoc, RParenLoc); + Diag(MemberDecl->getLocation(), diag::note_bitfield_decl); + return ExprError(); + } + if (cast<RecordDecl>(MemberDecl->getDeclContext())-> - isAnonymousStructOrUnion()) { + isAnonymousStructOrUnion()) { llvm::SmallVector<FieldDecl*, 4> Path; BuildAnonymousStructUnionMemberPath(MemberDecl, Path); unsigned n = Path.size(); @@ -6854,6 +6864,18 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, return ExprError(Diag(BuiltinLoc, diag::err_no_member) << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd)); + // C99 7.17p3: + // (If the specified member is a bit-field, the behavior is undefined.) + // + // We diagnose this as an error. + if (MemberDecl->getBitWidth()) { + Diag(OC.LocEnd, diag::err_offsetof_bitfield) + << MemberDecl->getDeclName() + << SourceRange(BuiltinLoc, RPLoc); + Diag(MemberDecl->getLocation(), diag::note_bitfield_decl); + return ExprError(); + } + // FIXME: C++: Verify that MemberDecl isn't a static field. // FIXME: Verify that MemberDecl isn't a bitfield. if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) { |