On Wed, 2020-03-04 at 09:22 -0700, Martin Sebor wrote:
> 
> I don't remember why the code in -Wrestrict unconditionally overwrites
> the statement location rather than only when it's not available, but
> I do remember adding conditional code like in your patch in r277076
> to deal with missing location on the statement.  So either your fix
> or something like the hunk below might be the right solution (if we
> go with the code below, abstracting it into a utility function might
> be nice).
So there's several chunks that are fairly similar to what you referenced in
maybe_warn_pointless_strcmp.  Factoring all of them into a single location is
pretty easy.

That also gives us a nice place where we can experiment with "does extraction of
location information from the expression ever help".  The answer is, it doesn't,
at least not within our testsuite when run on x86_64.

I'm hesitant to remove the code that extracts the location out of the 
expression,
but could be convinced to do so.

Thoughts?

Jeff
Fix location maybe_diag_overlap passes to diagnostics so that
diagnostic pragmas work better.

        PR tree-optimization/91890
        * gimple-ssa-warn-restrict.c (maybe_diag_overlap): Remove LOC argument.
        Use gimple_or_expr_nonartificial_location.
        (check_bounds_overlap): Drop LOC argument to maybe_diag_access_bounds.
        Use gimple_or_expr_nonartificial_location.
        * gimple.c (gimple_or_expr_nonartificial_location): New function.
        * gimple.h (gimple_or_expr_nonartificial_location): Declare it.
        * tree-ssa-strlen.c (maybe_warn_overflow): Use
        gimple_or_expr_nonartificial_location.
        (maybe_diag_stxncpy_trunc, handle_builtin_stxncpy_strncat): Likewise.
        (maybe_warn_pointless_strcmp): Likewise.

        * gcc.dg/pragma-diag-8.c: New test.
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 2c582a670eb..5e7e5d41dbb 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -1692,10 +1692,11 @@ maybe_diag_overlap (location_t loc, gimple *call, 
builtin_access &acs)
    has been issued, or would have been issued if DO_WARN had been true.  */
 
 static bool
-maybe_diag_access_bounds (location_t loc, gimple *call, tree func, int strict,
+maybe_diag_access_bounds (gimple *call, tree func, int strict,
                          const builtin_memref &ref, offset_int wroff,
                          bool do_warn)
 {
+  location_t loc = gimple_or_expr_nonartificial_location (call, ref.ptr);
   const offset_int maxobjsize = ref.maxobjsize;
 
   /* Check for excessive size first and regardless of warning options
@@ -1711,11 +1712,6 @@ maybe_diag_access_bounds (location_t loc, gimple *call, 
tree func, int strict,
 
       if (warn_stringop_overflow)
        {
-         if (EXPR_HAS_LOCATION (ref.ptr))
-           loc = EXPR_LOCATION (ref.ptr);
-
-         loc = expansion_point_location_if_in_system_header (loc);
-
          if (ref.sizrange[0] == ref.sizrange[1])
            return warning_at (loc, OPT_Wstringop_overflow_,
                               "%G%qD specified bound %wu "
@@ -1754,11 +1750,6 @@ maybe_diag_access_bounds (location_t loc, gimple *call, 
tree func, int strict,
       || (ref.ref && TREE_NO_WARNING (ref.ref)))
     return false;
 
-  if (EXPR_HAS_LOCATION (ref.ptr))
-    loc = EXPR_LOCATION (ref.ptr);
-
-  loc = expansion_point_location_if_in_system_header (loc);
-
   char rangestr[2][64];
   if (ooboff[0] == ooboff[1]
       || (ooboff[0] != ref.offrange[0]
@@ -2018,9 +2009,6 @@ check_bounds_or_overlap (gimple *call, tree dst, tree 
src, tree dstsize,
                         tree srcsize, bool bounds_only /* = false */,
                         bool do_warn /* = true */)
 {
-  location_t loc = gimple_nonartificial_location (call);
-  loc = expansion_point_location_if_in_system_header (loc);
-
   tree func = gimple_call_fndecl (call);
 
   builtin_memref dstref (dst, dstsize);
@@ -2041,8 +2029,8 @@ check_bounds_or_overlap (gimple *call, tree dst, tree 
src, tree dstsize,
   /* Validate offsets to each reference before the access first to make
      sure they are within the bounds of the destination object if its
      size is known, or PTRDIFF_MAX otherwise.  */
-  if (maybe_diag_access_bounds (loc, call, func, strict, dstref, wroff, 
do_warn)
-      || maybe_diag_access_bounds (loc, call, func, strict, srcref, 0, 
do_warn))
+  if (maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn)
+      || maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn))
     {
       if (do_warn)
        gimple_set_no_warning (call, true);
@@ -2066,6 +2054,7 @@ check_bounds_or_overlap (gimple *call, tree dst, tree 
src, tree dstsize,
        }
     }
 
+  location_t loc = gimple_or_expr_nonartificial_location (call, dst);
   if (operand_equal_p (dst, src, 0))
     {
       /* Issue -Wrestrict unless the pointers are null (those do
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 324e706d508..92c6e642589 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3285,6 +3285,19 @@ gimple_inexpensive_call_p (gcall *stmt)
   return false;
 }
 
+/* Return a non-artificial location for STMT.  If STMT does not have
+   location information, get the location from EXPR.  */
+
+location_t
+gimple_or_expr_nonartificial_location (gimple *stmt, tree)
+{
+  location_t loc = gimple_nonartificial_location (stmt);
+  if (loc == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (expr))
+    loc = tree_nonartificial_location (expr);
+  return expansion_point_location_if_in_system_header (loc);
+}
+
+
 #if CHECKING_P
 
 namespace selftest {
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 192f19ad23a..0420d6d2251 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1633,6 +1633,8 @@ extern void gimple_seq_discard (gimple_seq);
 extern void maybe_remove_unused_call_args (struct function *, gimple *);
 extern bool gimple_inexpensive_call_p (gcall *);
 extern bool stmt_can_terminate_bb_p (gimple *);
+extern location_t gimple_or_expr_nonartificial_location (gimple *, tree);
+
 
 /* Formal (expression) temporary table handling: multiple occurrences of
    the same scalar expression are evaluated into the same temporary.  */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index b76b54efbd8..7cc576b333e 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2106,11 +2106,7 @@ maybe_warn_overflow (gimple *stmt, tree len,
          || !si || !is_strlen_related_p (si->ptr, len)))
     return;
 
-  location_t loc = gimple_nonartificial_location (stmt);
-  if (loc == UNKNOWN_LOCATION && dest && EXPR_HAS_LOCATION (dest))
-    loc = tree_nonartificial_location (dest);
-  loc = expansion_point_location_if_in_system_header (loc);
-
+  location_t loc = gimple_or_expr_nonartificial_location (stmt, dest);
   bool warned = false;
   if (wi::leu_p (lenrng[0], spcrng[1]))
     {
@@ -3159,9 +3155,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree 
src, tree cnt)
        }
     }
 
