JornVernee created this revision.
JornVernee added reviewers: akyrtzi, aaron.ballman, rsmith.
JornVernee added a project: clang.
Herald added subscribers: arphaman, dexonsmith.

Currently, looking up the offset of a field in a type with an incomplete array, 
using `clang_Type_getOffsetOf` always returns `CXTypeLayoutError_Incomplete`. 
e.g. for the following:

  struct Foo {
      int size;
      void* data[]; // incomplete array
  };

This returns `CXTypeLayoutError_Incomplete` when looking up the offset of 
either the 'size' or the 'data' field.

But, since an incomplete array always appears at the end of a record, looking 
up the field offsets should be fine. Note that this also works fine using the 
offsetof macro.

The fix for this is to ignore incomplete array fields when doing the recursive 
type validation.


https://reviews.llvm.org/D61239

Files:
  test/Index/print-type-size.c
  tools/libclang/CXType.cpp


Index: tools/libclang/CXType.cpp
===================================================================
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
     QualType FQT = I->getType();
-    if (FQT->isIncompleteType())
+    if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is 
okay here
       return CXTypeLayoutError_Incomplete;
     if (FQT->isDependentType())
       return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===================================================================
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+struct Foo {
+    int size;
+    void* data[]; // incomplete array
+};
+
+struct Bar {
+    int size;
+    struct {
+        int dummy;
+        void* data[]; // incomplete array
+    };
+};
+
+struct Baz {
+    int size;
+    union {
+        void* data1[]; // incomplete array
+        void* data2[]; // incomplete array
+    };
+};
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data:3:11 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64]
+// CHECK: FieldDecl=size:7:9 (Definition) [type=int] [typekind=Int] [sizeof=4] 
[alignof=4] [offsetof=0]
+// CHECK: FieldDecl=dummy:9:13 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=64/0]
+// CHECK: FieldDecl=data:10:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=128/64]
+// CHECK: FieldDecl=size:15:9 (Definition) [type=int] [typekind=Int] 
[sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data1:17:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
+// CHECK: FieldDecl=data2:18:15 (Definition) [type=void *[]] 
[typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
\ No newline at end of file


Index: tools/libclang/CXType.cpp
===================================================================
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -953,7 +953,7 @@
 static long long visitRecordForValidation(const RecordDecl *RD) {
   for (const auto *I : RD->fields()){
     QualType FQT = I->getType();
-    if (FQT->isIncompleteType())
+    if (FQT->isIncompleteType() && !FQT->isIncompleteArrayType()) // IAT is okay here
       return CXTypeLayoutError_Incomplete;
     if (FQT->isDependentType())
       return CXTypeLayoutError_Dependent;
Index: test/Index/print-type-size.c
===================================================================
--- /dev/null
+++ test/Index/print-type-size.c
@@ -0,0 +1,30 @@
+struct Foo {
+    int size;
+    void* data[]; // incomplete array
+};
+
+struct Bar {
+    int size;
+    struct {
+        int dummy;
+        void* data[]; // incomplete array
+    };
+};
+
+struct Baz {
+    int size;
+    union {
+        void* data1[]; // incomplete array
+        void* data2[]; // incomplete array
+    };
+};
+
+// RUN: c-index-test -test-print-type-size %s | FileCheck %s
+// CHECK: FieldDecl=size:2:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data:3:11 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64]
+// CHECK: FieldDecl=size:7:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=dummy:9:13 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=64/0]
+// CHECK: FieldDecl=data:10:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=128/64]
+// CHECK: FieldDecl=size:15:9 (Definition) [type=int] [typekind=Int] [sizeof=4] [alignof=4] [offsetof=0]
+// CHECK: FieldDecl=data1:17:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
+// CHECK: FieldDecl=data2:18:15 (Definition) [type=void *[]] [typekind=IncompleteArray] [sizeof=-2] [alignof=-2] [offsetof=64/0]
\ No newline at end of file
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to