On Fri, Oct 25, 2013 at 03:04:41PM -0400, Jason Merrill wrote: > >I'm sorry, you want me to move the c++1y VLA check into > >compute_array_index_type, or just do the ubsan instrumentation in > >there? Thanks, > > Both.
Unfortunately, I'm having quite a lot of trouble with side-effects. :( For e.g. int x = 1; int a[++x]; with the following hunk --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8394,6 +8382,18 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t com if (found) itype = variable_size (fold (newitype)); } + + if ((flag_sanitize & SANITIZE_VLA) + && !processing_template_decl + /* From C++1y onwards, we throw an exception on a negative + length size of an array; see above */ + && cxx_dialect < cxx1y) + { + tree x = cp_save_expr (size); + x = build2 (COMPOUND_EXPR, TREE_TYPE (x), + ubsan_instrument_vla (input_location, x), x); + finish_expr_stmt (x); + } } /* Make sure that there was no overflow when creating to a signed index type. (For example, on a 32-bit machine, an array with we generate int x = 1; int a[0:(sizetype) SAVE_EXPR <D.2143>]; <<cleanup_point int x = 1;>>; <<cleanup_point <<< Unknown tree: expr_stmt if (SAVE_EXPR < ++x> <= 0) { __builtin___ubsan_handle_vla_bound_not_positive (&*.Lubsan_data0, (unsigned long) SAVE_EXPR < ++x>); } else { 0 }, (void) SAVE_EXPR < ++x>; >>>>>; ssizetype D.2143; <<cleanup_point <<< Unknown tree: expr_stmt (void) (D.2143 = (ssizetype) ++x + -1) >>>>>; <<cleanup_point int a[0:(sizetype) SAVE_EXPR <D.2143>];>>; that is, x is incremented twice and that is wrong. Is it possible to tell "x has already been evaluated, don't evaluate it again" so that the x isn't incremented in the cleanup_point? Or, would you, please, have some other advice? I've been looking into this for quite some time now, but haven't been able to come up with anything better than moving the checks back to create_array_type_for_decl, where it all started ;). Marek