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.