[applied] Bug 33055 - classes_have_same_layout & types_are_compatible enter in endless loop

Message ID 875xgrq0qc.fsf@redhat.com
State New
Headers
Series [applied] Bug 33055 - classes_have_same_layout & types_are_compatible enter in endless loop |

Commit Message

Dodji Seketeli June 19, 2025, 2:12 p.m. UTC
  Hello,

classes_have_same_layout can invoke types_are_compatible which itself
can invoke classes_have_same_layout.  That can create an endless loop
if all the dreaded conditions are set in the code being analyzed.  Oh
well.

This patch adds some guard to gently handle that case.

We still have to add regression tests for this.

	* src/abg-ir-priv.h (class_or_union::priv): Add a set of
	type_base* to record the classes which layouts are being compared
	against this one.
	* src/abg-ir.cc (classes_have_same_layout): If this type is
	already involved in comparing class layouts using
	classes_have_same_layout then do get out early to avoid calling
	types_are_compatible.
	* tests/data/test-abidiff-exit/PR33055/Makefile: New Makefile to
	build the test input binaries.
	* tests/data/test-abidiff-exit/PR33055/PR33055-report-[12].txt:
	New expected reference test output.
	* tests/data/test-abidiff-exit/PR33055/file.cpp: Source code of
	the test binaries.
	* tests/data/test-abidiff-exit/PR33055/{new,old}-lib.so: New test
	input binaries.
	* tests/data/Makefile.am: Add the new test material to source
	distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the new test
	binary inputs to this harness.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Applied to the mainline.
---
 src/abg-ir-priv.h                             |   5 +-
 src/abg-ir.cc                                 |  56 +++++++++++++++---
 tests/data/Makefile.am                        |   6 ++
 tests/data/test-abidiff-exit/PR33055/Makefile |  25 ++++++++
 .../PR33055/PR33055-report-1.txt              |   7 +++
 .../PR33055/PR33055-report-2.txt              |  47 +++++++++++++++
 tests/data/test-abidiff-exit/PR33055/file.cpp |  33 +++++++++++
 .../data/test-abidiff-exit/PR33055/new-lib.so | Bin 0 -> 19280 bytes
 .../data/test-abidiff-exit/PR33055/old-lib.so | Bin 0 -> 18928 bytes
 tests/test-abidiff-exit.cc                    |  30 ++++++++++
 10 files changed, 200 insertions(+), 9 deletions(-)
 create mode 100644 tests/data/test-abidiff-exit/PR33055/Makefile
 create mode 100644 tests/data/test-abidiff-exit/PR33055/PR33055-report-1.txt
 create mode 100644 tests/data/test-abidiff-exit/PR33055/PR33055-report-2.txt
 create mode 100644 tests/data/test-abidiff-exit/PR33055/file.cpp
 create mode 100755 tests/data/test-abidiff-exit/PR33055/new-lib.so
 create mode 100755 tests/data/test-abidiff-exit/PR33055/old-lib.so

new file mode 100755
index 0000000000000000000000000000000000000000..c5b57ee8894fb7e963272bfda2f5ec1f0af6598c
GIT binary patch
literal 18928
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
F{tfVS@KXQ)

literal 0
HcmV?d00001
  

Patch

