https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63764
--- Comment #7 from joseph at codesourcery dot com <joseph at codesourcery dot com> --- On Tue, 18 Nov 2014, jakub at gcc dot gnu.org wrote: > does. The difference is when > handling the (type) saijplus16 cast in build_c_cast. > In the ppc case and fn3 case, the type is the same, so we end up with > NON_LVALUE_EXPR of saijplus16. In the fn2 case with V typedef, the type is > different (saijplus16 has V type, the cast uses its main variant), so we end > up > with VIEW_CONVERT_EXPR of saijplus16 instead. The VCE gets folded away, while > NON_LVALUE_EXPR remains. But in all cases the casts aren't valid lvalue. > Note, C++ ICEs on all the testcases. > IMHO either we need to reject it (but how to find out in the case of > build_c_cast that it originally was non-lvalue?), or we need to skip the > NON_LVALUE_EXPRs when marking the var as addressable and taking address of it. What folds away the VIEW_CONVERT_EXPR, when? c-typeck.c:lvalue_p does not consider VIEW_CONVERT_EXPRs to be lvalues, and lvalue checks are meant to happen before any folding that could change a non-lvalue to an lvalue. Maybe build_array_ref needs to ensure that references to elements of non-lvalue vectors don't become lvalues? (This would be different to non-lvalue arrays arising from non-lvalue structs and unions, where the result of an array reference *is* an lvalue but modifying it, or accessing it after the next sequence point, has undefined behavior.)