@@ -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);