diff --git a/src/abg-ir-priv.h b/src/abg-ir-priv.h
index 640f6de0..24da0f02 100644
--- a/src/abg-ir-priv.h
+++ b/src/abg-ir-priv.h
@@ -28,6 +28,7 @@  namespace ir
 {
 
 using std::string;
+using std::unordered_set;
 using abg_compat::optional;
 
 /// The result of structural comparison of type ABI artifacts.
@@ -1601,7 +1602,9 @@  struct class_or_union::priv
   member_function_templates	member_function_templates_;
   member_class_templates	member_class_templates_;
   bool				is_printing_flat_representation_ = false;
-
+  // The set of classes which layouts are currently being compared
+  // against this one.  This is to avoid endless loops.
+  unordered_set<type_base*>	comparing_class_layouts_;
   priv()
   {}
 
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 697466e4..0a2ce5a1 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -10261,6 +10261,37 @@  get_type_declaration(const type_base_sptr t)
 bool
 classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
 {
+#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
+#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
+#endif
+
+#ifdef ENSURE_NO_ENDLESS_LOOP
+#undef ENSURE_NO_ENDLESS_LOOP
+#endif
+
+#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE)		\
+  do								\
+    {								\
+      auto t1 = is_class_or_union_type(f);			\
+      auto t2 = is_class_or_union_type(s);			\
+      t1->priv_->comparing_class_layouts_.erase(t2.get());	\
+      t2->priv_->comparing_class_layouts_.erase(t1.get());	\
+      return VALUE;						\
+    } while (false)
+
+#define ENSURE_NO_ENDLESS_LOOP						\
+  do									\
+    {									\
+      auto t1 = is_class_or_union_type(f);				\
+      auto t2 = is_class_or_union_type(s);				\
+      const auto& END = t1->priv_->comparing_class_layouts_.end();	\
+      if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END	\
+	  || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
+	return true;							\
+      t1->priv_->comparing_class_layouts_.insert(t2.get());		\
+      t2->priv_->comparing_class_layouts_.insert(t1.get());		\
+    } while (false)
+
   class_decl_sptr fc = is_class_type(peel_qualified_or_typedef_type(f)),
     sc = is_class_type(peel_qualified_or_typedef_type(s));
 
@@ -10272,7 +10303,7 @@  classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
     return false;
 
   if (*fc == *sc)
-    return true;
+    RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
 
   // Compare the types and offsets of data members one by one.
   for (auto f_decl_it = fc->get_data_members().begin(),
@@ -10286,7 +10317,7 @@  classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
 
       if (*dm1_type != *dm2_type
 	  || get_data_member_offset(dm1) != get_data_member_offset(dm2))
-	return false;
+	RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
     }
 
   // Compare the layout of base types
@@ -10299,22 +10330,23 @@  classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
       class_decl::base_spec_sptr f_bs = *f_bs_it, s_bs = *s_bs_it;
       if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
 	  || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
-	return false;
+	RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
 
       class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
       if (!classes_have_same_layout(fb, sb))
-	return false;
+	RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
     }
 
   if (fc->has_vtable() != sc->has_vtable())
-    return false;
+    RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
 
   // Compare virtual function types
+  ENSURE_NO_ENDLESS_LOOP;
   if (fc->has_vtable())
     {
       if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
 	// Some virtual member function got removed.  Bad.
-	return false;
+	RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
 
       for (auto it1 = fc->get_virtual_mem_fns().begin(),
 	     it2 = sc->get_virtual_mem_fns().begin();
@@ -10329,11 +10361,19 @@  classes_have_same_layout(const type_base_sptr& f, const type_base_sptr& s)
 	       != get_member_function_vtable_offset(method2))
 	      || !types_are_compatible(method1->get_type(),
 				       method2->get_type()))
-	    return false;
+	    RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(false);
 	}
     }
 
-  return true;
+  RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(true);
+
+#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
+#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
+#endif
+
+#ifdef ENSURE_NO_ENDLESS_LOOP
+#undef ENSURE_NO_ENDLESS_LOOP
+#endif
 }
 
 /// Test if two types are equal modulo a typedef or CV qualifiers.
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 68811a5e..f6b77077 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -512,6 +512,12 @@  test-abidiff-exit/replace-dm-with-compatible-anon-dm-1-v0.o \
 test-abidiff-exit/replace-dm-with-compatible-anon-dm-1-v1.c \
 test-abidiff-exit/replace-dm-with-compatible-anon-dm-1-v1.o \
 test-abidiff-exit/replace-dm-with-compatible-anon-dm-1-report-1.txt \
+test-abidiff-exit/PR33055/Makefile \
+test-abidiff-exit/PR33055/PR33055-report-1.txt \
+test-abidiff-exit/PR33055/PR33055-report-2.txt \
+test-abidiff-exit/PR33055/file.cpp \
+test-abidiff-exit/PR33055/new-lib.so \
+test-abidiff-exit/PR33055/old-lib.so \
 \
 test-diff-dwarf/test0-v0.cc		\
 test-diff-dwarf/test0-v0.o			\
