diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index 6d64c0c7..46f08a9e 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -4552,12 +4552,7 @@ public:
 	  ABG_ASSERT(is_member_function(i->second));
 	  ABG_ASSERT(get_member_function_is_virtual(i->second));
 	  i->second->set_symbol(sym);
-	  // The function_decl now has an associated (public) ELF symbol so
-	  // it ought to be advertised as being public.
-	  i->second->set_is_in_public_symbol_table(true);
-	  // Add the function to the set of exported decls of the
-	  // current corpus.
-	  maybe_add_fn_to_exported_decls(i->second.get());
+
 	  if (do_log())
 	    cerr << "fixed up '"
 		 << i->second->get_pretty_representation()
@@ -16016,7 +16011,13 @@ build_ir_node_from_die(reader&	rdr,
 
 	if (fn)
 	  {
-	    rdr.maybe_add_fn_to_exported_decls(fn.get());
+	    if (!is_member_function(fn)
+		|| !get_member_function_is_virtual(fn))
+	      // Virtual member functions are added to the set of
+	      // functions exported by the current ABI corpus *after*
+	      // the canonicalization of their parent type.  So let's
+	      // not do it here.
+	      rdr.maybe_add_fn_to_exported_decls(fn.get());
 	    rdr.associate_die_to_decl(die, fn, where_offset,
 				       /*associate_by_repr=*/false);
 	    maybe_canonicalize_type(fn->get_type(), rdr);
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index d3fbafb4..d0d92055 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -15649,18 +15649,15 @@ static void
 maybe_adjust_canonical_type(const type_base_sptr& canonical,
 			    const type_base_sptr& type)
 {
-  if (!canonical
-      // If 'type' is *NOT* a newly canonicalized type ...
-      || type->get_naked_canonical_type()
-      // ... or if 'type' is it's own canonical type, then get out.
-      || type.get() == canonical.get())
+  if (type->get_naked_canonical_type())
     return;
 
+  class_decl_sptr canonical_class = is_class_type(canonical);
+
   if (class_decl_sptr cl = is_class_type(type))
     {
-      class_decl_sptr canonical_class = is_class_type(canonical);
-
-      if (canonical_class)
+      if (canonical_class
+	  && canonical_class.get() != cl.get())
 	{
 	  // Set symbols of member functions that might be missing
 	  // theirs.
@@ -15695,6 +15692,37 @@ maybe_adjust_canonical_type(const type_base_sptr& canonical,
 	}
     }
 
+  // Make sure the virtual member functions with exported symbols are
+  // all added to the set of exported functions of the corpus.
+
+  // If we are looking at a non-canonicalized class (for instance, a
+  // decl-only class that has virtual member functoins), let's pretend
+  // it does have a canonical class so that we can perform the
+  // necessary virtual  member function adjustments
+  if (class_decl_sptr cl = is_class_type(type))
+    if (is_non_canonicalized_type(cl))
+      {
+	ABG_ASSERT(!canonical_class);
+	canonical_class = cl;
+      }
+
+  if (canonical_class)
+    {
+      if (auto abi_corpus = canonical_class->get_corpus())
+	{
+	  for (auto& fn : canonical_class->get_member_functions())
+	    {
+	      if (elf_symbol_sptr sym = fn->get_symbol())
+		if (sym->is_defined() && sym->is_public())
+		  {
+		    fn->set_is_in_public_symbol_table(true);
+		    auto b = abi_corpus->get_exported_decls_builder();
+		    b->maybe_add_fn_to_exported_fns(fn.get());
+		  }
+	    }
+	}
+    }
+
   // If an artificial function type equals a non-artfificial one in
   // the system, then the canonical type of both should be deemed
   // non-artificial.  This is important because only non-artificial
diff --git a/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi b/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi
index a7ee1ef3..8c598216 100644
--- a/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi
+++ b/tests/data/test-read-dwarf/test9-pr18818-clang.so.abi
@@ -4810,7 +4810,7 @@
             </function-decl>
           </member-function>
           <member-function access='public' destructor='yes' vtable-offset='0'>
-            <function-decl name='~system_error' mangled-name='_ZN5boost6system12system_errorD2Ev' filepath='src/third_party/boost-1.56.0/boost/system/system_error.hpp' line='47' column='1' visibility='default' binding='global' size-in-bits='64'>
+            <function-decl name='~system_error' mangled-name='_ZN5boost6system12system_errorD2Ev' filepath='src/third_party/boost-1.56.0/boost/system/system_error.hpp' line='47' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN5boost6system12system_errorD2Ev'>
               <parameter type-id='type-id-206' is-artificial='yes'/>
               <return type-id='type-id-118'/>
             </function-decl>
