arphaman created this revision.
arphaman added a reviewer: aaron.ballman.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.

This patch fixes a crash that happens when clang is analyzing a 
transparent_union attribute on a union which has a field with incomplete type.

(Right now there's also a C++ crash like this when a field has a dependent 
type, but I plan on fixing it in a separate patch by analyzing the dependent 
attribute when the dependent union is instantiated).


Repository:
  rL LLVM

https://reviews.llvm.org/D25273

Files:
  lib/Sema/SemaDeclAttr.cpp
  test/Sema/transparent-union.c


Index: test/Sema/transparent-union.c
===================================================================
--- test/Sema/transparent-union.c
+++ test/Sema/transparent-union.c
@@ -89,3 +89,12 @@
     unsigned int u3;
   } __attribute__((aligned(8)));
 } __attribute__((transparent_union));
+
+union pr30520v { void b; } __attribute__((transparent_union)); // 
expected-error {{field has incomplete type 'void'}}
+
+union pr30520a { int b[]; } __attribute__((transparent_union)); // 
expected-error {{field has incomplete type 'int []'}}
+
+// expected-note@+1 2 {{forward declaration of 'struct stb'}}
+union pr30520s { struct stb b; } __attribute__((transparent_union)); // 
expected-error {{field has incomplete type 'struct stb'}}
+
+union pr30520s2 { int *v; struct stb b; } __attribute__((transparent_union)); 
// expected-error {{field has incomplete type 'struct stb'}}
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -3044,10 +3044,14 @@
     return;
   }
 
+  if (FirstType->isIncompleteType())
+    return;
   uint64_t FirstSize = S.Context.getTypeSize(FirstType);
   uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
   for (; Field != FieldEnd; ++Field) {
     QualType FieldType = Field->getType();
+    if (FieldType->isIncompleteType())
+      return;
     // FIXME: this isn't fully correct; we also need to test whether the
     // members of the union would all have the same calling convention as the
     // first member of the union. Checking just the size and alignment isn't


Index: test/Sema/transparent-union.c
===================================================================
--- test/Sema/transparent-union.c
+++ test/Sema/transparent-union.c
@@ -89,3 +89,12 @@
     unsigned int u3;
   } __attribute__((aligned(8)));
 } __attribute__((transparent_union));
+
+union pr30520v { void b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'void'}}
+
+union pr30520a { int b[]; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'int []'}}
+
+// expected-note@+1 2 {{forward declaration of 'struct stb'}}
+union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
+
+union pr30520s2 { int *v; struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}}
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -3044,10 +3044,14 @@
     return;
   }
 
+  if (FirstType->isIncompleteType())
+    return;
   uint64_t FirstSize = S.Context.getTypeSize(FirstType);
   uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
   for (; Field != FieldEnd; ++Field) {
     QualType FieldType = Field->getType();
+    if (FieldType->isIncompleteType())
+      return;
     // FIXME: this isn't fully correct; we also need to test whether the
     // members of the union would all have the same calling convention as the
     // first member of the union. Checking just the size and alignment isn't
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to