diff --git a/tests/data/test-abidiff-exit/PR33055/Makefile b/tests/data/test-abidiff-exit/PR33055/Makefile
new file mode 100644
index 00000000..b415ba14
--- /dev/null
+++ b/tests/data/test-abidiff-exit/PR33055/Makefile
@@ -0,0 +1,25 @@ 
+CXXFLAGS = -g -fPIC
+LDFLAGS = ${CXXFLAGS} -shared
+
+all: old-lib.so new-lib.so
+.PHONY: all     
+
+old-file.o: file.cpp
+	g++ ${CXXFLAGS} -o "$@" -c "$<"
+
+new-file.o: file.cpp
+	g++ ${CXXFLAGS} -DNEW_VERSION -o "$@" -c "$<"
+
+old-lib.so: old-file.o
+	g++ ${LDFLAGS} -o "$@" "$<"
+
+new-lib.so: new-file.o
+	g++ ${LDFLAGS} -o "$@" "$<"
+
+check: old-lib.so new-lib.so
+	abidiff $^
+.PHONY: check
+
+clean:
+	${RM} -f *.so *.o
+.PHONY: clean
diff --git a/tests/data/test-abidiff-exit/PR33055/PR33055-report-1.txt b/tests/data/test-abidiff-exit/PR33055/PR33055-report-1.txt
new file mode 100644
index 00000000..ce294d74
--- /dev/null
+++ b/tests/data/test-abidiff-exit/PR33055/PR33055-report-1.txt
@@ -0,0 +1,7 @@ 
+Functions changes summary: 0 Removed, 0 Changed (3 filtered out), 1 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 Added function:
+
+  [A] 'method void PublicImplementation::someNewMethod()'    {_ZN20PublicImplementation13someNewMethodEv}
+
diff --git a/tests/data/test-abidiff-exit/PR33055/PR33055-report-2.txt b/tests/data/test-abidiff-exit/PR33055/PR33055-report-2.txt
new file mode 100644
index 00000000..0a35da8a
--- /dev/null
+++ b/tests/data/test-abidiff-exit/PR33055/PR33055-report-2.txt
@@ -0,0 +1,47 @@ 
+Functions changes summary: 0 Removed, 3 Changed, 1 Added functions
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+1 Added function:
+
+  [A] 'method void PublicImplementation::someNewMethod()'    {_ZN20PublicImplementation13someNewMethodEv}
+
+3 functions with some indirect sub-type change:
+
+  [C] 'method PublicImplementation::PublicImplementation()' at file.cpp:28:1 has some indirect sub-type changes:
+    implicit parameter 0 of type 'PublicImplementation*' has sub-type changes:
+      in pointed to type 'class PublicImplementation' at file.cpp:13:1:
+        type size hasn't changed
+        3 member function changes:
+          'method virtual PublicImplementation::~PublicImplementation()' has some sub-type changes:
+            implicit parameter 0 of type 'PublicImplementation*' has sub-type changes:
+              pointed to type 'class PublicImplementation' changed, as being reported
+          'method virtual PublicImplementation::~PublicImplementation()' has some sub-type changes:
+            implicit parameter 0 of type 'PublicImplementation*' has sub-type changes:
+              pointed to type 'class PublicImplementation' changed, as being reported
+          'method virtual PublicImplementation::~PublicImplementation(int)' has some sub-type changes:
+            implicit parameter 0 of type 'PublicImplementation*' has sub-type changes:
+              pointed to type 'class PublicImplementation' changed, as being reported
+        1 data member change:
+          type of 'Interface* _pImpl' changed:
+            in pointed to type 'class Interface' at file.cpp:1:1:
+              type size hasn't changed
+              1 member function insertion:
+                'method virtual void Interface::someNewMethod()' at file.cpp:9:1, virtual at voffset 3/3
+              2 member function changes:
+                'method virtual Interface* Interface::clone()' has some sub-type changes:
+                  return type changed:
+                    pointed to type 'class Interface' changed, as being reported
+                  implicit parameter 0 of type 'Interface*' has sub-type changes:
+                    pointed to type 'class Interface' changed, as being reported
+                'method virtual Interface::~Interface(int)' has some sub-type changes:
+                  implicit parameter 0 of type 'Interface*' has sub-type changes:
+                    pointed to type 'class Interface' changed, as being reported
+
+  [C] 'method virtual PublicImplementation::~PublicImplementation()' at file.cpp:29:1 has some indirect sub-type changes:
+    implicit parameter 0 of type 'PublicImplementation*' has sub-type changes:
+      pointed to type 'class PublicImplementation' changed at file.cpp:13:1, as reported earlier
+
+  [C] 'method virtual PublicImplementation::~PublicImplementation()' at file.cpp:29:1 has some indirect sub-type changes:
+    implicit parameter 0 of type 'PublicImplementation*' has sub-type changes:
+      pointed to type 'class PublicImplementation' changed at file.cpp:13:1, as reported earlier
+
diff --git a/tests/data/test-abidiff-exit/PR33055/file.cpp b/tests/data/test-abidiff-exit/PR33055/file.cpp
new file mode 100644
index 00000000..0d637f09
--- /dev/null
+++ b/tests/data/test-abidiff-exit/PR33055/file.cpp
@@ -0,0 +1,33 @@ 
+class Interface
+{
+public:
+  virtual ~Interface() {};
+
+  virtual Interface* clone() = 0;
+
+#ifdef NEW_VERSION
+  virtual void someNewMethod() = 0;
+#endif
+};
+
+class PublicImplementation
+{
+public:
+  PublicImplementation();
+
+  virtual ~PublicImplementation();
+
+#ifdef NEW_VERSION
+  void someNewMethod();
+#endif
+
+private:
+  Interface* _pImpl;
+};
+
+PublicImplementation::PublicImplementation() = default;
+PublicImplementation::~PublicImplementation() = default;
+
+#ifdef NEW_VERSION
+void PublicImplementation::someNewMethod() {}
+#endif
diff --git a/tests/data/test-abidiff-exit/PR33055/new-lib.so b/tests/data/test-abidiff-exit/PR33055/new-lib.so
new file mode 100755
index 0000000000000000000000000000000000000000..372d3058462e11609f017fc15f73731d23e628f2
GIT binary patch
literal 19280
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

