Re: [PATCH] PR86957

2018-09-15 Thread Indu Bhagat

Thanks for the reviews. I have incorporated all but one (See below; its the 
change in the warning's
brief summary in common.opt) in the patch.

In this patch,

1. -Wmissing-profile is a warning by default and is ON by default with
   -fprofile-use
2. Attached pr86957-missing-profile-diagnostic-2 shows the warning messages
3. Added a testcase for warning in the case of missing profile feedback data
   file for a compilation unit

Thanks

gcc/ChangeLog:

2018-09-14  "Indu Bhagat"

* common.opt: New warning option -Wmissing-profile.
* coverage.c (get_coverage_counts): Add warning for missing .gcda file.
* doc/invoke.texi: Document -Wmissing-profile.

gcc/testsuite/ChangeLog:

2018-09-14  "Indu Bhagat"

* gcc.dg/Wmissing-profile.c: New test.


On 09/11/2018 02:21 AM, Martin Liška wrote:

diff --git a/gcc/common.opt b/gcc/common.opt
index ebc3ef4..d93ddca 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -811,6 +811,10 @@ Wcoverage-mismatch
  Common Var(warn_coverage_mismatch) Init(1) Warning
  Warn in case profiles in -fprofile-use do not match.
  
+Wmissing-profile

+Common Var(warn_missing_profile) Init(1) Warning
+Warn in case profiles in -fprofile-use do not exist.

Maybe 'Want about missing profile for a function in -fprofile-use build.' ?



Since, Wmissing-profile also warns when feedback data file is missing for a 
compilation unit, the
suggested text above will be more restrictive. So I did not change.

[Testcase 1] Missing profile data file with -fprofile-use. The sort.c file 
contains two functions main() and stop()

gcc -c sort.c -fprofile-use -O1 
-fprofile-dir=/scratch/user/gcc-temp/fdo/profdata/
sort.c: In function ‘main’:
sort.c:29:1: warning: 
‘/scratch/user/gcc-temp/fdo/profdata//#scratch#user#gcc-temp#fdo#sort.gcda’ 
profile count data file not found [-Wmissing-profile]
29 | }
   | ^


[Testcase 2] bubble_sort.c has a non-empty function bubble_sort() for which 
profile data exists.
Now at profile-use phase, a user adds empty function before1() before an 
existing lone function bubble_sort() and empty function after1() after the lone 
existing function bubble_sort()

gcc -c bubble_sort.c -fprofile-use -O1 
-fprofile-dir=/scratch/user/gcc-temp/fdo/profdata/
bubble_sort.c:20:6: warning: profile for function ‘after1’ not found in profile 
data [-Wmissing-profile]
20 | void after1() { }
   |  ^~
bubble_sort.c: In function ‘bubble_sort’:
bubble_sort.c:20:1: error: source locations for function ‘bubble_sort’ have 
changed, the profile data may be out of date [-Werror=coverage-mismatch]
20 | void after1() { }
   | ^~~~
bubble_sort.c: In function ‘before1’:
bubble_sort.c:3:6: warning: profile for function ‘before1’ not found in profile 
data [-Wmissing-profile]
3 | void before1() { }
  |  ^~~
cc1: some warnings being treated as errors
make: *** [bubble_sort.o] Error 1


[Testcase 3] Use -Wno-missing-profile to disable warnings (A coverage-mismatch 
error remains here because of source file changes as mentioned in Testcase 2 
above; but no warnings are issued for before1() and after1())

gcc -c bubble_sort.c -fprofile-use -O1 -Wno-missing-profile 
-fprofile-dir=/scratch/user/gcc-temp/fdo/profdata/
bubble_sort.c: In function ‘bubble_sort’:
bubble_sort.c:20:1: error: source locations for function ‘bubble_sort’ have 
changed, the profile data may be out of date [-Werror=coverage-mismatch]
20 | void after1() { }
   | ^~~~
cc1: some warnings being treated as errors

