def err_flexible_array_not_at_end : Error<
"flexible array member %0 with type %1 is not at the end of"
" %select{struct|interface|union|class|enum}2">;
-def err_objc_variable_sized_type_not_at_end : Error<
- "field %0 with variable sized type %1 is not at the end of class">;
+def err_objc_variable_sized_type_not_at_end
+ : Error<"%select{field %1|unnamed field}0 with variable sized type %2 is "
+ "not at the end of class">;
def note_next_field_declaration : Note<
"next field declaration is here">;
def note_next_ivar_declaration : Note<
AccessSpecifier AS, DeclSpecContext DSC);
void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType,
- Decl *TagDecl);
+ RecordDecl *TagDecl);
void ParseStructDeclaration(
ParsingDeclSpec &DS,
/// [OBC] '@' 'defs' '(' class-name ')'
///
void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
- DeclSpec::TST TagType, Decl *TagDecl) {
+ DeclSpec::TST TagType, RecordDecl *TagDecl) {
PrettyDeclStackTraceEntry CrashInfo(Actions.Context, TagDecl, RecordLoc,
"parsing struct/union body");
assert(!getLangOpts().CPlusPlus && "C++ declarations not supported");
ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
- SmallVector<Decl *, 32> FieldDecls;
-
// While we still have something to read, read the declarations in the struct.
while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
Tok.isNot(tok::eof)) {
Actions.ActOnField(getCurScope(), TagDecl,
FD.D.getDeclSpec().getSourceRange().getBegin(),
FD.D, FD.BitfieldSize);
- FieldDecls.push_back(Field);
FD.complete(Field);
};
SmallVector<Decl *, 16> Fields;
Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(),
Tok.getIdentifierInfo(), Fields);
- FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
ConsumeToken();
ExpectAndConsume(tok::r_paren);
}
// If attributes exist after struct contents, parse them.
MaybeParseGNUAttributes(attrs);
+ SmallVector<Decl *, 32> FieldDecls(TagDecl->field_begin(),
+ TagDecl->field_end());
+
Actions.ActOnFields(getCurScope(), RecordLoc, TagDecl, FieldDecls,
T.getOpenLocation(), T.getCloseLocation(), attrs);
StructScope.Exit();
Decl *D =
SkipBody.CheckSameAsPrevious ? SkipBody.New : TagOrTempResult.get();
// Parse the definition body.
- ParseStructUnionBody(StartLoc, TagType, D);
+ ParseStructUnionBody(StartLoc, TagType, cast<RecordDecl>(D));
if (SkipBody.CheckSameAsPrevious &&
!Actions.ActOnDuplicateDefinition(DS, TagOrTempResult.get(),
SkipBody)) {
struct PreserveAttributes {};
typedef struct __attribute__((noreturn)) PreserveAttributes PreserveAttributes_t; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
+
+// PR46255
+struct FlexibleArrayMem {
+ int a;
+ int b[];
+};
+
+struct FollowedByNamed {
+ struct FlexibleArrayMem a; // expected-warning {{field 'a' with variable sized type 'struct FlexibleArrayMem' not at the end of a struct or class is a GNU extension}}
+ int i;
+};
+
+struct FollowedByUnNamed {
+ struct FlexibleArrayMem a; // expected-warning {{field 'a' with variable sized type 'struct FlexibleArrayMem' not at the end of a struct or class is a GNU extension}}
+ struct {
+ int i;
+ };
+};
+
+struct InAnonymous {
+ struct { // expected-warning-re {{field '' with variable sized type 'struct InAnonymous::(anonymous at {{.+}})' not at the end of a struct or class is a GNU extension}}
+
+ struct FlexibleArrayMem a;
+ };
+ int i;
+};
+struct InAnonymousFollowedByAnon {
+ struct { // expected-warning-re {{field '' with variable sized type 'struct InAnonymousFollowedByAnon::(anonymous at {{.+}})' not at the end of a struct or class is a GNU extension}}
+
+ struct FlexibleArrayMem a;
+ };
+ struct {
+ int i;
+ };
+};
+
+// This is the behavior in C++ as well, so making sure we reproduce it here.
+struct InAnonymousFollowedByEmpty {
+ struct FlexibleArrayMem a; // expected-warning {{field 'a' with variable sized type 'struct FlexibleArrayMem' not at the end of a struct or class is a GNU extension}}
+ struct {};
+};