On 01/08/2018 04:01 PM, David Malcolm wrote:
On Fri, 2018-01-05 at 15:29 -0500, Jason Merrill wrote:
I'd rather handle location wrappers separately, and abort if
VIEW_CONVERT_EXPR or NON_LVALUE_EXPR appear other than as wrappers.
Once I fixed the issue with location_wrapper_p with decls changing
type, it turns out that trunk is already passing VIEW_CONVERT_EXPR to
tsubst_copy_and_build for non-wrapper nodes (and from there to
tsubst_copy), where the default case currently handles them. Adding an
assert turns this into an ICE.
g++.dg/delayedfold/builtin1.C is the only instance of it I found in our
test suite, where it's used here:
class RegionLock {
template <unsigned long> void m_fn1();
int spinlock;
} acquire_zero;
int acquire_one;
template <unsigned long> void RegionLock::m_fn1() {
__atomic_compare_exchange(&spinlock, &acquire_zero, &acquire_one, false, 2,
2);
^~~~~~~~~~~~~
}
(gdb) call debug_tree (t)
<view_convert_expr 0x7ffff1a15b40
...
arg:0 <non_dependent_expr 0x7ffff1a15aa0
...
arg:0 <addr_expr 0x7ffff1a159e0 type <pointer_type
0x7ffff1a18150>
arg:0 <var_decl 0x7ffff7ffbd80 acquire_zero>
(This one is just for VIEW_CONVERT_EXPR; I don't yet know of any
existing places where NON_LVALUE_EXPR can be passed to tsubst_*).
Hmm, a NON_DEPENDENT_EXPR also shouldn't make it into the saved trees
for a template. I'll take a look.
Jason