Patchwork [C++] PR 51326

login
register
mail settings
Submitter Paolo Carlini
Date Dec. 1, 2011, 10:43 a.m.
Message ID <4ED75A6F.7000500@oracle.com>
Download mbox | patch
Permalink /patch/128680/
State New
Headers show

Comments

Paolo Carlini - Dec. 1, 2011, 10:43 a.m.
Hi,

in this ICE on invalid, 4.7 Regression, we ICE at the beginning of 
build_user_type_conversion_1 because expr is NULL_TREE. The function is 
called as such from reference_binding which, in 4.6, used to call 
instead convert_class_to_reference which does check for a NULL_TREE 
expr. Thus I think adjusting likewise build_user_type_conversion_1 
should be fine. Tested x86_64-linux.

Thanks,
Paolo.

//////////////////
/cp
2011-12-01  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/51326
	* call.c (build_user_type_conversion_1): Early return NULL if
	expr is NULL_TREE.

/testsuite
2011-12-01  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/51326
	* g++.dg/inherit/crash3.C: New.
Jason Merrill - Dec. 1, 2011, 9:52 p.m.
OK.

Jason
Dodji Seketeli - Dec. 3, 2011, 9:25 p.m.
Hello Paolo,

Paolo Carlini <paolo.carlini@oracle.com> a écrit:

> Index: cp/call.c
> ===================================================================
> --- cp/call.c	(revision 181875)
> +++ cp/call.c	(working copy)
> @@ -3373,7 +3373,7 @@ static struct z_candidate *
>  build_user_type_conversion_1 (tree totype, tree expr, int flags)
>  {
>    struct z_candidate *candidates, *cand;
> -  tree fromtype = TREE_TYPE (expr);
> +  tree fromtype;
>    tree ctors = NULL_TREE;
>    tree conv_fns = NULL_TREE;
>    conversion *conv = NULL;
> @@ -3382,6 +3382,11 @@ build_user_type_conversion_1 (tree totype, tree ex
>    bool any_viable_p;
>    int convflags;
>  
> +  if (!expr)
> +    return NULL;
> +
> +  fromtype = TREE_TYPE (expr);
> +
>    /* We represent conversion within a hierarchy using RVALUE_CONV and
>       BASE_CONV, as specified by [over.best.ics]; these become plain
>       constructor calls, as specified in [dcl.init].  */

This might be a theoretical nit, but it looks like if expr is
error_mark_node, we'd crash as well, because of the line below that comes
right after the comment above:

  gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
	      || !DERIVED_FROM_P (totype, fromtype));

I don't have a test case for that though.
Jason Merrill - Dec. 4, 2011, 12:20 a.m.
On 12/03/2011 04:25 PM, Dodji Seketeli wrote:
> This might be a theoretical nit, but it looks like if expr is
> error_mark_node, we'd crash as well, because of the line below that comes
> right after the comment above:
>
>    gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
> 	      || !DERIVED_FROM_P (totype, fromtype));

That should be OK, since TREE_TYPE (error_mark_node) is error_mark_node.

Jason
Dodji Seketeli - Dec. 4, 2011, 7:31 a.m.
Jason Merrill <jason@redhat.com> a écrit:

> On 12/03/2011 04:25 PM, Dodji Seketeli wrote:
>> This might be a theoretical nit, but it looks like if expr is
>> error_mark_node, we'd crash as well, because of the line below that comes
>> right after the comment above:
>>
>>    gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
>> 	      || !DERIVED_FROM_P (totype, fromtype));
>
> That should be OK, since TREE_TYPE (error_mark_node) is
> error_mark_node.

Oh, right.

Patch

Index: testsuite/g++.dg/inherit/crash3.C
===================================================================
--- testsuite/g++.dg/inherit/crash3.C	(revision 0)
+++ testsuite/g++.dg/inherit/crash3.C	(revision 0)
@@ -0,0 +1,11 @@ 
+// PR c++/51326
+
+struct A
+{
+  virtual int& foo(); // { dg-error "overriding" }
+};
+
+struct B : A
+{
+  B& foo();           // { dg-error "conflicting return type" }
+};
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 181875)
+++ cp/call.c	(working copy)
@@ -3373,7 +3373,7 @@  static struct z_candidate *
 build_user_type_conversion_1 (tree totype, tree expr, int flags)
 {
   struct z_candidate *candidates, *cand;
-  tree fromtype = TREE_TYPE (expr);
+  tree fromtype;
   tree ctors = NULL_TREE;
   tree conv_fns = NULL_TREE;
   conversion *conv = NULL;
@@ -3382,6 +3382,11 @@  build_user_type_conversion_1 (tree totype, tree ex
   bool any_viable_p;
   int convflags;
 
+  if (!expr)
+    return NULL;
+
+  fromtype = TREE_TYPE (expr);
+
   /* We represent conversion within a hierarchy using RVALUE_CONV and
      BASE_CONV, as specified by [over.best.ics]; these become plain
      constructor calls, as specified in [dcl.init].  */