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">;
|
"using extended field designator is an extension">;
|
||||||
def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
|
def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
|
||||||
InGroup<InvalidOffsetof>;
|
InGroup<InvalidOffsetof>;
|
||||||
|
def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
|
||||||
|
|
||||||
def warn_floatingpoint_eq : Warning<
|
def warn_floatingpoint_eq : Warning<
|
||||||
"comparing floating point with == or != is unsafe">,
|
"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.U.IdentInfo << RD << SourceRange(OC.LocStart,
|
||||||
OC.LocEnd));
|
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())->
|
if (cast<RecordDecl>(MemberDecl->getDeclContext())->
|
||||||
isAnonymousStructOrUnion()) {
|
isAnonymousStructOrUnion()) {
|
||||||
llvm::SmallVector<FieldDecl*, 4> Path;
|
llvm::SmallVector<FieldDecl*, 4> Path;
|
||||||
BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
|
BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
|
||||||
unsigned n = Path.size();
|
unsigned n = Path.size();
|
||||||
|
@ -6854,6 +6864,18 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
|
||||||
return ExprError(Diag(BuiltinLoc, diag::err_no_member)
|
return ExprError(Diag(BuiltinLoc, diag::err_no_member)
|
||||||
<< OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
|
<< 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: C++: Verify that MemberDecl isn't a static field.
|
||||||
// FIXME: Verify that MemberDecl isn't a bitfield.
|
// FIXME: Verify that MemberDecl isn't a bitfield.
|
||||||
if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {
|
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'}}
|
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, 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 array0[__builtin_offsetof(HasArray, array[5])];
|
||||||
int array1[__builtin_offsetof(HasArray, array[i])]; // expected-error{{variable length arrays are not permitted in C++}}
|
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