]> granicus.if.org Git - clang/commitdiff
[ASTImporter] Fix for importing unnamed structs
authorAleksei Sidorin <a.sidorin@samsung.com>
Thu, 5 Apr 2018 15:31:49 +0000 (15:31 +0000)
committerAleksei Sidorin <a.sidorin@samsung.com>
Thu, 5 Apr 2018 15:31:49 +0000 (15:31 +0000)
Patch by Peter Szecsi!

Differential Revision: https://reviews.llvm.org/D30876

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@329301 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTImporter.cpp
lib/AST/ASTStructuralEquivalence.cpp
test/ASTMerge/struct/Inputs/struct1.c
test/ASTMerge/struct/Inputs/struct2.c
test/ASTMerge/struct/test.c

index 6b9260d2d879a95f515b8906cb6b7f343e0fae8b..2d9e1c888395fa3d1eefa71c6798b10ad40679f9 100644 (file)
@@ -1923,9 +1923,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
       }
       
       if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
-        if (D->isAnonymousStructOrUnion() && 
-            FoundRecord->isAnonymousStructOrUnion()) {
-          // If both anonymous structs/unions are in a record context, make sure
+        if (!SearchName) {
+          // If both unnamed structs/unions are in a record context, make sure
           // they occur in the same location in the context records.
           if (Optional<unsigned> Index1 =
                   StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
index da0a26e40b11712129c7130715d9012c8f8eef0b..d74042c8835d7503f54d66b6aef19715f414270b 100644 (file)
@@ -1256,6 +1256,10 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
     // If the field looks like this:
     // struct { ... } A;
     QualType FieldType = F->getType();
+    // In case of nested structs.
+    while (const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
+      FieldType = ElabType->getNamedType();
+
     if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
       const RecordDecl *RecDecl = RecType->getDecl();
       if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
index 0f3e8b9bc3ebfd3252143a09c8474ed569dcf2a2..a85aec70a84ce718e487424cc0b4156266c34565 100644 (file)
@@ -77,3 +77,65 @@ typedef struct {
 } S13;
 
 S13 x13;
+
+// Matches
+struct Unnamed {
+  union {
+    struct {
+      int i;
+    } S;
+    struct {
+      float i;
+    } R;
+  } U;
+} x14;
+
+// Matches
+struct DeepUnnamed {
+  union {
+    union {
+      struct {
+        long i;
+      } S;
+      struct {
+        int i;
+      } R;
+    } U1;
+    union {
+      struct {
+        long i;
+      } S;
+      struct {
+        float i;
+      } T;
+    } U2;
+  } U;
+  struct {
+    long i;
+  } V;
+} x15;
+
+// Mismatch due to unnamed struct used internally
+struct DeepUnnamedError {
+  union {
+    union {
+      struct {
+        long i;
+      } S;
+      struct {
+        int i;
+      } R;
+    } U1;
+    union {
+      struct {
+        long i; // Mismatch here.
+      } S;
+      struct {
+        float i;
+      } T;
+    } U2;
+  } U;
+  struct {
+    long i;
+  } V;
+} x16;
index 7fe17a576b23ac9b55c3b10d1660400e91e01ba3..49fe36d823d0c332401d9d106eef135d668a4cff 100644 (file)
@@ -74,3 +74,65 @@ typedef struct {
 } S13;
 
 S13 x13;
+
+// Matches
+struct Unnamed {
+  union {
+    struct {
+      int i;
+    } S;
+    struct {
+      float i;
+    } R;
+  } U;
+} x14;
+
+// Matches
+struct DeepUnnamed {
+  union {
+    union {
+      struct {
+        long i;
+      } S;
+      struct {
+        int i;
+      } R;
+    } U1;
+    union {
+      struct {
+        long i;
+      } S;
+      struct {
+        float i;
+      } T;
+    } U2;
+  } U;
+  struct {
+    long i;
+  } V;
+} x15;
+
+// Mismatch due to unnamed struct used internally
+struct DeepUnnamedError {
+  union {
+    union {
+      struct {
+        long i;
+      } S;
+      struct {
+        int i;
+      } R;
+    } U1;
+    union {
+      struct {
+        float i; // Mismatch here.
+      } S;
+      struct {
+        float i;
+      } T;
+    } U2;
+  } U;
+  struct {
+    long i;
+  } V;
+} x16;
index ed7750f6beccadc70a47376106cc3840cc823a39..b7e24416d2509d4f289bca739547bbd03325df9c 100644 (file)
 // CHECK: struct2.c:72:7: note: field 'i' has type 'int' here
 // CHECK: struct2.c:76:5: error: external variable 'x13' declared with incompatible types in different translation units ('S13' vs. 'S13')
 // CHECK: struct1.c:79:5: note: declared here with type 'S13'
-// CHECK: 9 warnings and 8 errors generated
+// CHECK: struct1.c:130:7: warning: type 'struct DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS:.+]]/struct1.c:130:7)' has incompatible definitions in different translation units
+// CHECK: struct1.c:131:14: note: field 'i' has type 'long' here
+// CHECK: struct2.c:128:15: note: field 'i' has type 'float' here
+// CHECK: struct1.c:129:5: warning: type 'union DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS]]/struct1.c:129:5)' has incompatible definitions in different translation units
+// CHECK: struct1.c:132:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]/struct1.c:130:7)' here
+// CHECK: struct2.c:129:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]/struct2.c:127:7)' here
+// CHECK: struct2.c:138:3: error: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError')
+// CHECK: struct1.c:141:3: note: declared here with type 'struct DeepUnnamedError'
+// CHECK: 11 warnings and 9 errors generated