literal 0
HcmV?d00001

diff --git a/tests/data/test-abidiff-exit/PR33055/old-lib.so b/tests/data/test-abidiff-exit/PR33055/old-lib.so
diff --git a/tests/test-abidiff-exit.cc b/tests/test-abidiff-exit.cc
index a037d424..01a8b798 100644
--- a/tests/test-abidiff-exit.cc
+++ b/tests/test-abidiff-exit.cc
@@ -1639,6 +1639,36 @@  InOutSpec in_out_specs[] =
     "data/test-abidiff-exit/replace-dm-with-compatible-anon-dm-1-report-1.txt",
     "output/test-abidiff-exit/replace-dm-with-compatible-anon-dm-1-report-1.txt"
   },
+  {
+    "data/test-abidiff-exit/PR33055/old-lib.so",
+    "data/test-abidiff-exit/PR33055/new-lib.so",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/PR33055/PR33055-report-1.txt",
+    "output/test-abidiff-exit/PR33055/PR33055-report-1.txt"
+  },
+  {
+    "data/test-abidiff-exit/PR33055/old-lib.so",
+    "data/test-abidiff-exit/PR33055/new-lib.so",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "",
+    "--no-default-suppression --harmless",
+    abigail::tools_utils::ABIDIFF_ABI_CHANGE,
+    "data/test-abidiff-exit/PR33055/PR33055-report-2.txt",
+    "output/test-abidiff-exit/PR33055/PR33055-report-2.txt"
+  },
 #ifdef WITH_BTF
   {
     "data/test-abidiff-exit/btf/test0-v0.o",