summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-28 22:36:06 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-28 22:36:06 +0000
commit10982ea3f9e11da2311b6b47d6bad2dd63bdff9d (patch)
tree9b1f73c9682d8d24f0fcdac7937dbc819ff31952 /clang/lib/Sema
parent669064a772092f8588c22bf06ae669ecb3c2eb62 (diff)
downloadbcm5719-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.cpp28
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()) {
OpenPOWER on IntegriCloud