public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ RFC / Patch] Again about PR 70202
@ 2016-06-09 17:02 Paolo Carlini
  2016-06-09 17:06 ` Jakub Jelinek
  2016-06-09 21:39 ` Jason Merrill
  0 siblings, 2 replies; 14+ messages in thread
From: Paolo Carlini @ 2016-06-09 17:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

Hi again,

thus today I had to revert my first try at resolving this error recovery 
issue because it caused c++/71465. In retrospect it was a bit heavy 
handed anyway, the zeroing of the type served us well for many years...

Today I tried to investigate the issue a bit more. I remind you that we 
are crashing on the gcc_unreachable () at the end of 
build_simple_base_path while, during error recovery, we are processing 
the initialization of the final 'a' in:

class A
{
   virtual void foo () { }
};
class B : public A, A { };  // { dg-error "duplicate base type" }

B b1, &b2 = b1;
A a = b2;

Now the first comment I have about this, about which I'd like to have 
some feedback, is that the gcc_unreachable () at the end of 
build_simple_base_path without a return seems a bit weird to me, because 
the function is *supposed to return a tree*, not void. I guess some 
front-ends would even warn on this?!? Anyway, if we change:


     /* */

     gcc_unreachable ();
}

to:

     /* */

     gcc_assert (seen_error ());
     return error_mark_node;
}

we get something which, by and large is equally safe in terms of 
miscompilations and helps a lot error recovery, ie, we would not have 
c++/70202. It's also true however that we would not make much progress 
in trying to understand if we could solve the specific problem at issue 
in a more insightful way.

Then my next observation is the following: if we change the testcase to:

class A
{
   virtual void foo () { }
};
class B : public A, A { };  // { dg-error "duplicate base type" }

B b1, &b2 = b1;
A a = b1;

thus everything is the same but at the end we have 'b1', not 'b2', we 
also don't crash. We are saved not by something particularly smart ;) 
but by this check at the beginning of ocp_convert:

   if (error_operand_p (e) || type == error_mark_node)
      return error_mark_node;

that is, the TREE_TYPE of 'e', the VAR_DECL for 'b1', is error_mark_node 
and we return early the error_mark_node, we don't reach the problematic 
build_base_path. With 'b2' we have a more complicated REFERENCE_REF 
which we don't catch, but otherwise everything is the same, we reach 
build_base_path and we crash on the gcc_unreachable. In practice, if I 
add at the beginning of ocp_convert:

+  if (REFERENCE_REF_P (expr)
+      && VAR_P (TREE_OPERAND (expr, 0))
+      && DECL_INITIAL (TREE_OPERAND (expr, 0)) == error_mark_node)
+    return error_mark_node;

it also passes testing. Then the final observation is that we also don't 
crash if the type of 'A' is simpler, thus we don't have the declaration of

     virtual void foo () { }

Then I gather that when the type is "complex" enough we are not cleaning 
things up completely enough when we encounter it as a duplicated base. 
Maybe as optimal error recovery when we see a duplicated base we should 
clean up everything having to do with bases end up with something 
equivalent to an incomplete class B; or something like that?!? I don't 
know what we want to try short / medium /long term...

Thanks!
Paolo.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-06-14 19:29 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-09 17:02 [C++ RFC / Patch] Again about PR 70202 Paolo Carlini
2016-06-09 17:06 ` Jakub Jelinek
2016-06-09 21:39 ` Jason Merrill
2016-06-09 23:29   ` Paolo Carlini
2016-06-10  1:43     ` Paolo Carlini
2016-06-10 20:09       ` Jason Merrill
2016-06-10 20:15         ` Paolo Carlini
2016-06-10 20:30         ` Paolo Carlini
2016-06-10 20:34           ` Paolo Carlini
2016-06-10 20:48             ` Paolo Carlini
2016-06-11 16:06               ` [C++ Patch] PR 70202: avoid creating incomplete types (was: "[C++ RFC / Patch] Again about PR 70202") Paolo Carlini
2016-06-14 13:06                 ` [C++ Patch] PR 70202: avoid creating incomplete types Jason Merrill
2016-06-14 18:09                   ` Paolo Carlini
2016-06-14 19:29                     ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).