From 89b53e0a49c30942d4ef77218a6155e0699a3f00 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 18 Sep 2014 00:42:05 +0000 Subject: [PATCH] Sema: Diagnose undefined structs used as Microsoft anonymous structs Previously, we would not mark structs containing anonymous structs as invalid. Later, horrific things would occur when trying to determine the size of the parent record. Instead, require the struct to be a complete type when used as an anonymous struct. Mark both the anonymous field for the struct and the parent context as invalid (this is similar to what we do when a struct contains a field with an incomplete type.) This fixes PR11847. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218006 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 16 +++++++++++----- test/Sema/MicrosoftExtensions.c | 8 ++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1f2cf7bc9f..0aaa60c90f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4066,13 +4066,16 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S); assert(TInfo && "couldn't build declarator info for anonymous struct"); + auto *ParentDecl = cast(CurContext); + QualType RecTy = Context.getTypeDeclType(Record); + // Create a declaration for this anonymous struct. NamedDecl *Anon = FieldDecl::Create(Context, - cast(CurContext), + ParentDecl, DS.getLocStart(), DS.getLocStart(), /*IdentifierInfo=*/nullptr, - Context.getTypeDeclType(Record), + RecTy, TInfo, /*BitWidth=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit); @@ -4088,10 +4091,13 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, Chain.push_back(Anon); RecordDecl *RecordDef = Record->getDefinition(); - if (!RecordDef || InjectAnonymousStructOrUnionMembers(*this, S, CurContext, - RecordDef, AS_none, - Chain, true)) + if (RequireCompleteType(Anon->getLocation(), RecTy, + diag::err_field_incomplete) || + InjectAnonymousStructOrUnionMembers(*this, S, CurContext, RecordDef, + AS_none, Chain, true)) { Anon->setInvalidDecl(); + ParentDecl->setInvalidDecl(); + } return Anon; } diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c index 908ec04876..e7032305fc 100644 --- a/test/Sema/MicrosoftExtensions.c +++ b/test/Sema/MicrosoftExtensions.c @@ -104,6 +104,14 @@ typedef struct { AA; // expected-warning {{anonymous structs are a Microsoft extension}} } BB; +struct anon_fault { + struct undefined; // expected-warning {{anonymous structs are a Microsoft extension}} + // expected-error@-1 {{field has incomplete type 'struct undefined'}} + // expected-note@-2 {{forward declaration of 'struct undefined'}} +}; + +const int anon_falt_size = sizeof(struct anon_fault); + __declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; // expected-note {{'e1' has been explicitly marked deprecated here}} struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{'DS1' has been explicitly marked deprecated here}} -- 2.50.1