[applied] {btf,dwarf,ctf,abixml}-reader: Fix size of subrange type

Message ID 87wmnv59xd.fsf@redhat.com
State New
Headers
Series [applied] {btf,dwarf,ctf,abixml}-reader: Fix size of subrange type |

Commit Message

Dodji Seketeli May 15, 2024, 4:14 p.m. UTC
  Hello,

While looking at something else, it appeared that the process of
setting the size of the array_type_def::subrange_type is wrong for all
front-ends.

For this patch, I went back to read the DWARF 5 specification at
"5.13/ Subrange Type Entries".

Basically, the size of the subrange type as described by the
DW_TAG_subrange_type DIE is set either:

    * by the size of the base type designated by the DW_AT_type
      attribute.

    * or by the DW_AT_byte_size or DW_AT_bit_size attribute that might
      be present on the DIE.

That is different from the length property carried by the subrange
type.

The patch updates the four front-rends (DWARF, BTF, CTF and ABIXML) to
fix the setting process of the size of the subrange type and adjusts
the testsuite accordingly.

	* src/abg-btf-reader.cc (reader::build_array_type): The size of
	the subrange is not defined specifically.  Let's set it to the
	default address size of the translation unit.
	* src/abg-ctf-reader.cc (build_array_ctf_range): If no basis type
	was found, then set the size of the subrange type to the default
	address size of the translation unit.
	* src/abg-dwarf-reader.cc (build_subrange_type): Consider the
	DW_AT_byte_size and DW_AT_bit_size attribute of
	DW_TAG_subrange_type if present.  Otherwise, if the basis type is
	present, its size as the size of the subrange type.  Otherwise,
	use the default address size of the translation unit as the size
	of the subrange type.
	* src/abg-ir.cc (array_type_def::subrange_type::subrange_type): If
	the underlying (basis) type is present, then use its size as the
	size of the subrange type.  Otherwise the size is zero.
	(array_type_def::subrange_type::set_underlying_type): Update the
	size of the subrange when setting a new underlying (basis) type.
	* src/abg-reader.cc (build_subrange_type): Read and set the size
	of the subrange.
	* tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt:
	Adjust.
	* tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt:
	Likewise.
	* tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt:
	Likewise.
	* tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
Applied to the master branch.
---
 src/abg-btf-reader.cc                         |  1 +
 src/abg-ctf-reader.cc                         |  3 ++
 src/abg-dwarf-reader.cc                       | 28 +++++++++++++++++--
 src/abg-ir.cc                                 | 11 ++++----
 src/abg-reader.cc                             | 17 +++++++++++
 .../test1-ada-subrange-report-1.txt           |  2 +-
 .../test1-ada-subrange-report-2.txt           |  2 +-
 .../test2-ada-subrange-redundant-report-1.txt |  2 +-
 .../test2-ada-subrange-redundant-report-2.txt |  2 +-
 ...x86_64--2.24.2-30.fc30.x86_64-report-0.txt |  8 +++---
 10 files changed, 60 insertions(+), 16 deletions(-)
  

Patch

diff --git a/src/abg-btf-reader.cc b/src/abg-btf-reader.cc
index 67206bb4..1cf92dfb 100644
--- a/src/abg-btf-reader.cc
+++ b/src/abg-btf-reader.cc
@@ -798,6 +798,7 @@  public:
 					    lower_bound, upper_bound,
 					    location()));
     subrange->is_non_finite(!arr->nelems);
+    subrange->set_size_in_bits(cur_tu()->get_address_size());
     add_decl_to_scope(subrange, cur_tu()->get_global_scope());
     canonicalize(subrange);
     array_type_def::subranges_type subranges = {subrange};
diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc
index f381021c..f4fb91ed 100644
--- a/src/abg-ctf-reader.cc
+++ b/src/abg-ctf-reader.cc
@@ -1263,6 +1263,9 @@  build_array_ctf_range(reader *rdr, ctf_dict_t *dic,
                                                    index_type,
                                                    location(),
                                                    translation_unit::LANG_C));
+  if (!index_type)
+    subrange->set_size_in_bits(rdr->cur_transl_unit()->get_address_size());
+
   if (!subrange)
     return nullptr;
 
diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index 43e5c85d..3e021a06 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -14705,6 +14705,18 @@  build_subrange_type(reader&		rdr,
 	  is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
     }
 
+  // The DW_TAG_subrange_type DIE may have some size related
+  // attributes (DW_AT_byte_size or DW_AT_bit_size).  If not, then the
+  // size is deduced from the size of its underlying type.
+  bool has_size_info = false;
+  uint64_t size = 0;
+  if ((has_size_info = die_unsigned_constant_attribute(die,
+						       DW_AT_byte_size, size)))
+    size *= 8;
+  else
+    has_size_info = die_unsigned_constant_attribute(die,
+						    DW_AT_bit_size, size);
+
   translation_unit::language language = rdr.cur_transl_unit()->get_language();
   array_type_def::subrange_type::bound_value lower_bound =
     get_default_array_lower_bound(language);
@@ -14780,13 +14792,23 @@  build_subrange_type(reader&		rdr,
 				       name,
 				       lower_bound,
 				       upper_bound,
+				       underlying_type,
 				       location()));
   result->is_non_finite(is_non_finite);
 
-  if (underlying_type)
-    result->set_underlying_type(underlying_type);
+  if (has_size_info)
+    result->set_size_in_bits(size);
+  else
+    {
+      // The DW_TAG_subrange_type doesn't appear to have any size
+      // attribute.  In that case, the size is deduced from the size
+      // of the underlying type.  If there is no underlying type
+      // specified, then the size of the subrange type is the size 
+      if (!underlying_type)
+	result->set_size_in_bits(rdr.cur_transl_unit()->get_address_size());
+    }
 
