]> sourceware.org Git - libabigail.git/commitdiff
Bug 27598 - abidiff mishandles union member functions
authorDodji Seketeli <dodji@redhat.com>
Wed, 31 Mar 2021 12:56:52 +0000 (14:56 +0200)
committerDodji Seketeli <dodji@redhat.com>
Wed, 31 Mar 2021 16:21:28 +0000 (18:21 +0200)
abidiff segfaults when a union member function is involved in the
comparison.  This patch fixes that.

* src/abg-default-reporter.cc (default_reporter::report): Assume
the parent type of the method can be either a class or a union.
* tests/data/test-diff-filter/test-PR27598-report-0.txt: New
reference output for the test.
* tests/data/test-diff-filter/test-PR27598-v{0,1}.cc: New source
code for the input binaries below.
* tests/data/test-diff-filter/test-PR27598-v{0,1}.o: New input
test binaries.
* tests/data/Makefile.am: Add the new test material to source
distribution.
* tests/test-diff-filter.cc (in_out_specs): Add the test inputs
above to this test harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
src/abg-default-reporter.cc
tests/data/Makefile.am
tests/data/test-diff-filter/test-PR27598-report-0.txt [new file with mode: 0644]
tests/data/test-diff-filter/test-PR27598-v0.cc [new file with mode: 0644]
tests/data/test-diff-filter/test-PR27598-v0.o [new file with mode: 0644]
tests/data/test-diff-filter/test-PR27598-v1.cc [new file with mode: 0644]
tests/data/test-diff-filter/test-PR27598-v1.o [new file with mode: 0644]
tests/test-diff-filter.cc

index 9940fc078971cf774a38f46df05ac2c9835e2f20..a5cebef421a8b00d354c193b1ccb60de6b9a1126 100644 (file)
@@ -1575,19 +1575,26 @@ default_reporter::report(const function_decl_diff& d, ostream& out,
              << " to " << sf_vtable_offset << "\n";
        }
 
-      // the classes of the two member functions.
-      class_decl_sptr fc =
-       is_class_type(is_method_type(ff->get_type())->get_class_type());
-      class_decl_sptr sc =
-       is_class_type(is_method_type(sf->get_type())->get_class_type());
+      // the parent types (classe or union) of the two member
+      // functions.
+      class_or_union_sptr f =
+       is_class_or_union_type(is_method_type(ff->get_type())->get_class_type());
+      class_or_union_sptr s =
+       is_class_or_union_type(is_method_type(sf->get_type())->get_class_type());
+
+      class_decl_sptr fc = is_class_type(f);
+      class_decl_sptr sc = is_class_type(s);
 
       // Detect if the virtual member function changes above
       // introduced a vtable change or not.
       bool vtable_added = false, vtable_removed = false;
-      if (!fc->get_is_declaration_only() && !sc->get_is_declaration_only())
+      if (!f->get_is_declaration_only() && !s->get_is_declaration_only())
        {
-         vtable_added = !fc->has_vtable() && sc->has_vtable();
-         vtable_removed = fc->has_vtable() && !sc->has_vtable();
+         if (fc && sc)
+           {
+             vtable_added = !fc->has_vtable() && sc->has_vtable();
+             vtable_removed = fc->has_vtable() && !sc->has_vtable();
+           }
        }
       bool vtable_changed = ((ff_is_virtual != sf_is_virtual)
                             || (ff_vtable_offset != sf_vtable_offset));
index 0b406f3bd01f82dff5ce5776ec041c861b6fdd54..ab3d249005ed70314d18171152b7f44c9fd99cbc 100644 (file)
@@ -927,6 +927,11 @@ test-diff-filter/test-PR27331-report-0.txt   \
 test-diff-filter/test-PR27569-v0.abi        \
 test-diff-filter/test-PR27569-v1.abi         \
 test-diff-filter/test-PR27569-report-0.txt   \
+test-diff-filter/test-PR27598-v0.cc          \
+test-diff-filter/test-PR27598-v0.o           \
+test-diff-filter/test-PR27598-v1.cc          \
+test-diff-filter/test-PR27598-v1.o           \
+test-diff-filter/test-PR27598-report-0.txt   \
 \
 test-diff-suppr/test0-type-suppr-v0.cc \
 test-diff-suppr/test0-type-suppr-v1.cc \
diff --git a/tests/data/test-diff-filter/test-PR27598-report-0.txt b/tests/data/test-diff-filter/test-PR27598-report-0.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/data/test-diff-filter/test-PR27598-v0.cc b/tests/data/test-diff-filter/test-PR27598-v0.cc
new file mode 100644 (file)
index 0000000..b31dee4
--- /dev/null
@@ -0,0 +1,14 @@
+union S
+{
+  void bar() const
+  {
+  }
+
+  int needed;
+};
+
+void
+fun(S s)
+{
+  s.bar();
+}
diff --git a/tests/data/test-diff-filter/test-PR27598-v0.o b/tests/data/test-diff-filter/test-PR27598-v0.o
new file mode 100644 (file)
index 0000000..146c539
Binary files /dev/null and b/tests/data/test-diff-filter/test-PR27598-v0.o differ
diff --git a/tests/data/test-diff-filter/test-PR27598-v1.cc b/tests/data/test-diff-filter/test-PR27598-v1.cc
new file mode 100644 (file)
index 0000000..67bb3ee
--- /dev/null
@@ -0,0 +1,12 @@
+union S
+{
+  void bar() const
+  {
+  }
+};
+
+void
+fun(S s)
+{
+  s.bar();
+}
diff --git a/tests/data/test-diff-filter/test-PR27598-v1.o b/tests/data/test-diff-filter/test-PR27598-v1.o
new file mode 100644 (file)
index 0000000..7015d7a
Binary files /dev/null and b/tests/data/test-diff-filter/test-PR27598-v1.o differ
index 0b6b65885b761b799b346fe05f40040f5abe1602..acf2d62f883bb96c27f994fddd6a45d55f616730 100644 (file)
@@ -793,6 +793,13 @@ InOutSpec in_out_specs[] =
    "--no-default-suppression",
    "data/test-diff-filter/test-PR27569-report-0.txt",
    "output/test-diff-filter/test-PR27569-report-0.txt",
+  },
+    {
+   "data/test-diff-filter/test-PR27598-v0.o",
+   "data/test-diff-filter/test-PR27598-v0.o",
+   "--no-default-suppression",
+   "data/test-diff-filter/test-PR27598-report-0.txt",
+   "output/test-diff-filter/test-PR27598-report-0.txt",
   },
   // This should be the last entry
   {NULL, NULL, NULL, NULL, NULL}
This page took 0.046659 seconds and 5 git commands to generate.