r218006 - Sema: Diagnose undefined structs used as Microsoft anonymous structs

David Majnemer david.majnemer at gmail.com
Wed Sep 17 17:42:05 PDT 2014


Author: majnemer
Date: Wed Sep 17 19:42:05 2014
New Revision: 218006

URL: http://llvm.org/viewvc/llvm-project?rev=218006&view=rev
Log:
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.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/MicrosoftExtensions.c

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=218006&r1=218005&r2=218006&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Sep 17 19:42:05 2014
@@ -4066,13 +4066,16 @@ Decl *Sema::BuildMicrosoftCAnonymousStru
   TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);
   assert(TInfo && "couldn't build declarator info for anonymous struct");
 
+  auto *ParentDecl = cast<RecordDecl>(CurContext);
+  QualType RecTy = Context.getTypeDeclType(Record);
+
   // Create a declaration for this anonymous struct.
   NamedDecl *Anon = FieldDecl::Create(Context,
-                             cast<RecordDecl>(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::BuildMicrosoftCAnonymousStru
   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;
 }

Modified: cfe/trunk/test/Sema/MicrosoftExtensions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/MicrosoftExtensions.c?rev=218006&r1=218005&r2=218006&view=diff
==============================================================================
--- cfe/trunk/test/Sema/MicrosoftExtensions.c (original)
+++ cfe/trunk/test/Sema/MicrosoftExtensions.c Wed Sep 17 19:42:05 2014
@@ -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 at -1 {{field has incomplete type 'struct undefined'}}
+                    // expected-note at -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}}
 





More information about the cfe-commits mailing list