[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-24 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Martin Sebor  changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

--- Comment #30 from Martin Sebor  ---
Fixed in r262958.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-24 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #29 from Martin Sebor  ---
Author: msebor
Date: Wed Jul 25 02:11:31 2018
New Revision: 262958

URL: https://gcc.gnu.org/viewcvs?rev=262958=gcc=rev
Log:
PR tree-optimization/86622 - incorrect strlen of array of array plus variable
offset
PR tree-optimization/86532 - Wrong code due to a wrong strlen folding starting
with r262522

gcc/ChangeLog:

PR tree-optimization/86622
PR tree-optimization/86532
* builtins.h (string_length): Declare.
* builtins.c (c_strlen): Correct handling of non-constant offsets.  
(check_access): Be prepared for non-constant length ranges.
(string_length): Make extern.
* expr.c (string_constant): Only handle the minor non-constant
array index.  Use string_constant to compute the length of
a generic string constant.

gcc/testsuite/ChangeLog:

PR tree-optimization/86622
PR tree-optimization/86532
* gcc.c-torture/execute/strlen-2.c: New test.
* gcc.c-torture/execute/strlen-3.c: New test.
* gcc.c-torture/execute/strlen-4.c: New test.


Added:
trunk/gcc/testsuite/gcc.c-torture/execute/strlen-2.c
trunk/gcc/testsuite/gcc.c-torture/execute/strlen-3.c
trunk/gcc/testsuite/gcc.c-torture/execute/strlen-4.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/builtins.c
trunk/gcc/builtins.h
trunk/gcc/expr.c
trunk/gcc/testsuite/ChangeLog

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-18 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #28 from Bernd Edlinger  ---
Yes, agreed.

Should I send a patch to take out the statement in comment #17,
or will you do that in your follow-up patch?

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-18 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #27 from Martin Sebor  ---
I don't think it would be appropriate to introduce dependencies on the
sanitizer for the same reason we can't do that for warnings.  But as I
mentioned in comment 16, I think performing these sorts of simplifications this
early (this one it happens during parsing) prevents subsequent analysis from
making use of the information that can be derived from in the original code. 
Deferring this non-constant folding until later (see bug 86434) would make it
possible not only to detect some of these bugs but also transform them into
traps/unreachable without any runtime overhead (when we know the non-constant
offset's range is out-of-bounds).

I did the comparison in signed because that's what the function returns but I
do agree that folding to zero rather than arbitrary value.  I opened bug 86572
for this idea.  Let me propose making the change separately (here I just want
to fix the wrong code without preventing  existing optimizations).  I would
also be open to emitting __builtin_unreachable().

The chartype loop needs to change to avoid assuming the element type is
necessarily an integer type.  I can reproduce the problem on my local machine
but I don't know why the full regression test run that I run on my team's
server didn't expose this or the previous ICE.  I'll look into it.

I very much appreciate your testing and feedback.  I would just ask you to
comment on the patch on the list so we don't clutter with details that are not
important to the record of the bug.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-18 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #26 from Bernd Edlinger  ---
../../gcc-9-20180715-1/gcc/expr.c:11360 is:

  while (TREE_CODE (chartype) != INTEGER_TYPE)
chartype = TREE_TYPE (chartype);

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-18 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #25 from Bernd Edlinger  ---
Sorry again Martin,

but with the latest patch I see the following:


FAIL: gcc.target/i386/avx-vdppd-2.c (internal compiler error)
FAIL: gcc.target/i386/avx-vdppd-2.c (test for excess errors)
FAIL: gcc.target/i386/avx-vdpps-2.c (internal compiler error)
FAIL: gcc.target/i386/avx-vdpps-2.c (test for excess errors)
FAIL: gcc.target/i386/avx-vinsertps-1.c (internal compiler error)
FAIL: gcc.target/i386/avx-vinsertps-1.c (test for excess errors)
FAIL: gcc.target/i386/avx-vinsertps-4.c (internal compiler error)
FAIL: gcc.target/i386/avx-vinsertps-4.c (test for excess errors)
FAIL: gcc.target/i386/sse4_1-dppd-2.c (internal compiler error)
FAIL: gcc.target/i386/sse4_1-dppd-2.c (test for excess errors)
FAIL: gcc.target/i386/sse4_1-dpps-2.c (internal compiler error)
FAIL: gcc.target/i386/sse4_1-dpps-2.c (test for excess errors)
FAIL: gcc.target/i386/sse4_1-insertps-1.c (internal compiler error)
FAIL: gcc.target/i386/sse4_1-insertps-1.c (test for excess errors)
FAIL: gcc.target/i386/sse4_1-insertps-4.c (internal compiler error)
FAIL: gcc.target/i386/sse4_1-insertps-4.c (test for excess errors)

/home/ed/gnu/gcc-9-20180715-1/gcc/testsuite/gcc.target/i386/sse4_1-dppd-2.c: In
function 'avx_test':^M
/home/ed/gnu/gcc-9-20180715-1/gcc/testsuite/gcc.target/i386/sse4_1-dppd-2.c:70:7:
internal compiler error: Segmentation fault^M
0xcd1b6f crash_signal^M
../../gcc-9-20180715-1/gcc/toplev.c:324^M
0x9ccabd string_constant(tree_node*, tree_node**)^M
../../gcc-9-20180715-1/gcc/expr.c:11360^M
0x9f9219 c_getstr(tree_node*, unsigned long*, unsigned long*)^M
../../gcc-9-20180715-1/gcc/fold-const.c:14591^M
0xa2439e fold_const_call(combined_fn, tree_node*, tree_node*, tree_node*,
tree_node*)^M
../../gcc-9-20180715-1/gcc/fold-const-call.c:1712^M
0x8a6431 fold_builtin_3^M
../../gcc-9-20180715-1/gcc/builtins.c:9355^M
0x8a6431 fold_builtin_n(unsigned int, tree_node*, tree_node**, int, bool)^M
../../gcc-9-20180715-1/gcc/builtins.c:9432^M
0xa1f2b1 fold(tree_node*)^M
../../gcc-9-20180715-1/gcc/fold-const.c:11964^M
0x814aeb c_fully_fold_internal^M
../../gcc-9-20180715-1/gcc/c/c-fold.c:626^M
0x8171b7 c_fully_fold(tree_node*, bool, bool*, bool)^M
../../gcc-9-20180715-1/gcc/c/c-fold.c:125^M
0x7e1dba build_binary_op(unsigned int, tree_code, tree_node*, tree_node*,
bool)^M
../../gcc-9-20180715-1/gcc/c/c-typeck.c:12015^M
0x7cbe40 c_objc_common_truthvalue_conversion(unsigned int, tree_node*)^M
../../gcc-9-20180715-1/gcc/c/c-typeck.c:12188^M
0x7fdd5e c_parser_condition^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5569^M
0x7fde07 c_parser_paren_condition^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5588^M
0x8099cd c_parser_if_statement^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5767^M
0x8099cd c_parser_statement_after_labels^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5399^M
0x80b4a9 c_parser_compound_statement_nostart^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5078^M
0x80b9d6 c_parser_compound_statement^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:4912^M
0x8093da c_parser_statement_after_labels^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5393^M
0x80ee0e c_parser_statement^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5366^M
0x80ee0e c_parser_c99_block_statement^M
../../gcc-9-20180715-1/gcc/c/c-parser.c:5605^M
Please submit a full bug report,^M
with preprocessed source if appropriate.^M
Please include the complete backtrace with any bug report.^M
See  for instructions.^M
compiler exited with status 1

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-18 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #24 from Bernd Edlinger  ---
Hope you don't mind, but may I suggest to do the comparison in unsigned
arithmetics, like:

  /* We don't know the starting offset, but we do know that the string
 has no internal zero bytes.  If the offset falls within the bounds
 of the string subtract the offset from the length of the string,
 and return that.  Otherwise the length is zero.  Take care to
 use SAVE_EXPR in case the OFFSET has side-effects.  */
  tree offsave = TREE_SIDE_EFFECTS (byteoff) ? save_expr (byteoff) :
byteoff;
  offsave = fold_convert (sizetype, offsave);
  tree condexp = fold_build2_loc (loc, LE_EXPR, boolean_type_node, offsave,
  size_int (len * eltsize));
  tree lenexp = size_diffop_loc (loc, size_int (len * eltsize), offsave);
  return fold_build3_loc (loc, COND_EXPR, ssizetype, condexp, lenexp,
  build_zero_cst (ssizetype));


That would have the advantage, that all undefined cases including i>len and
i<0 return 0, instead of an unlimited value.  This should not have any
extra cost.

BTW: the line "tree offsave = ...;" is 81 chars long and could be split up.

I don't know how to emit a trap in the false path of COND_EXPR.
All examples I see, use gimple for that.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #23 from Bernd Edlinger  ---
Aehm, and won't this kind of folding make it impossible
for asan/ubsan to spot the bug?
I mean why not make that dependent on the sanitizer?

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #22 from Bernd Edlinger  ---
(In reply to Martin Sebor from comment #21)
> Thanks for testing the patch!  I've tweaked it to avoid the ICE.  I'm not
> sure what masked the ICE in my testing but mixing signed and unsigned types
> in the same expression without conversion was the cause.

No problem.

One thought: if you already fold the strlen in a way where undefined
behaviour is singled out, could you also emit a gcc_unreachable() ?

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #21 from Martin Sebor  ---
Thanks for testing the patch!  I've tweaked it to avoid the ICE.  I'm not sure
what masked the ICE in my testing but mixing signed and unsigned types in the
same expression without conversion was the cause.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #20 from Bernd Edlinger  ---
part.c.004t.original looks funny:

;; Function main (null)
;; enabled by -tree-original


{
  volatile int i = 4;
  int n = 4;

volatile int i = 4;
int n = 4;
  SAVE_EXPR  <= 4 ? 4 - (ssizetype) SAVE_EXPR
<(sizetype) i> : 0>;, n = (int) ((unsigned int) (SAVE_EXPR  <= 4 ? 4 - (ssizetype) SAVE_EXPR <(sizetype) i> : 0>) +
(unsigned int) n);;
  if (n != 4)
{
  __builtin_abort ();
}
}
return 0;

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #19 from Bernd Edlinger  ---
sorry wrong test case:

$ cat part.c
cat part.c
#define a  "121\01" 

int main ()
{
  volatile int i=4;
  int n = __builtin_strlen ([0]);
  n += __builtin_strlen ([i]);

  if (n != 4)
__builtin_abort ();
}

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #18 from Bernd Edlinger  ---
(In reply to Martin Sebor from comment #12)
> Patch: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg00936.html

Sorry, Martin,
with your patch I have an ICE in the following test:

$ cat part.c
const char a[2][3] = { "121", "1" };

int main ()
{
  int n = __builtin_strlen ([0][0]);
  n += __builtin_strlen (a[0]);

  if (n != 8)
__builtin_abort ();
}

$ gcc part.c
part.c: In function 'main':
part.c:3:5: error: type mismatch in binary expression
 int main ()
 ^~~~
long unsigned int

ssizetype

ssizetype

iftmp.0 = 4 - _2;
part.c:3:5: internal compiler error: verify_gimple failed
0x106af1f verify_gimple_in_seq(gimple*)
../../gcc-trunk/gcc/tree-cfg.c:5085
0xc95dbc gimplify_body(tree_node*, bool)
../../gcc-trunk/gcc/gimplify.c:12822
0xc96284 gimplify_function_tree(tree_node*)
../../gcc-trunk/gcc/gimplify.c:12912
0xa3e8f2 cgraph_node::analyze()
../../gcc-trunk/gcc/cgraphunit.c:669
0xa401bd analyze_functions
../../gcc-trunk/gcc/cgraphunit.c:1122
0xa44c61 symbol_table::finalize_compilation_unit()
../../gcc-trunk/gcc/cgraphunit.c:2670
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #17 from Bernd Edlinger  ---
Martin,

in expr.c at string_constant() there is an impossible check:

  if (TREE_CODE (init) == CONSTRUCTOR)
{
  if (TREE_CODE (arg) != ARRAY_REF
  && TREE_CODE (arg) == COMPONENT_REF
  && TREE_CODE (arg) == MEM_REF)
return NULL_TREE;

it can't be COMPONENT_REF and MEM_REF at the same time.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #16 from Martin Sebor  ---
I would prefer to avoid discussing the array size rule and optimization in too
many places, and especially in bugs that aren't directly related to it.  There
are other bugs where it is being discussed (mainly pr86259), so let's keep it
there.

That said, since security and diagnostics are one of my main areas of focus let
me say this: There are standardization efforts where some of these concerns are
being actively discussed: both the language guarantees and requirements and the
mechanisms for relaxing them to perhaps make code like the example in comment
#8 valid (the C object model study group), and the safety and security
considerations surrounding these topics (e.g., the TS 17961 revision).  I have
been involved in these groups and others like it for many years, and at the
same time making an effort to enhance GCC to detect their violations.  There's
lots more work to do to be sure but I think GCC already is ahead of other
compilers in detecting these kinds of problems.  Some diagnostics are missing
and others are false positives because of missing optimizations (e.g., some of
those linked to bug 83819).  Others are missing because early optimizations
prevent them from being detected (e.g., bug 86434).  In this case, it should be
relatively straightforward to detect uses of unterminated const strings.  I
have raised bug 86552 for it and will look into implementing it.  It's a much
bigger challenge to get some of the others detected (or some of the false
positives avoided): partly because it's difficult to get maintainers to accept
middle-end warnings into GCC.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread sirl at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Franz Sirl  changed:

   What|Removed |Added

 CC||sirl at gcc dot gnu.org

--- Comment #15 from Franz Sirl  ---
(In reply to Bernd Edlinger from comment #8)
> $ cat part.c
> 
> const char a[2][3] = { "121", "1" };

FWIW, MSVC warns like this:

part.c(2): warning C4295: 'a': array is too small to include a terminating null
character

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #14 from Bernd Edlinger  ---
(In reply to Martin Sebor from comment #13)
> (In reply to Richard Biener from comment #9)
> > 
> > I bet Martin would argue it's invalid ...
> 
> That's right, the example in comment 8 is undefined because strlen()
> requires a nul-terminated string argument and a[0] in the call strlen(a[0])
> is not such a string.  It's not valid for strlen() to access one subobject
> when passed a pointer to another, even if the two are adjacent in memory. 
> This applies equally to struct members as well as multidimensional arrays.

From a security perspective I cannot agree.

First the sample generates 0 warnings -Wall and -Wextra
Second it generates zero warnings under -fsanitize=address,undefined

This is going into slippery terrain.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #13 from Martin Sebor  ---
(In reply to Richard Biener from comment #9)
> 
> I bet Martin would argue it's invalid ...

That's right, the example in comment 8 is undefined because strlen() requires a
nul-terminated string argument and a[0] in the call strlen(a[0]) is not such a
string.  It's not valid for strlen() to access one subobject when passed a
pointer to another, even if the two are adjacent in memory.  This applies
equally to struct members as well as multidimensional arrays.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Martin Sebor  changed:

   What|Removed |Added

   Keywords||patch

--- Comment #12 from Martin Sebor  ---
Patch: https://gcc.gnu.org/ml/gcc-patches/2018-07/msg00936.html

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #11 from Bernd Edlinger  ---
But seriously:

  /* Avoid returning a string that doesn't fit in the array
 it is stored in, like
 const char a[4] = "abcde";
 but do handle those that fit even if they have excess
 initializers, such as in
 const char a[4] = "abc\000\000";
 The excess elements contribute to TREE_STRING_LENGTH()
 but not to strlen().  */
  unsigned HOST_WIDE_INT length
= strnlen (TREE_STRING_POINTER (init), TREE_STRING_LENGTH (init));
  if (compare_tree_int (array_size, length + 1) < 0)
return NULL_TREE;

this is supposed to prevent such optimizations,
however it looks like the ARRAY_REFs decay in later optimization
stages, so here it looks like the access is for an array[6] at
offset 0 with an inital value of length 3.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #10 from Bernd Edlinger  ---
(In reply to Richard Biener from comment #9)
> 
> I bet Martin would argue it's invalid ...
> 
> The standard specifies initializing char[3] with "121" is valid.  7.24.1/1
> specifies "if an array is accessed beyond the end of an object, the behavior
> is undefined" where it is not clear how "object" relates to "array".
> 
> The definition of "string" doesn't talk about abstract layout so to me
> doesn't rule out char str[1][5] or str[5][1].  It rules out struct { char c;
> char d; } because of allowed padding.

Yes, you win!
But I bet someone will assign a CVE for this optimization.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #9 from Richard Biener  ---
(In reply to Bernd Edlinger from comment #8)
> $ cat part.c
> 
> const char a[2][3] = { "121", "1" };
> 
> int main ()
> {
>   int n = __builtin_strlen ([0][0]);
>   n += __builtin_strlen (a[0]);
> 
>   if (n != 8)
> __builtin_abort ();
> }
> 
> 
> I think I find no way to stop this example from being miscompiled.

I bet Martin would argue it's invalid ...

The standard specifies initializing char[3] with "121" is valid.  7.24.1/1
specifies "if an array is accessed beyond the end of an object, the behavior
is undefined" where it is not clear how "object" relates to "array".

The definition of "string" doesn't talk about abstract layout so to me
doesn't rule out char str[1][5] or str[5][1].  It rules out struct { char c;
char d; } because of allowed padding.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #8 from Bernd Edlinger  ---
$ cat part.c

const char a[2][3] = { "121", "1" };

int main ()
{
  int n = __builtin_strlen ([0][0]);
  n += __builtin_strlen (a[0]);

  if (n != 8)
__builtin_abort ();
}


I think I find no way to stop this example from being miscompiled.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #7 from Bernd Edlinger  ---
Maybe something like the following?

--- expr.c.kk   2018-07-17 10:14:43.668347058 +0200
+++ expr.c  2018-07-17 10:21:13.101779984 +0200
@@ -11282,6 +11282,7 @@ string_constant (tree arg, tree *ptr_off
   /* Non-constant index into the character array in an ARRAY_REF
  expression or null.  */
   tree varidx = NULL_TREE;
+  tree varsize = NULL_TREE;

   poly_int64 base_off = 0;

@@ -11289,6 +11290,7 @@ string_constant (tree arg, tree *ptr_off
 {
   arg = TREE_OPERAND (arg, 0);
   tree ref = arg;
+  varsize = TYPE_SIZE_UNIT (TREE_TYPE (ref));
   if (TREE_CODE (arg) == ARRAY_REF)
{
  tree idx = TREE_OPERAND (arg, 1);
@@ -11369,7 +11371,7 @@ string_constant (tree arg, tree *ptr_off
   /* Handle variables initialized with string literals.  */
   if (!init || init == error_mark_node)
 return NULL_TREE;
-  if (TREE_CODE (init) == CONSTRUCTOR)
+  if (TREE_CODE (init) == CONSTRUCTOR && !varidx)
 {
   if (TREE_CODE (arg) != ARRAY_REF
  && TREE_CODE (arg) == COMPONENT_REF
@@ -11401,8 +11403,7 @@ string_constant (tree arg, tree *ptr_off
   if (!init || TREE_CODE (init) != STRING_CST)
 return NULL_TREE;

-  tree array_size = DECL_SIZE_UNIT (array);
-  if (!array_size || TREE_CODE (array_size) != INTEGER_CST)
+  if (!varsize || TREE_CODE (varsize) != INTEGER_CST)
 return NULL_TREE;

   /* Avoid returning a string that doesn't fit in the array
@@ -11415,7 +11416,7 @@ string_constant (tree arg, tree *ptr_off
  but not to strlen().  */
   unsigned HOST_WIDE_INT length
 = strnlen (TREE_STRING_POINTER (init), TREE_STRING_LENGTH (init));
-  if (compare_tree_int (array_size, length + 1) < 0)
+  if (compare_tree_int (varsize, length + 1) < 0)
 return NULL_TREE;

   *ptr_offset = offset;

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-17 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #6 from Bernd Edlinger  ---
const char a[2][3] = { "1234", "12" };

int main ()
{
  {
volatile int i = 1;
int n = __builtin_strlen (a[i]);
n += __builtin_strlen (a[0]);

if (n != 3)
  __builtin_abort ();
  }
}

maybe you should look at this example, what is happening here?
I mean we know for sure that strlen is used on a non-zero terminated
value. especially if the initializer is exactly 3 characters wide,
it is even completely without warning, and yet __builtin_strlen (a[0])
seems to be folded to 4.

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-16 Thread edlinger at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #5 from Bernd Edlinger  ---
FYI the patch for pr85528 does not contain the hunk from comment #3

I think it is probably more restrictive than necessary.

Happy hacking!

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-16 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Martin Sebor  changed:

   What|Removed |Added

   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=86528

--- Comment #4 from Martin Sebor  ---
A reduced test case not involving loops is below.  There are a couple of places
in the constant_string() function where the handling of non-constant array
indices isn't correct and needs to be adjusted.  See also bug 86528.

static const char a[2][3] = { "1", "12" };
static const char b[2][2][5] = { { "1", "12" }, { "123", "1234" } };

int main ()
{
  {
volatile int i = 1;
int n = __builtin_strlen (a[i]);
n += __builtin_strlen (a[0]);

if (n != 3)
  __builtin_abort ();
  }

  {
 volatile int i = 1;
 int n = __builtin_strlen (b[1][i]);
 n += __builtin_strlen (b[1][0]);
 if (n != 7)
   __builtin_abort ();
  }
}

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-16 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

--- Comment #3 from Bernd Edlinger  ---
Hi Martin,
how about:

--- gcc/expr.c.jj   2018-07-09 22:33:48.0 +0200
+++ gcc/expr.c  2018-07-16 17:18:47.919177047 +0200
@@ -11359,6 +11359,9 @@ string_constant (tree arg, tree *ptr_off
   return array;
 }

+  if (varidx != NULL_TREE)
+return NULL_TREE;
+
   if (!VAR_P (array) && TREE_CODE (array) != CONST_DECL)
 return NULL_TREE;

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-16 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Martin Sebor  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |msebor at gcc dot 
gnu.org

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-16 Thread bernd.edlinger at hotmail dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Bernd Edlinger  changed:

   What|Removed |Added

 CC||bernd.edlinger at hotmail dot 
de

--- Comment #2 from Bernd Edlinger  ---
x is not initialized.
does it help to initialize it to zero?

[Bug tree-optimization/86532] [9 Regression] Wrong code due to a wrong strlen folding starting with r262522

2018-07-16 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86532

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P1
 Status|UNCONFIRMED |NEW
   Target Milestone|--- |9.0
 Ever confirmed|0   |1

--- Comment #1 from Richard Biener  ---
Confirmed.