http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46526

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> 2010-11-19 
09:55:10 UTC ---
Created attachment 22454
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=22454
gcc46-pr46526.patch

Possible fix.  Not sure how often C++ FE tries to modify something within
expressions returned by cxx_eval_constant_expression.  This patch is
conservative, perhaps might create too much garbage.  On the other side,
looking at what is done in other parts of cxx_eval_constant_expression, it
usually just creates new trees and thus has the unsharing semantics in it.
If cxx_eval_bare_aggregate's:
          /* Push our vtable pointer down into the base where it belongs.  */
          tree vptr_base = DECL_CONTEXT (ce->index);
          tree base_ctor;
          gcc_assert (ce->index == TYPE_VFIELD (type));
          for (base_ctor = VEC_index (constructor_elt, n, 0)->value; ;
               base_ctor = CONSTRUCTOR_ELT (base_ctor, 0)->value)
            if (TREE_TYPE (base_ctor) == vptr_base)
              { 
                constructor_elt *p = CONSTRUCTOR_ELT (base_ctor, 0);
                gcc_assert (p->index == ce->index);
                p->value = elt;
                break;
              }
is the only spot that actually tries to modify cxx_eval_constant_expression in
place, one could instead unshare it before starting to dive into the arguments,
but that could very well unshare twice e.g. all CONSTRUCTORS that went through
cxx_eval_bare_aggregate which created a new tree.

So this patch looks preferrable to me, but of course this is Jason's call what
to do.

Reply via email to