-  location_t callloc = gimple_nonartificial_location (stmt);
-  callloc = expansion_point_location_if_in_system_header (callloc);
-
+  location_t callloc = gimple_or_expr_nonartificial_location (stmt, dst);
   tree func = gimple_call_fndecl (stmt);
 
   if (lenrange[0] != 0 || !wi::neg_p (lenrange[1]))
@@ -3373,8 +3367,7 @@ handle_builtin_stxncpy_strncat (bool append_p, 
gimple_stmt_iterator *gsi)
      to strlen(S)).  */
   strinfo *silen = get_strinfo (pss->first);
 
-  location_t callloc = gimple_nonartificial_location (stmt);
-  callloc = expansion_point_location_if_in_system_header (callloc);
+  location_t callloc = gimple_or_expr_nonartificial_location (stmt, dst);
 
   tree func = gimple_call_fndecl (stmt);
 
@@ -4301,10 +4294,7 @@ maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT 
bound,
 
   /* FIXME: Include a note pointing to the declaration of the smaller
      array.  */
-  location_t stmt_loc = gimple_nonartificial_location (stmt);
-  if (stmt_loc == UNKNOWN_LOCATION && EXPR_HAS_LOCATION (lhs))
-    stmt_loc = tree_nonartificial_location (lhs);
-  stmt_loc = expansion_point_location_if_in_system_header (stmt_loc);
+  location_t stmt_loc = gimple_or_expr_nonartificial_location (stmt, lhs);
 
   tree callee = gimple_call_fndecl (stmt);
   bool warned = false;
diff --git a/gcc/testsuite/gcc.dg/pragma-diag-8.c 
b/gcc/testsuite/gcc.dg/pragma-diag-8.c
new file mode 100644
index 00000000000..00780606e9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pragma-diag-8.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+
+char one[50];
+char two[50];
+
+void
+test_strncat (void)
+{
+  (void) __builtin_strcpy (one, "gh");
+  (void) __builtin_strcpy (two, "ef");
+ 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstringop-overflow="
+#pragma GCC diagnostic ignored "-Warray-bounds"
+  (void) __builtin_strncat (one, two, 99); 
+#pragma GCC diagnostic pop
+}
+

Reply via email to