On Sun, 2016-09-18 at 22:46 +0530, Prathamesh Kulkarni wrote: > On 2 September 2016 at 23:14, David Malcolm <dmalc...@redhat.com> > wrote: > > On Thu, 2016-09-01 at 14:55 +0530, Prathamesh Kulkarni wrote: > > > > [...] > > > > > The attached version passes bootstrap+test on ppc64le-linux-gnu. > > > Given that it only looks if parameters are restrict qualified and > > > not > > > how they're used inside the callee, > > > this can have false positives as in above test-cases. > > > Should the warning be put in Wextra rather than Wall (I have left > > > it > > > in Wall in the patch) or only enabled with -Wrestrict ? > > > > > > Thanks, > > > Prathamesh > > > > > > > > Richard. > > > > > > diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c > > index 3feb910..a3dae34 100644 > > --- a/gcc/c-family/c-common.c > > +++ b/gcc/c-family/c-common.c > > @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not > > see > > #include "gimplify.h" > > #include "substring-locations.h" > > #include "spellcheck.h" > > +#include "gcc-rich-location.h" > > > > cpp_reader *parse_in; /* Declared in c-pragma.h. */ > > > > @@ -13057,4 +13058,76 @@ diagnose_mismatched_attributes (tree > > olddecl, > > tree newdecl) > > return warned; > > } > > > > +/* Warn if an argument at position param_pos is passed to a > > + restrict-qualified param, and it aliases with another argument. > > */ > > + > > +void > > +warn_for_restrict (unsigned param_pos, vec<tree, va_gc> *args) > > +{ > > + tree arg = (*args)[param_pos]; > > + if (TREE_VISITED (arg) || operand_equal_p (arg, > > null_pointer_node, > > 0)) > > + return; > > + > > + location_t loc = EXPR_LOC_OR_LOC (arg, input_location); > > + gcc_rich_location richloc (loc); > > + > > + unsigned i; > > + tree current_arg; > > + auto_vec<unsigned> arg_positions; > > + > > + FOR_EACH_VEC_ELT (*args, i, current_arg) > > + { > > + if (i == param_pos) > > + continue; > > + > > + tree current_arg = (*args)[i]; > > + if (operand_equal_p (arg, current_arg, 0)) > > + { > > + TREE_VISITED (current_arg) = 1; > > + arg_positions.safe_push (i); > > + } > > + } > > + > > + if (arg_positions.is_empty ()) > > + return; > > + > > + struct obstack fmt_obstack; > > + gcc_obstack_init (&fmt_obstack); > > + char *fmt = (char *) obstack_alloc (&fmt_obstack, 0); > > + > > + char num[32]; > > + sprintf (num, "%u", param_pos + 1); > > + > > + obstack_grow (&fmt_obstack, "passing argument ", > > + strlen ("passing argument ")); > > + obstack_grow (&fmt_obstack, num, strlen (num)); > > + obstack_grow (&fmt_obstack, > > + " to restrict-qualified parameter aliases with > > argument", > > + strlen (" to restrict-qualified parameter " > > + "aliases with argument")); > > + > > + /* make argument plural and append space. */ > > + if (arg_positions.length () > 1) > > + obstack_1grow (&fmt_obstack, 's'); > > + obstack_1grow (&fmt_obstack, ' '); > > + > > + unsigned pos; > > + FOR_EACH_VEC_ELT (arg_positions, i, pos) > > + { > > + tree arg = (*args)[pos]; > > + if (EXPR_HAS_LOCATION (arg)) > > + richloc.add_range (EXPR_LOCATION (arg), false); > > + > > + sprintf (num, "%u", pos + 1); > > + obstack_grow (&fmt_obstack, num, strlen (num)); > > + > > + if (i < arg_positions.length () - 1) > > + obstack_grow (&fmt_obstack, ", ", strlen (", ")); > > + } > > + > > + obstack_1grow (&fmt_obstack, 0); > > + warning_at_rich_loc (&richloc, OPT_Wrestrict, fmt); > > + obstack_free (&fmt_obstack, fmt); > > +} > > > > Thanks for working on this. > > > > I'm not a fan of how the patch builds "fmt" here. If nothing else, > > this perhaps should be: > > > > warning_at_rich_loc (&richloc, OPT_Wrestrict, "%s", fmt); > > > > but building up strings like the patch does makes localization > > difficult. > > > > Much better would be to have the formatting be done inside the > > diagnostics subsystem's call into pp_format, with something like > > this: > > > > warning_at_rich_loc_n (&richloc, OPT_Wrestrict, > > arg_positions > > .length (), > > "passing argument %i to restrict > > -qualified" > > " parameter aliases with argument > > %FIXME", > > "passing argument %i to restrict > > -qualified" > > " parameter aliases with arguments > > %FIXME", > > param_pos + 1, > > > > &arg_positions); > > > > > > and have %FIXME (or somesuch) consume &arg_positions in the va_arg, > > printing the argument numbers there. Doing it this way also avoids > > building the string for the case where Wrestrict is disabled, since > > the > > pp_format only happens after we know we're going to print the > > warning. > > > > Assuming that there isn't yet a pre-canned way to print a set of > > argument numbers that I've missed, the place to add the %FIXME > > -handling > > would presumably be in default_tree_printer in tree-diagnostic.c - > > though it's obviously nothing to do with trees. (Or if this is too > > single-purpose, perhaps there's a need to temporarily inject one > > -time > > callbacks for consuming custom args??). > > > > We can then have a fun discussion about the usage of the Oxford > > comma :) [1] > > > > IIRC we don't yet have warning_at_rich_loc_n, but it would be > > fairly easy to add. > Hi David, > Sorry for late response. In the attached patch, I removed obstack > building on fmt, and used > pp_format for formatting arg_positions by adding specifier %I (name > chosen arbitrarily). > Does that look OK ?
Thanks - this is a big improvement. In pretty-print.c, please can you add a description of "%I" to the comment at the top of pp_format. Also, please add some selftests for %I to test_pp_format, covering, say the case of 0, 1 and 2 elements in the vec (to ensure that the separator commas are working properly). > However it results in following warning during gcc build and am not > sure how to fix this: > ../../gcc/gcc/c-family/c-common.c: In function ‘void > warn_for_restrict(unsigned int, vec<tree_node*, va_gc>*)’: > ../../gcc/gcc/c-family/c-common.c:13132:24: warning: unknown > conversion type character ‘I’ in format [-Wformat=] > Thanks, > Prathamesh > > > > [...] > > > > [1] which seems to be locale-dependent itself: > > https://en.wikipedia.org/wiki/Serial_comma#Other_languages