On Fri, Nov 22, 2013 at 10:28:52AM +0100, Jakub Jelinek wrote: > Hi! > > Working virtually out of Pago Pago right now. > > In C++, falling through the end of a function that returns a value > without returning a value is undefined behavior (unlike C?), so this patch > implements instrumentation of it.
I think we really want to have this in for C99+ as well, mainly because C99 removed implicit int rule. > --- gcc/ubsan.c.jj 2013-11-22 01:40:03.000000000 +0100 > +++ gcc/ubsan.c 2013-11-22 10:05:29.491725405 +0100 > @@ -227,8 +227,8 @@ ubsan_source_location (location_t loc) > xloc = expand_location (loc); > > /* Fill in the values from LOC. */ > - size_t len = strlen (xloc.file); > - tree str = build_string (len + 1, xloc.file); > + size_t len = xloc.file ? strlen (xloc.file) : 0; > + tree str = build_string (len + 1, xloc.file ? xloc.file : ""); This shouldn't be needed - the ubsan_source_location call is guarded by if (loc != UNKNOWN_LOCATION). But it doesn't hurt either. > --- gcc/c-family/c-ubsan.c.jj 2013-11-19 21:56:20.000000000 +0100 > +++ gcc/c-family/c-ubsan.c 2013-11-22 09:52:31.810642606 +0100 > @@ -179,3 +179,14 @@ ubsan_instrument_vla (location_t loc, tr > > return t; > } > + > +/* Instrument missing return in C++ functions returning non-void. */ > + > +tree > +ubsan_instrument_return (location_t loc) > +{ > + tree data = ubsan_create_data ("__ubsan_missing_return_data", loc, > + NULL,NULL_TREE); Missing space after NULL. Otherwise the ubsan bits are ok. Recently I tried to implement this one, too, but I instead tweaked execute_warn_function_return in tree-cfg.c. It was something along the lines of (only tree-cfg.c changes here): --- gcc/tree-cfg.c.mp2 2013-11-22 12:42:13.452426763 +0100 +++ gcc/tree-cfg.c 2013-11-22 13:56:41.051581885 +0100 @@ -8090,9 +8090,16 @@ execute_warn_function_return (void) { location = gimple_location (last); if (location == UNKNOWN_LOCATION) - location = cfun->function_end_locus; - warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function"); + location = cfun->function_end_locus; + warning_at (location, OPT_Wreturn_type, "control reaches end " + "of non-void function"); TREE_NO_WARNING (cfun->decl) = 1; + if (flag_sanitize & SANITIZE_RETURN) + { + gimple_stmt_iterator gsi = gsi_for_stmt (last); + gsi_insert_before (&gsi, ubsan_instrument_return (location), + GSI_SAME_STMT); + } break; } } Marek