]> sourceware.org Git - libabigail.git/commitdiff
Prevent build_function_type from not canonicalizing certain types
authorDodji Seketeli <dodji@redhat.com>
Fri, 2 Oct 2015 16:27:34 +0000 (18:27 +0200)
committerDodji Seketeli <dodji@redhat.com>
Sun, 4 Oct 2015 11:51:25 +0000 (13:51 +0200)
I noticed that in some cases in build_function_type, when building the
sub-types of the function type, the construction of a function type
for the same DIE could be triggered.  This happens frequently for
aggregate types that happen to be recursive.  In those cases, we must
arrange for the construction of the function type for the same DIE to
return the same type that is being currently built by
build_function_type; otherwise, several types are going to be built
for the same DIE, and only one of them is going to be canonicalized.
build_function_type was just not prepared for this.

This patch fixes that.

Please note that the patch changes the test output
/home/dodji/git/libabigail.git/merge/build/tests/output/test-read-dwarf/test12-pr18844.so.abi
but it's a later patch that adjust that file because several patches
are going to require an update to that file.  We are going to update
that patch in one go at the end of the patch series.

* src/abg-dwarf-reader.cc (build_function_type): Associate the
type being built with its DIE, before starting to build the
sub-types.  The current type is then amended with the sub-types
that are built later.
(build_ir_node_from_die): In the case for DW_TAG_subroutine_type,
do not associate the type to the DIE here, as it's been done in
build_function_type.
* src/abg-ir.cc (function_type::set_parameters): Adjust the index
of the parameters being set to the function: they start at 1,
unless the first parameter is artificial, in which case its index
starts at zero.  This is just like what is done when the function
type is constructed directly with the parameters passed as an
argument to the constructor.

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

index f6a419d8b6b130399fc9372c41abeec53183ddcf..9e92e35c6aef795d1abf80ce03417ef1fa1b0ecd 100644 (file)
@@ -7063,6 +7063,21 @@ build_function_type(read_context&        ctxt,
       return result;
     }
 
+  // Let's create the type early and record it as being for the DIE
+  // 'die'.  This way, when building the sub-type triggers the
+  // creation of a type matching the same 'die', then we'll reuse this
+  // one.
+  result.reset(is_method
+              ? new method_type(is_method,
+                                tu->get_address_size(),
+                                /*alignment=*/0)
+              : new function_type(tu->get_address_size(),
+                                  /*alignment=*/0));
+  tu->bind_function_type_life_time(result);
+  ctxt.associate_die_to_type(dwarf_dieoffset(die),
+                            die_is_from_alt_di,
+                            result);
+
   decl_base_sptr return_type_decl;
   Dwarf_Die ret_type_die;
   bool ret_type_die_is_in_alternate_debug_info = false;
@@ -7075,6 +7090,7 @@ build_function_type(read_context& ctxt,
                                     where_offset));
   if (!return_type_decl)
     return_type_decl = build_ir_node_for_void_type(ctxt);
+  result->set_return_type(is_type(return_type_decl));
 
   Dwarf_Die child;
   function_decl::parameters function_parms;
@@ -7127,18 +7143,7 @@ build_function_type(read_context&        ctxt,
       }
   while (dwarf_siblingof(&child, &child) == 0);
 
-  result.reset(is_method
-              ? new method_type(is_type(return_type_decl),
-                                is_method,
-                                function_parms,
-                                tu->get_address_size(),
-                                /*alignment=*/0)
-              : new function_type(is_type(return_type_decl),
-                                  function_parms,
-                                  tu->get_address_size(),
-                                  /*alignment=*/0));
-
-  tu->bind_function_type_life_time(result);
+  result->set_parameters(function_parms);
 
   return result;
 }
@@ -7872,9 +7877,6 @@ build_ir_node_from_die(read_context&      ctxt,
        if (f)
          {
            result = f;
-           ctxt.associate_die_to_type(dwarf_dieoffset(die),
-                                      die_is_from_alt_di,
-                                      f);
            maybe_canonicalize_type(dwarf_dieoffset(die),
                                    die_is_from_alt_di,
                                    ctxt);
index 314ff11cf6d554cd5772410a4b23df4d19f57405..2625bb339cc700d4bb8146373bd2dfa1503cf91f 100644 (file)
@@ -8232,7 +8232,22 @@ function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
 /// @param p the new vector of parameters to set.
 void
 function_type::set_parameters(const parameters &p)
-{priv_->parms_ = p;}
+{
+  priv_->parms_ = p;
+  for (parameters::size_type i = 0, j = 1;
+       i < priv_->parms_.size();
+       ++i, ++j)
+    {
+      if (i == 0 && priv_->parms_[i]->get_artificial())
+       // If the first parameter is artificial, then it certainly
+       // means that this is a member function, and the first
+       // parameter is the implicit this pointer.  In that case, set
+       // the index of that implicit parameter to zero.  Otherwise,
+       // the index of the first parameter starts at one.
+       j = 0;
+      priv_->parms_[i]->set_index(j);
+    }
+}
 
 /// Append a new parameter to the vector of parameters of the current
 /// instance of @ref function_type.
This page took 0.055211 seconds and 5 git commands to generate.