diff --git a/src/abg-ir-priv.h b/src/abg-ir-priv.h
index 5c108dd3..dd3c6276 100644
--- a/src/abg-ir-priv.h
+++ b/src/abg-ir-priv.h
@@ -200,12 +200,14 @@ struct type_base::priv
   // The set of canonical recursive types this type depends on.
   unordered_set<uintptr_t> depends_on_recursive_type_;
   bool canonical_type_propagated_;
+  bool propagated_canonical_type_confirmed_;
 
   priv()
     : size_in_bits(),
       alignment_in_bits(),
       naked_canonical_type(),
-      canonical_type_propagated_(false)
+      canonical_type_propagated_(false),
+      propagated_canonical_type_confirmed_(false)
   {}
 
   priv(size_t s,
@@ -215,7 +217,8 @@ struct type_base::priv
       alignment_in_bits(a),
       canonical_type(c),
       naked_canonical_type(c.get()),
-      canonical_type_propagated_(false)
+      canonical_type_propagated_(false),
+      propagated_canonical_type_confirmed_(false)
   {}
 
   /// Test if the current type depends on recursive type comparison.
@@ -306,12 +309,38 @@ struct type_base::priv
   set_canonical_type_propagated(bool f)
   {canonical_type_propagated_ = f;}
 
+  /// Getter of the property propagated-canonical-type-confirmed.
+  ///
+  /// If canonical_type_propagated() returns true, then this property
+  /// says if the propagated canonical type has been confirmed or not.
+  /// If it hasn't been confirmed, then it means it can still
+  /// cancelled.
+  ///
+  /// @return true iff the propagated canonical type has been
+  /// confirmed.
+  bool
+  propagated_canonical_type_confirmed() const
+  {return propagated_canonical_type_confirmed_;}
+
+  /// Setter of the property propagated-canonical-type-confirmed.
+  ///
+  /// If canonical_type_propagated() returns true, then this property
+  /// says if the propagated canonical type has been confirmed or not.
+  /// If it hasn't been confirmed, then it means it can still
+  /// cancelled.
+  ///
+  /// @param f If this is true then the propagated canonical type has
+  /// been confirmed.
+  void
+  set_propagated_canonical_type_confirmed(bool f)
+  {propagated_canonical_type_confirmed_ = f;}
+
   /// If the current canonical type was set as the result of the
   /// "canonical type propagation optimization", then clear it.
   void
   clear_propagated_canonical_type()
   {
-    if (canonical_type_propagated_)
+    if (canonical_type_propagated_ && !propagated_canonical_type_confirmed_)
       {
 	canonical_type.reset();
 	naked_canonical_type = nullptr;
@@ -810,7 +839,7 @@ struct environment::priv
   /// propagation optimization" at @ref OnTheFlyCanonicalization, in
   /// the src/abg-ir.cc file.
   void
-  confirm_ct_propagation(const type_base* dependant_type)
+  confirm_ct_propagation_for_types_dependant_on(const type_base* dependant_type)
   {
     pointer_set to_remove;
     for (auto i : types_with_non_confirmed_propagated_ct_)
@@ -820,13 +849,65 @@ struct environment::priv
 		   || t->priv_->depends_on_recursive_type());
 	t->priv_->set_does_not_depend_on_recursive_type(dependant_type);
 	if (!t->priv_->depends_on_recursive_type())
-	  to_remove.insert(i);
+	  {
+	    to_remove.insert(i);
+	    t->priv_->set_propagated_canonical_type_confirmed(true);
+	  }
       }
 
     for (auto i : to_remove)
       types_with_non_confirmed_propagated_ct_.erase(i);
   }
 
+  /// Mark a type that has been the target of canonical type
+  /// propagation as being permanently canonicalized.
+  ///
+  /// This function also marks the set of types that have been the
+  /// target of canonical type propagation and that depend on a
+  /// recursive type as being permanently canonicalized.
+  ///
+  /// To understand the sentence above, please read the description of
+  /// type canonicalization and especially about the "canonical type
+  /// propagation optimization" at @ref OnTheFlyCanonicalization, in
+  /// the src/abg-ir.cc file.
+  void
+  confirm_ct_propagation(const type_base*t)
+  {
+    if (!t || t->priv_->propagated_canonical_type_confirmed())
+      return;
+
+    const environment* env = t->get_environment();
+    ABG_ASSERT(env);
+
+    env->priv_->confirm_ct_propagation_for_types_dependant_on(t);
+    t->priv_->set_does_not_depend_on_recursive_type();
+    env->priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
+    env->priv_->set_is_not_recursive(t);
+    t->priv_->set_propagated_canonical_type_confirmed(true);
+  }
+
+  /// Mark all the types that have been the target of canonical type
+  /// propagation and that are not yet confirmed as being permanently
+  /// canonicalized (aka confirmed).
+  ///
+  /// To understand the sentence above, please read the description of
+  /// type canonicalization and especially about the "canonical type
+  /// propagation optimization" at @ref OnTheFlyCanonicalization, in
+  /// the src/abg-ir.cc file.
+  void
+  confirm_ct_propagation()
+  {
+    for (auto i : types_with_non_confirmed_propagated_ct_)
+      {
+	type_base *t = reinterpret_cast<type_base*>(i);
+	ABG_ASSERT(t->get_environment()->priv_->is_recursive_type(t)
+		   || t->priv_->depends_on_recursive_type());
+	t->priv_->set_does_not_depend_on_recursive_type();
+	t->priv_->set_propagated_canonical_type_confirmed(true);
+      }
+    types_with_non_confirmed_propagated_ct_.clear();
+  }
+
   /// Collect the types that depends on a given "target" type.
   ///
   /// Walk a set of types and if they depend directly or indirectly on
@@ -868,7 +949,7 @@ struct environment::priv
   /// depend on a given recursive type.
   ///
   /// Once the canonical type of a type in that set is reset, the type
-  /// is marked as non being dependant on a recursive type anymore.
+  /// is marked as being non-dependant on a recursive type anymore.
   ///
   /// To understand the sentences above, please read the description
   /// of type canonicalization and especially about the "canonical
@@ -879,7 +960,7 @@ struct environment::priv
   /// type propagation optimizationdepends on a this target type, then
   /// cancel its canonical type.
   void
-  cancel_ct_propagation(const type_base* target)
+  cancel_ct_propagation_for_types_dependant_on(const type_base* target)
   {
     pointer_set to_remove;
     collect_types_that_depends_on(target,
@@ -903,6 +984,58 @@ struct environment::priv
       types_with_non_confirmed_propagated_ct_.erase(i);
   }
 
+  /// Reset the canonical type (set it nullptr) of a type that has
+  /// been the target of canonical type propagation.
+  ///
+  /// This also resets the propagated canonical type of the set of
+  /// types that depends on a given recursive type.
+  ///
+  /// Once the canonical type of a type in that set is reset, the type
+  /// is marked as being non-dependant on a recursive type anymore.
+  ///
+  /// To understand the sentences above, please read the description
+  /// of type canonicalization and especially about the "canonical
+  /// type propagation optimization" at @ref OnTheFlyCanonicalization,
+  /// in the src/abg-ir.cc file.
+  ///
+  /// @param target if a type which has been subject to the canonical
+  /// type propagation optimizationdepends on a this target type, then
+  /// cancel its canonical type.
+  void
+  cancel_ct_propagation(const type_base* t)
+  {
+    if (!t)
+      return;
+
+    const environment *env = t->get_environment();
+    env->priv_->cancel_ct_propagation_for_types_dependant_on(t);
+    if (t->priv_->depends_on_recursive_type()
+	|| env->priv_->is_recursive_type(t))
+      {
+	// This cannot carry any tentative canonical type at this
+	// point.
+	if (t->priv_->canonical_type_propagated()
+	    && !t->priv_->propagated_canonical_type_confirmed())
+	  t->priv_->clear_propagated_canonical_type();
+	// Reset the marking of the type as it no longer carries a
+	// tentative canonical type that might be later cancelled.
+	t->priv_->set_does_not_depend_on_recursive_type();
+	env->priv_->remove_from_types_with_non_confirmed_propagated_ct(t);
+      }
+  }
+
+  /// Add a given type to the set of types that have been
+  /// non-confirmed subjects of the canonical type propagation
+  /// optimization.
+  ///
+  /// @param t the dependant type to consider.
+  void
+  add_to_types_with_non_confirmed_propagated_ct(const type_base *t)
+  {
+    uintptr_t v = reinterpret_cast<uintptr_t>(t);
+    types_with_non_confirmed_propagated_ct_.insert(v);
+  }
+
   /// Remove a given type from the set of types that have been
   /// non-confirmed subjects of the canonical type propagation
   /// optimization.
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index f739b126..2563b5b3 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -1084,13 +1084,14 @@ return_comparison_result(T& l, T& r, bool value,
       if (value == true
 	  && (is_type(&r)->priv_->depends_on_recursive_type()
 	      || env->priv_->is_recursive_type(&r))
-	  && is_type(&r)->priv_->canonical_type_propagated())
+	  && is_type(&r)->priv_->canonical_type_propagated()
+	  && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
+	  && !env->priv_->right_type_comp_operands_.empty())
 	{
 	  // Track the object 'r' for which the propagated canonical
 	  // type might be re-initialized if the current comparison
 	  // eventually fails.
-	  env->priv_->types_with_non_confirmed_propagated_ct_.insert
-	    (reinterpret_cast<uintptr_t>(is_type(&r)));
+	  env->priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
 	}
       else if (value == true && env->priv_->right_type_comp_operands_.empty())
 	{
@@ -1102,13 +1103,6 @@ return_comparison_result(T& l, T& r, bool value,
 	  // sub-types that were compared during the comparison of
 	  // 'r'.
 	  env->priv_->confirm_ct_propagation(&r);
-	  if (is_type(&r)->priv_->depends_on_recursive_type()
-	      || env->priv_->is_recursive_type(&r))
-	    {
-	      is_type(&r)->priv_->set_does_not_depend_on_recursive_type();
-	      env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&r);
-	      env->priv_->set_is_not_recursive(&r);
-	    }
 	}
       else if (value == false)
 	{
@@ -1118,20 +1112,25 @@ return_comparison_result(T& l, T& r, bool value,
 	  // should see their tentatively propagated canonical type
 	  // cancelled.
 	  env->priv_->cancel_ct_propagation(&r);
-	  if (is_type(&r)->priv_->depends_on_recursive_type()
-	      || env->priv_->is_recursive_type(&r))
-	    {
-	      // The right-hand-side operand cannot carry any tentative
-	      // canonical type at this point.
-	      is_type(&r)->priv_->clear_propagated_canonical_type();
-	      // Reset the marking of the right-hand-side operand as it no
-	      // longer carries a tentative canonical type that might be
-	      // later cancelled.
-	      is_type(&r)->priv_->set_does_not_depend_on_recursive_type();
-	      env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&r);
-	    }
 	}
     }
+
+  // If we reached this point with value == true and the stack of
+  // types being compared is empty, then it means that the type pair
+  // that was at the bottom of the stack is now fully compared.
+  //
+  // It follows that all types that were target of canonical type
+  // propagation can now see their tentative canonical type be
+  // confirmed for real.
+  if (value == true
+      && env->priv_->right_type_comp_operands_.empty()
+      && !env->priv_->types_with_non_confirmed_propagated_ct_.empty())
+    // So the comparison is completely done and there are some
+    // types for which their propagated canonical type is sitll
+    // considered not confirmed.  As the comparison did yield true, we
+    // shall now confirm the propagation for all those types.
+    env->priv_->confirm_ct_propagation();
+
   ABG_RETURN(value);
 }
 
@@ -14666,6 +14665,19 @@ canonicalize(type_base_sptr t)
   t->priv_->canonical_type = canonical;
   t->priv_->naked_canonical_type = canonical.get();
 
+  // So this type is now canonicalized.
+  //
+  // It means that:
+  //
+  //   1/ Either the canonical type was not propagated during the
+  //      comparison of another type that was being canonicalized
+  //
+  //   2/ Or the canonical type has been propagated during the
+  //      comparison of another type was being canonicalized and that
+  //      propagated canonical type has been confirmed.
+  ABG_ASSERT(!t->priv_->canonical_type_propagated()
+	     || t->priv_->propagated_canonical_type_confirmed());
+
   if (class_decl_sptr cl = is_class_type(t))
     if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
       if ((canonical = d->get_canonical_type()))
