This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Fix PR c++/22508 ICE after invalid operator new


Consider the testcase

  struct A
  {
    void* operator new(__SIZE_TYPE__) throw(X);
  };

  A* p = new A;

In the function build_new_1 from cp/init.c the compiler calls
lookup_fnfields to find the appropriate new operator for "A".
Since we only have an invalid one, a NULL_TREE is returned and
assigend to "fns". We then get a segfault in the next line:

 if (TREE_CODE (fns) == TREE_LIST)

The following patch adds a test for "fns" being empty and
emits an appropriate error message. The patch also adds
the above testcase.

Bootstrapped and regtested on i686-pc-linux-gnu.
Ok for mainline and 4.0 branch (since this is a regression)?

After testing the patch I found the following code on the 3.4 branch:

  if (!fns)
    {
      /* See PR 15967. This should never happen (and it is
	 fixed correctly in mainline), but on the release branch
	 we prefer this less-intrusive approacch.  */
      error ("no suitable or ambiguous `%D' found in class `%T'",
	     fnname, true_type);
      return error_mark_node;
    }

PR 15967 is about having more than one candidate which is indeed fixed
on mainline (and the 4.0 branch). However, the case that we have no
candidate is not fixed there. The suggested patch would add the same
check as on the 3.4 branch (with a slightly reworded error message)
and would therefore invalidate the above comment.

Ok to remove the comment from the 3.4 branch as it would confuse the
reader?

Regards,
Volker


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

	PR c++/22508
        * init.c (build_new_1): Check for empty candidate list.

====================================================================
--- gcc/gcc/cp/init.c	2005-08-05 12:25:29.000000000 +0200
+++ gcc/gcc/cp/init.c	2005-08-05 12:26:49.000000000 +0200
@@ -1917,6 +1917,11 @@ build_new_1 (tree exp)
 	  args = tree_cons (NULL_TREE, size, placement);
 	  /* Do name-lookup to find the appropriate operator.  */
 	  fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
+	  if (fns == NULL_TREE)
+	    {
+	      error ("no suitable %qD found in class %qT", fnname, elt_type);
+	      return error_mark_node;
+	    }
 	  if (TREE_CODE (fns) == TREE_LIST)
 	    {
 	      error ("request for member %qD is ambiguous", fnname);
====================================================================

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

	PR c++/22508
        * g++.dg/init/new13.C: New test.

====================================================================
--- gcc/gcc/testsuite/g++.dg/init/new13.C      2003-09-23 19:59:22.000000000 +0200
+++ gcc/gcc/testsuite/g++.dg/init/new13.C      2005-08-05 12:37:04.000000000 +0200
@@ -0,0 +1,11 @@
+// PR c++/22508
+// ICE on invalid operator new
+// Origin: Flash Sheridan  <flash@pobox.com>
+// { dg-do compile }
+
+struct A
+{
+  void* operator new(__SIZE_TYPE__) throw(X);  // { dg-error "" }
+};
+
+A* p = new A;                                  // { dg-error "no suitable" }
====================================================================



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]