diff --git a/gcc/common.opt b/gcc/common.opt
index ef6a630..53aac19 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -811,6 +811,10 @@ Wcoverage-mismatch
 Common Var(warn_coverage_mismatch) Init(1) Warning
 Warn in case profiles in -fprofile-use do not match.
 
+Wmissing-profile
+Common Var(warn_missing_profile) Init(1) Warning
+Warn in case profiles in -fprofile-use do not exist.
+
 Wvector-operation-performance
 Common Var(warn_vector_operation_performance) Warning
 Warn when a vector operation is compiled outside the SIMD.
diff --git a/gcc/coverage.c b/gcc/coverage.c
index bae6f5c..f9b54d8 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -341,16 +341,23 @@ get_coverage_counts (unsigned counter, unsigned expected,
 {
   static int warned = 0;
 
-  if (!warned++ && dump_enabled_p ())
+  if (!warned++)
 	{
-	  dump_user_location_t loc
-	= dump_user_location_t::from_location_t (input_location);
-	  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+	  warning (OPT_Wmissing_profile,
+		   "%qs profile count data file not found",
+		   da_file_name);
+	  if (dump_enabled_p ())
+	{
+	  dump_user_location_t loc
+		= dump_user_location_t::from_location_t (input_location);
+	  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+			   "file %s not found\n",
+			   da_file_name);
+	  dump_printf (MSG_OPTIMIZED_LOCATIONS,
 			   (flag_guess_branch_prob
-			? "file %s not found, execution counts estimated\n"
-			: "file %s not found, execution counts ass

[doc] doc/service.texi: Switch the fsf.org link to https.

2018-09-15 Thread Gerald Pfeifer
Committed.

Gerald

2018-09-16  Gerald Pfeifer  

* doc/service.texi (Service): Switch the fsf.org link to https.

Index: doc/service.texi
===
--- doc/service.texi(revision 264342)
+++ doc/service.texi(working copy)
@@ -20,7 +20,7 @@
 @item
 Look in the service directory for someone who might help you for a fee.
 The service directory is found at
-@uref{http://www.fsf.org/resources/service}.
+@uref{https://www.fsf.org/resources/service}.
 @end itemize
 
 For further information, see


[wwwdocs] remove last use of cellspacing="0"

2018-09-15 Thread Gerald Pfeifer
We had this left on the main page.  I makes a slight visual difference,
but not signficant, and I plan on replacing the formatting via a table
mid term.

Applied.

Gerald

Index: style.mhtml
===
RCS file: /cvs/gcc/wwwdocs/htdocs/style.mhtml,v
retrieving revision 1.155
diff -u -r1.155 style.mhtml
--- style.mhtml 9 Sep 2018 21:18:17 -   1.155
+++ style.mhtml 15 Sep 2018 23:01:47 -
@@ -70,7 +70,7 @@
 
 
  
+  
   
 
   


[wwwdocs] gcc-3.1/gcj-status.html -- move to full HTML

2018-09-15 Thread Gerald Pfeifer
Similar to what I did with gcc-3.3/gcj-status.html a few days ago.

Committed.

Gerald

Index: gcc-3.1/gcj-status.html
===
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.1/gcj-status.html,v
retrieving revision 1.6
diff -u -r1.6 gcj-status.html
--- gcc-3.1/gcj-status.html 2 Sep 2018 19:16:10 -   1.6
+++ gcc-3.1/gcj-status.html 15 Sep 2018 22:55:42 -
@@ -17,7 +17,7 @@
 
  Platforms 
 
-
+
 
  Platform   Status   Who  
 
@@ -108,7 +108,7 @@
 
  Packages 
 
-
+
 
  Package   Status   Who  
 


Re: [PATCH, rs6000, committed] Use correct ABI type in mmintrin.h and xmmintrin.h

2018-09-15 Thread Segher Boessenkool
On Sat, Sep 15, 2018 at 03:28:17PM -0500, Bill Schmidt wrote:
> Jinsong Ji reported that these header files are using the non-ABI type
> __int128_t rather than __int128.  This patch from Jinsong corrects this.
> Bootstrapped and tested on powerpc64le-linux-gnu with no regressions,
> committed as obvious.

Thanks to both of you!

Does it actually matter for something, other than being cleaner?


Segher


[PATCH, rs6000, committed] Use correct ABI type in mmintrin.h and xmmintrin.h

2018-09-15 Thread Bill Schmidt
Hi,

Jinsong Ji reported that these header files are using the non-ABI type
__int128_t rather than __int128.  This patch from Jinsong corrects this.
Bootstrapped and tested on powerpc64le-linux-gnu with no regressions,
committed as obvious.

Thanks,
Bill


2018-09-15  Jinsong Ji  
Bill Schmidt  

* config/rs6000/mmintrin.h (_mm_unpackhi_pi8): Change __int128_t
to __int128.
(_mm_unpacklo_pi8): Likewise.
(_mm_add_pi8): Likewise.
(_mm_add_pi16): Likewise.
(_mm_add_pi32): Likewise.
(_mm_sub_pi8): Likewise.
(_mm_sub_pi16): Likewise.
(_mm_sub_pi32): Likewise.
(_mm_cmpgt_pi8): Likewise.
(_mm_cmpeq_pi16): Likewise.
(_mm_cmpgt_pi16): Likewise.
(_mm_cmpeq_pi32): Likewise.
(_mm_cmpgt_pi32): Likewise.
(_mm_adds_pi8): Likewise.
(_mm_adds_pi16): Likewise.
(_mm_adds_pu8): Likewise.
(_mm_adds_pu16): Likewise.
(_mm_subs_pi8): Likewise.
(_mm_subs_pi16): Likewise.
(_mm_subs_pu8): Likewise.
(_mm_subs_pu16): Likewise.
(_mm_madd_pi16): Likewise.
(_mm_mulhi_pi16): Likewise.
(_mm_mullo_pi16): Likewise.
(_mm_sll_pi16): Likewise.
(_mm_sra_pi16): Likewise.
(_mm_srl_pi16): Likewise.
(_mm_set1_pi16): Likewise.
(_mm_set1_pi8): Likewise.
* config/rs6000/xmmintrin.h (_mm_max_pi16): Likewise.
(_mm_max_pu8): Likewise.
(_mm_min_pi16): Likewise.
(_mm_min_pu8): Likewise.


Index: gcc/config/rs6000/mmintrin.h
===
--- gcc/config/rs6000/mmintrin.h(revision 264342)
+++ gcc/config/rs6000/mmintrin.h(working copy)
@@ -236,7 +236,7 @@ _mm_unpackhi_pi8 (__m64 __m1, __m64 __m2)
   a = (__vector unsigned char)vec_splats (__m1);
   b = (__vector unsigned char)vec_splats (__m2);
   c = vec_mergel (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -317,7 +317,7 @@ _mm_unpacklo_pi8 (__m64 __m1, __m64 __m2)
   a = (__vector unsigned char)vec_splats (__m1);
   b = (__vector unsigned char)vec_splats (__m2);
   c = vec_mergel (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 1));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 1));
 #else
   __m64_union m1, m2, res;
 
@@ -398,7 +398,7 @@ _mm_add_pi8 (__m64 __m1, __m64 __m2)
   a = (__vector signed char)vec_splats (__m1);
   b = (__vector signed char)vec_splats (__m2);
   c = vec_add (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -434,7 +434,7 @@ _mm_add_pi16 (__m64 __m1, __m64 __m2)
   a = (__vector signed short)vec_splats (__m1);
   b = (__vector signed short)vec_splats (__m2);
   c = vec_add (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -466,7 +466,7 @@ _mm_add_pi32 (__m64 __m1, __m64 __m2)
   a = (__vector signed int)vec_splats (__m1);
   b = (__vector signed int)vec_splats (__m2);
   c = vec_add (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -496,7 +496,7 @@ _mm_sub_pi8 (__m64 __m1, __m64 __m2)
   a = (__vector signed char)vec_splats (__m1);
   b = (__vector signed char)vec_splats (__m2);
   c = vec_sub (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -532,7 +532,7 @@ _mm_sub_pi16 (__m64 __m1, __m64 __m2)
   a = (__vector signed short)vec_splats (__m1);
   b = (__vector signed short)vec_splats (__m2);
   c = vec_sub (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -564,7 +564,7 @@ _mm_sub_pi32 (__m64 __m1, __m64 __m2)
   a = (__vector signed int)vec_splats (__m1);
   b = (__vector signed int)vec_splats (__m2);
   c = vec_sub (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2, res;
 
@@ -754,7 +754,7 @@ _mm_cmpgt_pi8 (__m64 __m1, __m64 __m2)
   a = (__vector signed char)vec_splats (__m1);
   b = (__vector signed char)vec_splats (__m2);
   c = (__vector signed char)vec_cmpgt (a, b);
-  return (__builtin_unpack_vector_int128 ((__vector __int128_t)c, 0));
+  return (__builtin_unpack_vector_int128 ((__vector __int128)c, 0));
 #else
   __m64_union m1, m2,

Re: bootstrap -O3 failure libgo on x64_86

2018-09-15 Thread Ian Lance Taylor via gcc-patches
On Sat, Sep 15, 2018 at 7:12 AM, graham stott via gcc-patches
 wrote:
> Hi
> Fails due to undefind symbols runtime.*
> O2 works

I tried my best guess at recreating the problem, and everything worked fine.

Please tell us exactly what you did and exactly what happened.

Thanks.

Ian


bootstrap -O3 failure libgo on x64_86

2018-09-15 Thread graham stott via gcc-patches
Hi
Fails due to undefind symbols runtime.*
O2 works

vector _M_start and 0 offset

2018-09-15 Thread Marc Glisse

Hello,

as explained in the PR, the implementation of vector is weirdly 
wasteful. Preserving the ABI prevents from changing much for now, but this 
small tweak can help the compiler remove quite a bit of dead code.


I think most other direct uses of _M_start are in constructors where the 
offset has just been initialized to 0, so the compiler should already know 
enough there, but I may have missed a few relevant places where the same 
idea could be used.


I used C++11 syntax because I find it nicer, and the compiler accepts it 
in C++98 mode with just a warning, suppressed in a standard header.


Bootstrap+regtest on powerpc64le-unknown-linux-gnu.

2018-09-15  Marc Glisse  

PR libstdc++/87258
* include/bits/stl_bvector.h (vector::begin(), vector::cbegin()):
Rebuild _M_start with an explicit 0 offset.

--
Marc GlisseIndex: include/bits/stl_bvector.h
===
--- include/bits/stl_bvector.h	(revision 264178)
+++ include/bits/stl_bvector.h	(working copy)
@@ -802,25 +802,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
 
 #if __cplusplus >= 201103L
   void
   assign(initializer_list __l)
   { _M_assign_aux(__l.begin(), __l.end(), random_access_iterator_tag()); }
 #endif
 
   iterator
   begin() _GLIBCXX_NOEXCEPT
-  { return this->_M_impl._M_start; }
+  { return { this->_M_impl._M_start._M_p, 0 }; }
 
   const_iterator
   begin() const _GLIBCXX_NOEXCEPT
-  { return this->_M_impl._M_start; }
+  { return { this->_M_impl._M_start._M_p, 0 }; }
 
   iterator
   end() _GLIBCXX_NOEXCEPT
   { return this->_M_impl._M_finish; }
 
   const_iterator
   end() const _GLIBCXX_NOEXCEPT
   { return this->_M_impl._M_finish; }
 
   reverse_iterator
@@ -835,21 +835,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   rend() _GLIBCXX_NOEXCEPT
   { return reverse_iterator(begin()); }
 
   const_reverse_iterator
   rend() const _GLIBCXX_NOEXCEPT
   { return const_reverse_iterator(begin()); }
 
 #if __cplusplus >= 201103L
   const_iterator
   cbegin() const noexcept
-  { return this->_M_impl._M_start; }
+  { return { this->_M_impl._M_start._M_p, 0 }; }
 
   const_iterator
   cend() const noexcept
   { return this->_M_impl._M_finish; }
 
   const_reverse_iterator
   crbegin() const noexcept
   { return const_reverse_iterator(end()); }
 
   const_reverse_iterator


Fix PR middle-end/86864

2018-09-15 Thread Eric Botcazou
This is a regression present on the mainline: an assertion is triggered in 
commit_one_edge_insertion at expansion time because a BB contains a BARRIER in 
its BB_END, which is not valid.  expand_gimple_basic_block is supposed to 
prevent that from happening, but it doesn't properly handle the sequence:

  JUMP
  BARRIER
  JUMP_TABLE_DATA
  BARRIER

that can be generated for a switch construct.

Bootstrapped/regtested on x86_64-suse-linux, applied on mainline as obvious.


2018-09-15  Eric Botcazou  

PR middle-end/86864
* cfgexpand.c (expand_gimple_basic_block): Be prepared for a BARRIER
before and after a JUMP_TABLE_DATA.


2018-09-15  Eric Botcazou  

* gcc.c-torture/compile/20180915-1.c: New test.

-- 
Eric BotcazouIndex: cfgexpand.c
===
--- cfgexpand.c	(revision 264202)
+++ cfgexpand.c	(working copy)
@@ -5810,6 +5810,8 @@ expand_gimple_basic_block (basic_block b
 last = PREV_INSN (last);
   if (JUMP_TABLE_DATA_P (last))
 last = PREV_INSN (PREV_INSN (last));
+  if (BARRIER_P (last))
+last = PREV_INSN (last);
   BB_END (bb) = last;
 
   update_bb_for_insn (bb);
/* PR middle-end/86864 */
/* Testcase by Serge Belyshev  */

long a;
void f ();
void g (int b, int c, int d)
{
  switch (b)
{
case 42:
case 29:
case 48:
case 40:
case 32:
  c = 2;
  break;
case 0:
  c = 1;
  break;
default:
  __builtin_unreachable ();
}
  if (d || a)
f ();
  if (c == 1)
f ();
}


Re: [PATCH] Make strlen range computations more conservative

2018-09-15 Thread Bernd Edlinger
Hi,

this is an update on my strlen range patch (V7).  Again re-based and
retested to current trunk.

I am aware that Martin wants to re-factor the interface of get_range_strlen
and have no objections against, but I'd suggest that to be a follow-up patch.

I might suggest to rename one of the two get_range_strlen functions at the
same time as it is rather confusing to have to count the parameters in order
to tell which function is meant.

Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.
gcc:
2018-08-26  Bernd Edlinger  

* gimple-fold.c (looks_like_a_char_array_without_typecast_p): New
helper function for strlen range estimations.
(get_range_strlen): Use looks_like_a_char_array_without_typecast_p
for warnings, but use GIMPLE semantics otherwise.
* tree-ssa-strlen.c (maybe_set_strlen_range): Use GIMPLE semantics.
(get_min_string_length): Avoid not NUL terminated string literals.

testsuite:
2018-08-26  Bernd Edlinger  

* c-c++-common/attr-nonstring-3.c: Remove xfail.
* gcc.dg/pr83373.c: Add xfail.
* gcc.dg/strlenopt-36.c: Add xfail.
* gcc.dg/strlenopt-40.c: Adjust test expectations.
* gcc.dg/strlenopt-45.c: Adjust test expectations.
* gcc.dg/strlenopt-48.c: Add xfail.
* gcc.dg/strlenopt-51.c: Adjust test expectations.
* gcc.dg/strlenopt-59.c: New test.
* gcc.dg/strlenopt-60.c: New test.

diff -Npur gcc/gimple-fold.c gcc/gimple-fold.c
--- gcc/gimple-fold.c	2018-09-14 21:52:32.0 +0200
+++ gcc/gimple-fold.c	2018-09-14 22:46:11.764019221 +0200
@@ -1261,6 +1261,40 @@ gimple_fold_builtin_memset (gimple_stmt_
   return true;
 }
 
+/* Determine if a char array is suitable for strlen range estimations.
+   Return false if ARG is not a char array, or if the inner reference
+   chain appears to go through a type cast, otherwise return true.
+   Note that the gimple type informations are not 100% guaranteed
+   to be accurate, therefore this function shall only be used for
+   warnings.  */
+
+static bool
+looks_like_a_char_array_without_typecast_p (tree arg)
+{
+  /* We handle arrays of integer types.  */
+  if (TREE_CODE (TREE_TYPE (arg)) != ARRAY_TYPE
+  || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != INTEGER_TYPE
+  || TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))) != TYPE_MODE (char_type_node)
+  || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg)))
+	 != TYPE_PRECISION (char_type_node))
+return false;
+
+  tree base = arg;
+  while (TREE_CODE (base) == ARRAY_REF
+	 || TREE_CODE (base) == ARRAY_RANGE_REF
+	 || TREE_CODE (base) == COMPONENT_REF)
+base = TREE_OPERAND (base, 0);
+
+  /* If this looks like a type cast don't assume anything.  */
+  if ((TREE_CODE (base) == MEM_REF
+   && (! integer_zerop (TREE_OPERAND (base, 1))
+	   || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (base, 0
+	  != TYPE_MAIN_VARIANT (TREE_TYPE (base
+  || handled_component_p (base))
+return false;
+
+  return true;
+}
 
 /* Obtain the minimum and maximum string length or minimum and maximum
value of ARG in LENGTH[0] and LENGTH[1], respectively.
@@ -1276,6 +1310,7 @@ gimple_fold_builtin_memset (gimple_stmt_
PHIs and COND_EXPRs optimistically, if we can determine string length
minimum and maximum, it will use the minimum from the ones where it
can be determined.
+   TYPE == 2 and FUZZY != 0 cannot be used together.
Set *FLEXP to true if the range of the string lengths has been
obtained from the upper bound of an array at the end of a struct.
Such an array may hold a string that's longer than its upper bound
@@ -1318,8 +1353,8 @@ get_range_strlen (tree arg, tree length[
 		 member.  */
 	  tree idx = TREE_OPERAND (op, 1);
 
-	  arg = TREE_OPERAND (op, 0);
-	  tree optype = TREE_TYPE (arg);
+	  op = TREE_OPERAND (op, 0);
+	  tree optype = TREE_TYPE (op);
 	  if (tree dom = TYPE_DOMAIN (optype))
 		if (tree bound = TYPE_MAX_VALUE (dom))
 		  if (TREE_CODE (bound) == INTEGER_CST
@@ -1346,23 +1381,21 @@ get_range_strlen (tree arg, tree length[
  visited, type, fuzzy, flexp,
  eltsize, nonstr);
 
+	  if (eltsize != 1 || fuzzy != 2)
+	return false;
+
 	  if (TREE_CODE (arg) == ARRAY_REF)
 	{
-	  tree type = TREE_TYPE (TREE_OPERAND (arg, 0));
-
-	  /* Determine the "innermost" array type.  */
-	  while (TREE_CODE (type) == ARRAY_TYPE
-		 && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
-		type = TREE_TYPE (type);
-
-	  /* Avoid arrays of pointers.  */
-	  tree eltype = TREE_TYPE (type);
-	  if (TREE_CODE (type) != ARRAY_TYPE
-		  || !INTEGRAL_TYPE_P (eltype))
+	  if (!looks_like_a_char_array_without_typecast_p (arg))
 		return false;
 
+	  tree type = TREE_TYPE (arg);
+
+	  /* Fail when the array bound is unknown or zero.  */
 	  val = TYPE_SIZE_UNIT (type);
-	  if (!val || integer_zerop (val))
+	  if (!val
+		  || TREE_C

Re: [PATCH] look harder for MEM_REF operand equality to avoid -Wstringop-truncation (PR 84561)

2018-09-15 Thread Bernd Edlinger
On 9/14/18, Martin Sebor wrote:
> As I said above, this happens during the dom walk in the ccp
> pass:
> 
>   substitute_and_fold_dom_walker walker (CDI_DOMINATORS, this);
>   walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
> 
> The warning is issued during the walker.walk() call as
> strncpy is being folded into memcpy.  The prior assignments are
> only propagated later, when the next statement after the strncpy
> call is reached.  It happens in
> substitute_and_fold_dom_walker::before_dom_children(). So during
> the strncpy folding we see the next statement as:
> 
>   MEM[(struct S *)_1].a[n_7] = 0;
> 
> After the strncpy call is transformed to memcpy, the assignment
> above is transformed to
> 
>   MEM[(struct S *)_8].a[3] = 0;
> 
> 
>> If they're only discovered as copies within the pass where you're trying
>> to issue the diagnostic, then you'd want to see if the pass has any
>> internal structures that tell you about equivalences.
> 
> 
> I don't know if this is possible.  I don't see any APIs in
> tree-ssa-propagate.h that would let me query the internal data
> somehow to find out during folding (when the warning is issued).


Well,

if I see this right, the CCP is doing tree transformations
while from the folding of strncpy the predicate maybe_diag_stxncpy_trunc
is called, and sees inconsistent information, in the tree,
and therefore it issues a warning.

I understand that walking the references is fragile at least
in this state.

But why not just prevent warnings when this is called from CCP?


Like this?

Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.
gcc:
2018-09-15  Bernd Edlinger  

	PR tree-optimization/84561
	* tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Bail out if called
	from CCP.

testsuite:
2018-09-15  Martin Sebor  

	PR tree-optimization/84561
	* gcc.dg/Wstringop-truncation-6.c: New test.

diff -Npur gcc/tree-ssa-strlen.c gcc/tree-ssa-strlen.c
--- gcc/tree-ssa-strlen.c	2018-09-14 13:12:10.0 +0200
+++ gcc/tree-ssa-strlen.c	2018-09-15 08:04:57.011142267 +0200
@@ -1846,11 +1846,13 @@ is_strlen_related_p (tree src, tree len)
 bool
 maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
 {
+  wide_int cntrange[2];
   gimple *stmt = gsi_stmt (gsi);
   if (gimple_no_warning_p (stmt))
 return false;
 
-  wide_int cntrange[2];
+  if (current_pass && !strcmp (current_pass->name, "ccp"))
+return false;
 
   if (TREE_CODE (cnt) == INTEGER_CST)
 cntrange[0] = cntrange[1] = wi::to_wide (cnt);
diff -Npur gcc/testsuite/gcc.dg/Wstringop-truncation-6.c gcc/testsuite/gcc.dg/Wstringop-truncation-6.c
--- gcc/testsuite/gcc.dg/Wstringop-truncation-6.c	1970-01-01 01:00:00.0 +0100
+++ gcc/testsuite/gcc.dg/Wstringop-truncation-6.c	2018-09-15 08:02:35.597198845 +0200
@@ -0,0 +1,59 @@
+/* PR tree-optimization/84561 - -Wstringop-truncation with -O2 depends
+   on strncpy's size type
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+enum { N = 3 };
+
+struct S
+{
+  char a[N + 1];
+};
+
+void set (struct S *ps, const char* s, size_t n)
+{
+  if (n > N)
+n = N;
+
+  __builtin_strncpy (ps->a, s, n);   /* { dg-bogus "\\\[-Wstringop-truncation]" } */
+  ps->a[n] = 0;
+}
+
+struct A
+{
+  struct S str;
+};
+
+void setStringSize_t (struct A *pa, const char *s, size_t n)
+{
+  set (&pa->str, s, n);
+}
+
+void setStringUnsignedInt (struct A *pa, const char* s, unsigned int n)
+{
+  set (&pa->str, s, n);
+}
+
+struct B
+{
+  struct A a;
+};
+
+struct A* getA (struct B *pb)
+{
+  return &pb->a;
+}
+
+void f (struct A *pa)
+{
+  setStringUnsignedInt (pa, "123", N); // No warning here.
+  setStringSize_t (pa, "123", N);  // No warning here.
+}
+
+void g (struct B *pb)
+{
+  setStringUnsignedInt (getA (pb), "123", N);  // Unexpected warning here.
+  setStringSize_t (getA (pb), "123", N);   // No warning here.
+}