-  // Let's ensure the resulting subrange looks metabolically healhty.
+  // Let's ensure the resulting subrange looks metabolically healthy.
   ABG_ASSERT(result->is_non_finite()
 	     || (result->get_length() ==
 		 (uint64_t) (result->get_upper_bound()
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index 6228f0f4..63527baf 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -18608,8 +18608,9 @@  array_type_def::subrange_type::subrange_type(const environment& env,
 					     translation_unit::language l)
   : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
     type_base(env,
-	      upper_bound.get_unsigned_value()
-	      - lower_bound.get_unsigned_value(),
+	      utype
+	      ? utype->get_size_in_bits()
+	      : 0,
 	      0),
     decl_base(env, name, loc, ""),
     priv_(new priv(lower_bound, upper_bound, utype, l))
@@ -18638,9 +18639,7 @@  array_type_def::subrange_type::subrange_type(const environment& env,
 					     const location&	loc,
 					     translation_unit::language l)
   : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
-    type_base(env,
-	      upper_bound.get_unsigned_value()
-	      - lower_bound.get_unsigned_value(), 0),
+    type_base(env, /*size-in-bits=*/0, /*alignment=*/0),
     decl_base(env, name, loc, ""),
     priv_(new priv(lower_bound, upper_bound, l))
 {
@@ -18689,6 +18688,8 @@  array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
 {
   ABG_ASSERT(priv_->underlying_type_.expired());
   priv_->underlying_type_ = u;
+  if (u)
+    set_size_in_bits(u->get_size_in_bits());
 }
 
 /// Getter of the upper bound of the subrange type.
diff --git a/src/abg-reader.cc b/src/abg-reader.cc
index 29e593c2..ee578639 100644
--- a/src/abg-reader.cc
+++ b/src/abg-reader.cc
@@ -4609,6 +4609,21 @@  build_subrange_type(reader&		rdr,
 	length = strtoull(CHAR_STR(s), NULL, 0);
     }
 
+  uint64_t size_in_bits = 0;
+  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
+    {
+      char *endptr = nullptr;
+      size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
+      if (*endptr != '\0')
+	{
+	  if (!strcmp(CHAR_STR(s), "infinite")
+	      ||!strcmp(CHAR_STR(s), "unknown"))
+	    size_in_bits = (size_t) -1;
+	  else
+	    return nil;
+	}
+    }
+
   int64_t lower_bound = 0, upper_bound = 0;
   bool bounds_present = false;
   if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "lower-bound"))
@@ -4662,6 +4677,8 @@  build_subrange_type(reader&		rdr,
 				       underlying_type, loc));
   maybe_set_artificial_location(rdr, node, p);
   p->is_non_finite(is_non_finite);
+  if (size_in_bits)
+  p->set_size_in_bits(size_in_bits);
 
   if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
     rdr.map_xml_node_to_decl(node, p);
diff --git a/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt b/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt
index 69f3eb5f..8b2bc4c5 100644
--- a/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt
+++ b/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-1.txt
@@ -6,7 +6,7 @@  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
   [C] 'function test1__my_int[6] test1__first_function(void)' at test1.adb:6:1 has some indirect sub-type changes:
     return type changed:
       type name changed from 'test1__my_int[6]' to 'test1__my_int[7]'
-      array type size changed from 6000 to 7000
+      array type size changed from 96 to 112
       array type subrange 1 changed length from 6 to 7
 
   [C] 'function test1__my_index test1__second_function(void)' at test1.adb:14:1 has some indirect sub-type changes:
diff --git a/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt b/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt
index 7c299ea9..29c30481 100644
--- a/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt
+++ b/tests/data/test-abidiff-exit/ada-subrange/test1-ada-subrange/test1-ada-subrange-report-2.txt
@@ -8,7 +8,7 @@  Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable
   [C] 'function test1__my_int[6] test1__first_function(void)' at test1.adb:6:1 has some sub-type changes:
     return type changed:
       type name changed from 'test1__my_int[6]' to 'test1__my_int[7]'
-      array type size changed from 6000 to 7000
+      array type size changed from 96 to 112
       array type subrange 1 changed length from 6 to 7
 
   [C] 'function test1__my_index test1__second_function(void)' at test1.adb:14:1 has some sub-type changes:
diff --git a/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt b/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt
index 742dda83..2fd51473 100644
--- a/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt
+++ b/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-1.txt
@@ -6,7 +6,7 @@  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
   [C] 'function test__my_int[101] test__first_function(test__my_int[101]&)' at test.adb:6:1 has some indirect sub-type changes:
     return type changed:
       type name changed from 'test__my_int[101]' to 'test__my_int[201]'
-      array type size changed from 101000 to 201000
+      array type size changed from 1616 to 3216
       array type subrange 1 changed length from 101 to 201
 
   [C] 'function test__my_index test__second_function(const test__my_index)' at test.adb:12:1 has some indirect sub-type changes:
diff --git a/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt b/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt
index 45e1c527..f9d75049 100644
--- a/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt
+++ b/tests/data/test-abidiff-exit/ada-subrange/test2-ada-subrange-redundant/test2-ada-subrange-redundant-report-2.txt
@@ -8,7 +8,7 @@  Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable
   [C] 'function test__my_int[101] test__first_function(test__my_int[101]&)' at test.adb:6:1 has some sub-type changes:
     return type changed:
       type name changed from 'test__my_int[101]' to 'test__my_int[201]'
-      array type size changed from 101000 to 201000
+      array type size changed from 1616 to 3216
       array type subrange 1 changed length from 101 to 201
 
   [C] 'function test__my_index test__second_function(const test__my_index)' at test.adb:12:1 has some sub-type changes:
diff --git a/tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt b/tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt
index 868e6ed1..bc705318 100644
--- a/tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt
+++ b/tests/data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt
@@ -17,10 +17,10 @@ 
                 2 data member changes:
                   type of 'integer LB0' changed:
                     entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
-                    type size changed from 32 to 2147483647 (in bits)
+                    type size hasn't changed
                   type of 'integer UB0' changed:
                     entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
-                    type size changed from 32 to 2147483647 (in bits)
+                    type size hasn't changed
 
     [C] 'function gtk__glarea__gtk_glarea gtk__glarea__gtk_new(gtk__glarea__gtk_glarea, const gtk__glarea__attributes_array___XUP)' at gtk-glarea.adb:63:1 has some indirect sub-type changes:
       parameter 2 of type 'const gtk__glarea__attributes_array___XUP' has sub-type changes:
@@ -33,10 +33,10 @@ 
                 2 data member changes:
                   type of 'integer LB0' changed:
                     entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
-                    type size changed from 32 to 2147483647 (in bits)
+                    type size hasn't changed
                   type of 'integer UB0' changed:
                     entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
-                    type size changed from 32 to 2147483647 (in bits)
+                    type size hasn't changed
 
   6 Removed variable symbols not referenced by debug info: