Fix anonymous union constructed under the wrong context
authorDodji Seketeli <dodji@redhat.com>
Fri, 5 Apr 2019 09:42:38 +0000 (11:42 +0200)
committerDodji Seketeli <dodji@redhat.com>
Mon, 8 Apr 2019 09:26:15 +0000 (11:26 +0200)
This patch is second of the series:

    Internal pretty repr of union cannot be flat representation
    Fix anonymous union constructed under the wrong context
    Propagate private type diff category through refs/qualified type diffs

The intent of this series is to fix the bug:

    https://sourceware.org/bugzilla/show_bug.cgi?id=24410
    "Empty change report emitted for libpoppler-qt5.so.1.18.0"

What happens here is that when the DWARF reader sees an anonymous
union/struct, it can mistakenly think that it has seen it before
(because the comparison doesn't take the scope of the union/struct
into account), and thus mistakenly represent the union/struct.

The solution implemented by this patch is to take the scope of the
anonymous union/struct into account.

Note that regression tests are all updated in the last patch of the
series.

* src/abg-dwarf-reader.cc (add_or_update_class_type)
(add_or_update_union_type): Only reuse anonymous class/union types
which have the same scope as the current one.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-dwarf-reader.cc

index 8f3052f..be327a8 100644 (file)
@@ -13495,7 +13495,10 @@ add_or_update_class_type(read_context&  ctxt,
   // re-use that one.
   if (class_decl_sptr pre_existing_class =
       is_class_type(ctxt.lookup_type_artifact_from_die(die)))
-    klass = pre_existing_class;
+    // For an anonymous type, make sure the pre-existing one has the
+    // same scope as the current one.
+    if (!is_anonymous || pre_existing_class->get_scope() == scope)
+      klass = pre_existing_class;
 
   uint64_t size = 0;
   die_size_in_bits(die, size);
@@ -13803,7 +13806,10 @@ add_or_update_union_type(read_context& ctxt,
   // 'die' then let's re-use that one.
   if (union_decl_sptr pre_existing_union =
       is_union_type(ctxt.lookup_artifact_from_die(die)))
-    union_type = pre_existing_union;
+    // For an anonymous type, make sure the pre-existing one has the
+    // same scope as the current one.
+    if (!is_anonymous || pre_existing_union->get_scope() == scope)
+      union_type = pre_existing_union;
 
   uint64_t size = 0;
   die_size_in_bits(die, size);