[patch] Fix PR c++/23118, ICE on invalid overloading

Volker Reichelt reichelt@igpm.rwth-aachen.de
Sun Aug 14 11:51:00 GMT 2005


The following testcase causes a segfault since GCC 3.0:

  struct A
  {
    void foo();
    virtual void foo();
  };

PR23118.cc:4: error: 'virtual void A::foo()' cannot be overloaded
PR23118.cc:3: error: with 'void A::foo()'
PR23118.cc:2: internal compiler error: Segmentation fault

The problem is the following loop in build_vtbl_initializer in cp/class.c:

  for (b = binfo; ; b = get_primary_binfo (b))
    {
      /* We found a defn before a lost primary; go ahead as normal.  */
      if (look_for_overrides_here (BINFO_TYPE (b), fn_original))
	break;

      /* The nearest definition is from a lost primary; clear the
	 slot.  */
      if (BINFO_LOST_PRIMARY_P (b))
	{
	  init = size_zero_node;
	  break;
	}
    }

Because of the invalid code, b is a NULL_TREE and this is causing the
segfault. Since b is only used in the loop, the problem can be fixed
by leaving the loop if b == NULL_TREE.

The loop has a sibling in update_vtable_entry_for_fn. If we find an
empty binfo, we cannot update the vtable and should therefore skip the
rest of the function. Without this modification we would trigger an ICE
with the attached testcase.

Bootstrapped and regtested on i686-pc-linux-gnu.
Ok for mainline, 4.0 branch and 3.4 branch?

(Well the patch has to be modified for the 3.4 branch: the gcc_assert
has to be changed into a my_friendly_assert and the first dg-error marker
in the testcase has to be deleted. Apart from that the patch is the same
so that I refrained from posting it, too.)

Regards,
Volker


2005-08-12  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/23118
	* class.c (update_vtable_entry_for_fn): Check for empty binfo.
	(build_vtbl_initializer): Likewise.

===================================================================
--- gcc/gcc/cp/class.c	8 Jul 2005 23:36:55 -0000	1.726
+++ gcc/gcc/cp/class.c	12 Aug 2005 10:20:37 -0000
@@ -1956,7 +1956,8 @@ update_vtable_entry_for_fn (tree t, tree
      calling FN through BINFO.  */
   for (b = binfo; ; b = get_primary_binfo (b))
     {
-      gcc_assert (b);
+      if (!b)
+	return;
       if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
 	break;
 
@@ -7182,10 +7183,10 @@ build_vtbl_initializer (tree binfo,
 
 	 We first check this in update_vtable_entry_for_fn, so we handle
 	 restored primary bases properly; we also need to do it here so we
-	 zero out unused slots in ctor vtables, rather than filling themff
+	 zero out unused slots in ctor vtables, rather than filling them
 	 with erroneous values (though harmless, apart from relocation
 	 costs).  */
-      for (b = binfo; ; b = get_primary_binfo (b))
+      for (b = binfo; b; b = get_primary_binfo (b))
 	{
 	  /* We found a defn before a lost primary; go ahead as normal.  */
 	  if (look_for_overrides_here (BINFO_TYPE (b), fn_original))
===================================================================


2005-08-12  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/23118
	* g++.dg/overload/error2.C: New test.

===================================================================
--- gcc/gcc/testsuite/g++.dg/overload/error2.C	2005-06-27 13:32:40.055820328 +0200
+++ gcc/gcc/testsuite/g++.dg/overload/error2.C	2005-08-05 21:34:44.000000000 +0200
@@ -0,0 +1,16 @@
+// PR c++/23118
+// ICE on invalid overload
+// Origin: Flash Sheridan  <flash@pobox.com>
+//         Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
+// { dg-do compile }
+
+struct A
+{
+  void foo();          // { dg-error "with" }
+  virtual void foo();  // { dg-error "cannot be overloaded" }
+};
+
+struct B : A
+{
+  void foo();
+};
===================================================================




More information about the Gcc-patches mailing list