forked from OSchip/llvm-project
Diagnose __builtin_offsetof expressions that refer to bit-fields
llvm-svn: 102548
This commit is contained in:
parent
669064a772
commit
10982ea3f9
|
@ -1817,6 +1817,7 @@ def ext_offsetof_extended_field_designator : Extension<
|
|||
"using extended field designator is an extension">;
|
||||
def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
|
||||
InGroup<InvalidOffsetof>;
|
||||
def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
|
||||
|
||||
def warn_floatingpoint_eq : Warning<
|
||||
"comparing floating point with == or != is unsafe">,
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -53,4 +53,12 @@ int x[__builtin_offsetof(union x, x)];
|
|||
struct incomplete; // expected-note 2 {{forward declaration of 'struct incomplete'}}
|
||||
int test1[__builtin_offsetof(struct incomplete, foo)]; // expected-error {{offsetof of incomplete type 'struct incomplete'}}
|
||||
|
||||
int test1[__builtin_offsetof(struct incomplete[10], [4].foo)]; // expected-error {{array has incomplete element type 'struct incomplete'}}
|
||||
int test2[__builtin_offsetof(struct incomplete[10], [4].foo)]; // expected-error {{array has incomplete element type 'struct incomplete'}}
|
||||
|
||||
// Bitfields
|
||||
struct has_bitfields {
|
||||
int i : 7;
|
||||
int j : 12; // expected-note{{bit-field is declared here}}
|
||||
};
|
||||
|
||||
int test3 = __builtin_offsetof(struct has_bitfields, j); // expected-error{{cannot compute offset of bit-field 'j'}}
|
||||
|
|
|
@ -28,3 +28,11 @@ void test_ice(int i) {
|
|||
int array0[__builtin_offsetof(HasArray, array[5])];
|
||||
int array1[__builtin_offsetof(HasArray, array[i])]; // expected-error{{variable length arrays are not permitted in C++}}
|
||||
}
|
||||
|
||||
// Bitfields
|
||||
struct has_bitfields {
|
||||
int i : 7;
|
||||
int j : 12; // expected-note{{bit-field is declared here}}
|
||||
};
|
||||
|
||||
int test3 = __builtin_offsetof(struct has_bitfields, j); // expected-error{{cannot compute offset of bit-field 'j'}}
|
||||
|
|
Loading…
Reference in New Issue