Re: [PATCH] fix a couple of bugs in const string folding (PR 86532)

2018-07-22 Thread Bernd Edlinger
On 07/21/18 00:15, Martin Sebor wrote:
> On 07/20/2018 08:51 AM, Bernd Edlinger wrote:
>> Martin,
>>
>> when I look at tree-ssa-forwprop.c:
>>
>>    str1 = string_constant (src1, &off1);
>>    if (str1 == NULL_TREE)
>>  break;
>>    if (!tree_fits_uhwi_p (off1)
>>    || compare_tree_int (off1, TREE_STRING_LENGTH (str1) - 1) 
>> > 0
>>    || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
>>   - tree_to_uhwi (off1)) > 0
>>    || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
>>    || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
>>   != TYPE_MODE (char_type_node))
>>  break;
>>
>> I don't think it is a good idea to let string_constant return
>> strings which have not necessarily valid content after the first
>> NUL byte.  It looks like the content has to be valid up to
>> TREE_STRING_LENGTH.
> 
> I'm not sure I understand when this could happen.  From the patch
> below it sounds like you are concerned about cases like:
> 
>    const char a[4] = "abc\000\000";
> 
> where the STRING_CST is bigger than the array.  But the string
> constant has valid content here up to TREE_STRING_LENGTH.  Am
> I missing something?  (A test case would be helpful.)
> 

No, I mean something like:

$ cat y.c
const char a[2][3] = { "1234", "xyz" };
char b[6];

int main ()
{
   __builtin_memcpy(b, a, 4);
   __builtin_memset(b + 4, 'a', 2);
   __builtin_printf("%.6s\n", b);
}
$ gcc y.c
y.c:1:24: warning: initializer-string for array of chars is too long
  const char a[2][3] = { "1234", "xyz" };
 ^~
y.c:1:24: note: (near initialization for 'a[0]')
$ ./a.out
1234aa

but expected would be "123xaa".


> In any case, unless the concern is specifically related to
> this bug fix let's discuss it separately so I can fix this
> bug.  I'm not opposed to making further changes here (in
> fact, I have one in the queue and two others that I raised
> in Bugzilla in response to our discussion so far), I just
> want to avoid mission creep.
> 

I think when you touch a function you should fix it completely
or restrict it to the subset that is known to be safe, and not
leave lots of already known bugs behind.

Fixing this bug by bug will soon exceed my ability to reverse
engineer test cases for the remaining bugs.


Bernd.

> Martin
> 
>>
>> So may I suggest to do something like the following
>> (diff to your last patch):
>>
>> --- expr.c.jj    2018-07-20 10:51:51.983605588 +0200
>> +++ expr.c    2018-07-20 15:07:29.769423479 +0200
>> @@ -11277,6 +11277,7 @@ tree
>>   string_constant (tree arg, tree *ptr_offset)
>>   {
>>     tree array;
>> +  tree array_size;
>>     STRIP_NOPS (arg);
>>
>>     /* Non-constant index into the character array in an ARRAY_REF
>> @@ -11295,9 +11296,11 @@ string_constant (tree arg, tree *ptr_off
>>
>>     arg = TREE_OPERAND (arg, 0);
>>     tree ref = arg;
>> +  tree reftype = TREE_TYPE (ref);
>>     if (TREE_CODE (arg) == ARRAY_REF)
>>   {
>>     tree idx = TREE_OPERAND (arg, 1);
>> +  reftype = TREE_TYPE (TREE_OPERAND (arg, 0));
>>     if (TREE_CODE (idx) != INTEGER_CST
>>     && TREE_CODE (argtype) == POINTER_TYPE)
>>   {
>> @@ -11313,6 +11316,11 @@ string_constant (tree arg, tree *ptr_off
>>   return NULL_TREE;
>>   }
>>   }
>> +  if (TREE_CODE (reftype) != ARRAY_TYPE)
>> +    return NULL_TREE;
>> +  while (TREE_CODE (TREE_TYPE (reftype)) == ARRAY_TYPE)
>> +    reftype = TREE_TYPE (reftype);
>> +  array_size = TYPE_SIZE_UNIT (reftype);
>>     array = get_addr_base_and_unit_offset (ref, &base_off);
>>     if (!array
>>     || (TREE_CODE (array) != VAR_DECL
>> @@ -11345,7 +11353,10 @@ string_constant (tree arg, tree *ptr_off
>>     return NULL_TREE;
>>   }
>>     else if (DECL_P (arg))
>> -    array = arg;
>> +    {
>> +  array = arg;
>> +  array_size = DECL_SIZE_UNIT (array);
>> +    }
>>     else
>>   return NULL_TREE;
>>
>> @@ -11410,24 +11421,18 @@ 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)
>>   return NULL_TREE;
>>
>>     /* Avoid returning a string that doesn't fit in the array
>> - it is stored in, like
>> + 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 charsize
>> -    = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init;
>> + ... or:
>> + const char a[4] = "abc\000";
>> + ... because some cal

Re: [wwwdocs] Mention LTO link-time issue fixed in gcc 8.2

2018-07-22 Thread Gerald Pfeifer
On Sat, 21 Jul 2018, Gerald Pfeifer wrote:
> Thanks, Jan, this looks fine to me.

Oops, I missed  closing an ; just followed up on your
commit to fix that.

Gerald

Index: changes.html
===
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-8/changes.html,v
retrieving revision 1.90
diff -u -r1.90 changes.html
--- changes.html21 Jul 2018 19:55:10 -  1.90
+++ changes.html22 Jul 2018 08:25:46 -
@@ -1321,7 +1321,7 @@
 complete (that is, it is possible that some PRs that have been fixed
 are not listed here).
 
-General Improvements
+General Improvements
   
 Fixed LTO link-time performance problems caused by an overflow
in the partitioning algorithm while building large binaries.


Re: [PATCH 1/4] Clean up of new format of -falign-FOO.

2018-07-22 Thread Gerald Pfeifer
On Wed, 18 Jul 2018, Martin Sebor wrote:
> I'm seeing lots of warnings for this file:
> 
> /ssd/src/gcc/svn/gcc/align.h:53:32: warning: extended initializer lists only
> available with -std=c++11 or -std=gnu++11

With clang version 3.4 (system compiler on FreeBSD 10.x) this is
even a hard error and GCC failed to build.  So thanks for fixing
this, Martin!

Gerald


Re: [PATCH 8/8] Enhance documentation of gcov.

2018-07-22 Thread Gerald Pfeifer
On Fri, 28 Apr 2017, Martin Sebor wrote:
>> 2017-04-27  Martin Liska  
>>
>>  * doc/gcov.texi: Enhance documentation of gcov.
> Since I started picking on this change set I might as well keep
> at it ;)   Just a tiny nit: the sentence is missing a preposition:
> 
>   depending on  whether a basic block is reachable.

This adds a bit more.  Applied.

(This section still needs a bit more love, ideally by a native
speaker.)

Gerald


2018-07-22  Gerald Pfeifer  

* doc/gcov.texi (Invoking Gcov): Editorial changes.

Index: doc/gcov.texi
===
--- doc/gcov.texi   (revision 262161)
+++ doc/gcov.texi   (working copy)
@@ -378,12 +378,12 @@
 containing no code.  Unexecuted lines are marked @samp{#} or
 @samp{=}, depending on whether they are reachable by
 non-exceptional paths or only exceptional paths such as C++ exception
-handlers, respectively. Given @samp{-a} option, unexecuted blocks are
+handlers, respectively. Given the @samp{-a} option, unexecuted blocks are
 marked @samp{$} or @samp{%}, depending on whether a basic block
 is reachable via non-exceptional or exceptional paths.
 Executed basic blocks having a statement with zero @var{execution_count}
-end with @samp{*} character and are colored with magenta color with @option{-k}
-option.  The functionality is not supported in Ada.
+end with @samp{*} character and are colored with magenta color with
+the @option{-k} option.  This functionality is not supported in Ada.
 
 Note that GCC can completely remove the bodies of functions that are
 not needed -- for instance if they are inlined everywhere.  Such functions


Re: [PATCH] fix a couple of bugs in const string folding (PR 86532)

2018-07-22 Thread Bernd Edlinger
On 07/21/18 01:58, Martin Sebor wrote:
> On 07/20/2018 03:11 PM, Bernd Edlinger wrote:
>> I think I have found a valid test case where the latest patch
>> does generate invalid code:
> 
> This is due to another bug in string_constant() that's latent
> on trunk but that's exposed by the patch.  Trunk only "works"
> because of a bug/limitation in c_strlen() that the patch fixes
> or removes.
> 

I am not sure if that falls under the definition of "latent" bug.
A latent bug would be something unexpected in a completely different
area of the compiler that is triggered by an improved optimization
or a fixed bug elsewhere.

> The underlying root cause is the handling of POINTER_PLUS
> expressions in string_constant().  The original code (before
> the handling of aggregates was added) just dealt with string
> constants.  The new code does much more but doesn't get it
> quite right in these cases.
> 

I think you should be much more careful with the expressions
you evaluate in string_constant.  For instance when you look
at get_addr_base_and_unit_offset, you'll see it walks through
all kinds of type casts, VIEW_CONVERT_EXPR and MEM_REF with
nonzero displacement.  When you see something like that do
not fold that on the assumption that the source code does not
have undefined behavior.

So I'd say you should add a check that there is no type
cast in the expression you parse.  If that is the case,
your optimization will certainly be wrong.

As Richard already repeatedly said, and I can only emphasize
this once more:

The middle end does not follow the "C" standard too closely,
and it is also the C++, fortran, Ada and Go middle-end.
Even if the source code does not exhibit undefined behavior
the folding in the middle-end can introduce it.


Bernd.

> It shouldn't be too difficult to fix, but as valuable as
> the testing you are doing is, I'd really prefer to focus
> on one problem at a time and make incremental progress.
> It will make it easier to track down and fix regressions
> than lumping multiple fixes into a larger patch.
> 
> Martin
> 
>>
>> $ cat part.c
>> static const char a[3][8] = { "1234", "12345", "123456" };
>>
>> int main ()
>> {
>>    volatile int i = 1;
>>    int n = __builtin_strlen (*(&a[1]+i));
>>
>>    if (n != 6)
>>  __builtin_abort ();
>> }
>> $ gcc part.c -fdump-tree-original
>> $ ./a.out
>> Aborted (core dumped)
>> $ cat part.c.004t.original
>>
>> ;; Function main (null)
>> ;; enabled by -tree-original
>>
>>
>> {
>>    volatile int i = 1;
>>    int n = (ssizetype) (SAVE_EXPR <(long unsigned int) i * 8>) <= 5 ? (int) 
>> (5 - (unsigned int) (SAVE_EXPR <(long unsigned int) i * 8>)) : 0;
>>
>>  volatile int i = 1;
>>  int n = (ssizetype) (SAVE_EXPR <(long unsigned int) i * 8>) <= 5 ? 
>> (int) (5 - (unsigned int) (SAVE_EXPR <(long unsigned int) i * 8>)) : 0;
>>    if (n != 6)
>>  {
>>    __builtin_abort ();
>>  }
>> }
>> return 0;
>>
>>
>> string_constant is called with arg = (const char *) (&a[1] + (sizetype) 
>> ((long unsigned int) i * 8))
> 


New Swedish PO file for 'gcc' (version 8.1.0)

2018-07-22 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.

A revised PO file for textual domain 'gcc' has been submitted
by the Swedish team of translators.  The file is available at:

http://translationproject.org/latest/gcc/sv.po

(This file, 'gcc-8.1.0.sv.po', has just now been sent to you in
a separate email.)

All other PO files for your package are available in:

http://translationproject.org/latest/gcc/

Please consider including all of these in your next release, whether
official or a pretest.

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

The following HTML page has been updated:

http://translationproject.org/domain/gcc.html

If any question arises, please contact the translation coordinator.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




Re: [PATCH 1/4] Clean up of new format of -falign-FOO.

2018-07-22 Thread Gerald Pfeifer
On Sun, 22 Jul 2018, Gerald Pfeifer wrote:
> With clang version 3.4 (system compiler on FreeBSD 10.x) this is
> even a hard error and GCC failed to build.  So thanks for fixing
> this, Martin!

Unfortunately it appears there was another bootstrap failure hidden
behind that one:


In file included from /scratch/tmp/gerald/GCC-HEAD/gcc/system.h:691,
 from /scratch/tmp/gerald/GCC-HEAD/gcc/tree-vect-slp.c:23:
/scratch/tmp/gerald/GCC-HEAD/gcc/tree-vect-slp.c: In function 
‘_slp_tree* vect_build_slp_tree_2(vec_info*, vec, unsigned int, 
poly_uint64*, vec<_slp_tree*>*, bool*, unsigned int*, unsigned int*, 
unsigned int)’:
/scratch/tmp/gerald/GCC-HEAD/gcc/../include/libiberty.h:722:36: error: ‘alloca’ 
bound is unknown [-Werror=alloca-larger-than=]
 # define alloca(x) __builtin_alloca(x)
^~~
/scratch/tmp/gerald/GCC-HEAD/gcc/../include/libiberty.h:356:33: note: in 
expansion of macro ‘alloca’
 #define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N)))
 ^~
/scratch/tmp/gerald/GCC-HEAD/gcc/tree-vect-slp.c:1437:16: note: in expansion of 
macro ‘XALLOCAVEC’
bool *tem = XALLOCAVEC (bool, group_size);
^~
cc1plus: all warnings being treated as errors
gmake[3]: *** [Makefile:1112: tree-vect-slp.o] Error 1
gmake[3]: Leaving directory '/scratch/tmp/gerald/OBJ-0722-0939/gcc'
gmake[2]: *** [Makefile:4644: all-stage2-gcc] Error 2


This is on FreeBSD 10.4 which features clang 3.4.1 as system compiler;
FreeBSD 11.2 with clang 6.0.0 does not trigger that.

Gerald

Re: [PATCH 1/4] Clean up of new format of -falign-FOO.

2018-07-22 Thread Rainer Orth
Hi Gerald,

> On Sun, 22 Jul 2018, Gerald Pfeifer wrote:
>> With clang version 3.4 (system compiler on FreeBSD 10.x) this is
>> even a hard error and GCC failed to build.  So thanks for fixing
>> this, Martin!
>
> Unfortunately it appears there was another bootstrap failure hidden
> behind that one:
>
>
> In file included from /scratch/tmp/gerald/GCC-HEAD/gcc/system.h:691,
>  from /scratch/tmp/gerald/GCC-HEAD/gcc/tree-vect-slp.c:23:
> /scratch/tmp/gerald/GCC-HEAD/gcc/tree-vect-slp.c: In function 
> ‘_slp_tree* vect_build_slp_tree_2(vec_info*, vec, unsigned int, 
> poly_uint64*, vec<_slp_tree*>*, bool*, unsigned int*, unsigned int*, 
> unsigned int)’:
> /scratch/tmp/gerald/GCC-HEAD/gcc/../include/libiberty.h:722:36: error: 
> ‘alloca’ bound is unknown [-Werror=alloca-larger-than=]
>  # define alloca(x) __builtin_alloca(x)
> ^~~
> /scratch/tmp/gerald/GCC-HEAD/gcc/../include/libiberty.h:356:33: note: in 
> expansion of macro ‘alloca’
>  #define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N)))
>  ^~
> /scratch/tmp/gerald/GCC-HEAD/gcc/tree-vect-slp.c:1437:16: note: in expansion 
> of macro ‘XALLOCAVEC’
> bool *tem = XALLOCAVEC (bool, group_size);
> ^~
> cc1plus: all warnings being treated as errors
> gmake[3]: *** [Makefile:1112: tree-vect-slp.o] Error 1
> gmake[3]: Leaving directory '/scratch/tmp/gerald/OBJ-0722-0939/gcc'
> gmake[2]: *** [Makefile:4644: all-stage2-gcc] Error 2
>
>
> This is on FreeBSD 10.4 which features clang 3.4.1 as system compiler;
> FreeBSD 11.2 with clang 6.0.0 does not trigger that.

known issue: PR bootstrap/86621.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


[PATCH] Avoid out of scope access in hsa-dump.c

2018-07-22 Thread Bernd Edlinger
Hi,

this fixes an use of a buffer after the block scope
in hsa-dump.c: "buf" is assigned to "name" and used after
the scope ends in a fprintf.

I have not done any real checks, except boot-strapping with
all languages.
Is it OK for trunk?


Thanks
Bernd.
2018-07-22  Bernd Edlinger  

	hsa-dump.c (dump_hsa_symbol): Avoid out of scope access to buf.

Index: gcc/hsa-dump.c
===
--- gcc/hsa-dump.c	(revision 262904)
+++ gcc/hsa-dump.c	(working copy)
@@ -776,11 +776,11 @@ static void
 dump_hsa_symbol (FILE *f, hsa_symbol *symbol)
 {
   const char *name;
+  char buf[64];
   if (symbol->m_name)
 name = symbol->m_name;
   else
 {
-  char buf[64];
   sprintf (buf, "__%s_%i", hsa_seg_name (symbol->m_segment),
 	   symbol->m_name_number);
 


[C++ PATCH] Avoid code generation changes with -Wnonnull-compare vs. -Wno-nonnull-compare (PR c++/86569)

2018-07-22 Thread Jakub Jelinek
Hi!

A couple of -fcompare-debug=-Wsomething PRs have been filed recently, this
fixes one of them.  Changing code generation based on TREE_NO_WARNING flag
which usually gets set only in the warning code, or on warn_* option is
undesirable.  This patch prevents that kind of folding regardless of the
warning options, the GIMPLE optimizers can handle it fine (but it makes a
difference with -O0).

Bootstrapped/regtested on x86_64-linux (only, i686-linux bootstrap is
broken), ok for trunk?

2018-07-22  Jakub Jelinek  

PR c++/86569
* cp-gimplify.c (cp_fold): Don't fold comparisons into other kind
of expressions other than INTEGER_CST regardless of TREE_NO_WARNING
or warn_nonnull_compare.

* g++.dg/warn/Wnonnull-compare-9.C: New test.

--- gcc/cp/cp-gimplify.c.jj 2018-07-16 09:43:03.237023048 +0200
+++ gcc/cp/cp-gimplify.c2018-07-19 11:44:24.881759294 +0200
@@ -2381,21 +2381,26 @@ cp_fold (tree x)
   else
x = fold (x);
 
-  if (TREE_NO_WARNING (org_x)
- && warn_nonnull_compare
- && COMPARISON_CLASS_P (org_x))
+  /* This is only needed for -Wnonnull-compare and only if
+TREE_NO_WARNING (org_x), but to avoid that option affecting code
+generation, we do it always.  */
+  if (COMPARISON_CLASS_P (org_x))
{
  if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
;
  else if (COMPARISON_CLASS_P (x))
-   TREE_NO_WARNING (x) = 1;
+   {
+ if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
+   TREE_NO_WARNING (x) = 1;
+   }
  /* Otherwise give up on optimizing these, let GIMPLE folders
 optimize those later on.  */
  else if (op0 != TREE_OPERAND (org_x, 0)
   || op1 != TREE_OPERAND (org_x, 1))
{
  x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
- TREE_NO_WARNING (x) = 1;
+ if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
+   TREE_NO_WARNING (x) = 1;
}
  else
x = org_x;
--- gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C.jj   2018-07-19 
11:57:41.909727597 +0200
+++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C  2018-07-19 
11:57:14.627696497 +0200
@@ -0,0 +1,11 @@
+// PR c++/86569
+// { dg-do compile }
+// { dg-options "-fcompare-debug=-Wnonnull-compare" }
+
+bool b;
+
+int
+main ()
+{
+  return ((!b) != 0);
+}

Jakub


Re: [C++ PATCH] Avoid code generation changes with -Wnonnull-compare vs. -Wno-nonnull-compare (PR c++/86569)

2018-07-22 Thread Richard Biener
On July 22, 2018 9:15:50 PM GMT+02:00, Jakub Jelinek  wrote:
>Hi!
>
>A couple of -fcompare-debug=-Wsomething PRs have been filed recently,
>this
>fixes one of them.  Changing code generation based on TREE_NO_WARNING
>flag
>which usually gets set only in the warning code, or on warn_* option is
>undesirable.  This patch prevents that kind of folding regardless of
>the
>warning options, the GIMPLE optimizers can handle it fine (but it makes
>a
>difference with -O0).
>
>Bootstrapped/regtested on x86_64-linux (only, i686-linux bootstrap is
>broken), ok for trunk?

OK. 

Richard. 

>2018-07-22  Jakub Jelinek  
>
>   PR c++/86569
>   * cp-gimplify.c (cp_fold): Don't fold comparisons into other kind
>   of expressions other than INTEGER_CST regardless of TREE_NO_WARNING
>   or warn_nonnull_compare.
>
>   * g++.dg/warn/Wnonnull-compare-9.C: New test.
>
>--- gcc/cp/cp-gimplify.c.jj2018-07-16 09:43:03.237023048 +0200
>+++ gcc/cp/cp-gimplify.c   2018-07-19 11:44:24.881759294 +0200
>@@ -2381,21 +2381,26 @@ cp_fold (tree x)
>   else
>   x = fold (x);
> 
>-  if (TREE_NO_WARNING (org_x)
>-&& warn_nonnull_compare
>-&& COMPARISON_CLASS_P (org_x))
>+  /* This is only needed for -Wnonnull-compare and only if
>+   TREE_NO_WARNING (org_x), but to avoid that option affecting code
>+   generation, we do it always.  */
>+  if (COMPARISON_CLASS_P (org_x))
>   {
> if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
>   ;
> else if (COMPARISON_CLASS_P (x))
>-  TREE_NO_WARNING (x) = 1;
>+  {
>+if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
>+  TREE_NO_WARNING (x) = 1;
>+  }
> /* Otherwise give up on optimizing these, let GIMPLE folders
>optimize those later on.  */
> else if (op0 != TREE_OPERAND (org_x, 0)
>  || op1 != TREE_OPERAND (org_x, 1))
>   {
> x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
>-TREE_NO_WARNING (x) = 1;
>+if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
>+  TREE_NO_WARNING (x) = 1;
>   }
> else
>   x = org_x;
>--- gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C.jj  2018-07-19
>11:57:41.909727597 +0200
>+++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C 2018-07-19
>11:57:14.627696497 +0200
>@@ -0,0 +1,11 @@
>+// PR c++/86569
>+// { dg-do compile }
>+// { dg-options "-fcompare-debug=-Wnonnull-compare" }
>+
>+bool b;
>+
>+int
>+main ()
>+{
>+  return ((!b) != 0);
>+}
>
>   Jakub



[C++ PATCH] Implement P0595R1 - so far as __builtin_is_constant_evaluated rather than std::is_constant_evaluated magic builtin

2018-07-22 Thread Jakub Jelinek
Hi!

As part of the PR86590 discussions that the current libstdc++
__constant_string is extremely costly, because we don't fold the
__builtin_constant_p in the loop early enough and because Richard doesn't
want __builtin_early_constant_p, this patch is an attempt to implement
P0595R1 as a builtin (which will be likely needed anyway, so that libstdc++
will be able to use it even without -std=c++2a).

When evaluating (outermost) constant expressions with !ctx->quiet (i.e.
when we require constant expressions) as well in the special case of
reference initializers, or const non-volatile decl initializers, or
TREE_STATIC decl initializers, the builtin is folded into true (for the
ctx->quiet special cases if the constexpr evaluation doesn't turn a
constant expression, we retry without the special flag), otherwise
folding of it is deferred and it is flagged as non-constant expression,
and folding during gimplification folds it into false.

Not really sure about potential_constant_expression, for if it attempts
to evaluate the condition with ctx->quiet true and the patch doesn't set the
magic flag to fold the builtin to true in that case; it is unclear to me if
in case the condition includes std::is_constant_evaluated () call we need
to fold it also to true or not depending on what will we be evaluating later
on.

Bootstrapped/regtested on x86_64-linux.

2018-07-22  Jakub Jelinek  

P0595R1 - is_constant_evaluated
* builtins.def (BUILT_IN_IS_CONSTANT_EVALUATED): New C++ builtin.
* builtins.c (fold_builtin_0): Fold BUILT_IN_IS_CONSTANT_EVALUATED
to 0.
cp/
* cp-tree.h (maybe_constant_init): Add const_evaluated argument.
* typeck2.c (store_init_value): Pass true as new argument to
maybe_constant_init.
* constexpr.c (struct constexpr_ctx): Add const_evaluated field.
(cxx_eval_builtin_function_call): Handle
BUILT_IN_IS_CONSTANT_EVALUATED.
(cxx_eval_outermost_constant_expr): Add const_evaluated argument,
initialize const_evaluated field in ctx.  If the result is
TREE_CONSTANT and non_constant_p, retry with const_evaluated false
if it was true.
(is_sub_constant_expr): Initialize const_evaluated_field in ctx.
(cxx_constant_value): Pass true as const_evaluated to
cxx_eval_outermost_constant_expr.
(maybe_constant_value): Pass false as const_evaluated to
cxx_eval_outermost_constant_expr.
(fold_non_dependent_expr): Likewise.
(maybe_constant_init_1): Add const_evaluated argument, pass it
down to cxx_eval_outermost_constant_expr.  Pass !allow_non_constant
instead of false as strict to cxx_eval_outermost_constant_expr.
(maybe_constant_init): Add const_evaluated argument, pass it down
to maybe_constant_init_1.
(cxx_constant_init): Pass true as const_evaluated to
maybe_constant_init_1.
* cp-gimplify.c (cp_fold): Don't fold BUILT_IN_IS_CONSTANT_EVALUATED
calls.
lto/
* lto-lang.c (c_dialect_cxx): Define.
ada/
* gcc-interface/utils.c (c_dialect_cxx): Define.
brig/
* brig-lang.c (c_dialect_cxx): Define.
testsuite/
* g++.dg/cpp2a/is-constant-evaluated1.C: New test.

--- gcc/builtins.def.jj 2018-06-20 08:15:34.179862153 +0200
+++ gcc/builtins.def2018-07-20 12:03:10.254453811 +0200
@@ -974,6 +974,11 @@ DEF_EXT_LIB_BUILTIN(BUILT_IN_PRINTF_
 DEF_EXT_LIB_BUILTIN(BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", 
BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_NONNULL_1_FORMAT_PRINTF_3_0)
 DEF_EXT_LIB_BUILTIN(BUILT_IN_VPRINTF_CHK, "__vprintf_chk", 
BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
 
+/* C++ __builtin_is_constant_evaluated.  */
+DEF_BUILTIN (BUILT_IN_IS_CONSTANT_EVALUATED, "__builtin_is_constant_evaluated",
+BUILT_IN_NORMAL, BT_FN_BOOL, BT_LAST, false, false, false,
+ATTR_CONST_NOTHROW_LEAF_LIST, true, c_dialect_cxx ())
+
 /* Profiling hooks.  */
 DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", 
BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
 false, false, false, ATTR_NULL, true, true)
--- gcc/builtins.c.jj   2018-07-16 23:24:51.306429546 +0200
+++ gcc/builtins.c  2018-07-20 12:09:13.278818768 +0200
@@ -9104,6 +9104,10 @@ fold_builtin_0 (location_t loc, tree fnd
 case BUILT_IN_CLASSIFY_TYPE:
   return fold_builtin_classify_type (NULL_TREE);
 
+case BUILT_IN_IS_CONSTANT_EVALUATED:
+  /* The C++ FE can evaluate this to something other than false.  */
+  return boolean_false_node; 
+
 default:
   break;
 }
--- gcc/cp/cp-tree.h.jj 2018-07-18 22:57:10.657780293 +0200
+++ gcc/cp/cp-tree.h2018-07-20 18:10:33.416409798 +0200
@@ -7536,7 +7536,7 @@ extern bool require_potential_rvalue_con
 extern tree cxx_constant_value (tree, tree = NULL_TREE);
 extern tree cxx_constant_init  (tree, tree = NULL_TREE);
 extern tree maybe_c

Re: [PATCH] specify large command line option arguments (PR 82063)

2018-07-22 Thread Martin Sebor

On 07/21/2018 06:42 PM, H.J. Lu wrote:

On Fri, Jul 20, 2018 at 1:57 PM, Martin Sebor  wrote:

On 07/19/2018 04:31 PM, Jeff Law wrote:


On 06/24/2018 03:05 PM, Martin Sebor wrote:


Storing integer command line option arguments in type int
limits options such as -Wlarger-than= or -Walloca-larger-than
to at most INT_MAX (see bug 71905).  Larger values wrap around
zero.  The value zero is considered to disable the option,
making it impossible to specify a zero limit.

To get around these limitations, the -Walloc-size-larger-than=
option accepts a string argument that it then parses itself
and interprets as HOST_WIDE_INT.  The option also accepts byte
size suffixes like KB, MB, GiB, etc. to make it convenient to
specify very large limits.

The int limitation is obviously less than ideal in a 64-bit
world.  The treatment of zero as a toggle is just a minor wart.
The special treatment to make it work for just a single option
makes option handling inconsistent.  It should be possible for
any option that takes an integer argument to use the same logic.

The attached patch enhances GCC option processing to do that.
It changes the storage type of option arguments from int to
HOST_WIDE_INT and extends the existing (although undocumented)
option property Host_Wide_Int to specify wide option arguments.
It also introduces the ByteSize property for options for which
specifying the byte-size suffix makes sense.

To make it possible to consider zero as a meaningful argument
value rather than a flag indicating that an option is disabled
the patch also adds a CLVC_SIZE enumerator to the cl_var_type
enumeration, and modifies how options of the kind are handled.

Warning options that take large byte-size arguments can be
disabled by specifying a value equal to or greater than
HOST_WIDE_INT_M1U.  For convenience, aliases in the form of
-Wno-xxx-larger-than have been provided for all the affected
options.

In the patch all the existing -larger-than options are set
to PTRDIFF_MAX.  This makes them effectively enabled, but
because the setting is exceedingly permissive, and because
some of the existing warnings are already set to the same
value and some other checks detect and reject such exceedingly
large values with errors, this change shouldn't noticeably
affect what constructs are diagnosed.

Although all the options are set to PTRDIFF_MAX, I think it
would make sense to consider setting some of them lower, say
to PTRDIFF_MAX / 2.  I'd like to propose that in a followup
patch.

To minimize observable changes the -Walloca-larger-than and
-Wvla-larger-than warnings required more extensive work to
make of the new mechanism because of the "unbounded" argument
handling (the warnings trigger for arguments that are not
visibly constrained), and because of the zero handling
(the warnings also trigger


Martin


gcc-82063.diff


PR middle-end/82063 - issues with arguments enabled by -Wall

gcc/ada/ChangeLog:

PR middle-end/82063
* gcc-interface/misc.c (gnat_handle_option): Change function
argument
to HOST_WIDE_INT.

gcc/brig/ChangeLog:
* brig/brig-lang.c (brig_langhook_handle_option): Change function
argument to HOST_WIDE_INT.

gcc/c-family/ChangeLog:

PR middle-end/82063
* c-common.h (c_common_handle_option): Change function argument
to HOST_WIDE_INT.
* c-opts.c (c_common_init_options): Same.
(c_common_handle_option): Same.  Remove special handling of
OPT_Walloca_larger_than_ and OPT_Wvla_larger_than_.
* c.opt (-Walloc-size-larger-than, -Walloca-larger-than): Change
options to take a HOST_WIDE_INT argument and accept a byte-size
suffix.  Initialize.
(-Wvla-larger-than): Same.
(-Wno-alloc-size-larger-than, -Wno-alloca-larger-than): New.
(-Wno-vla-larger-than): Same.


gcc/fortran/ChangeLog:

PR middle-end/82063
* gfortran.h (gfc_handle_option): Change function argument
to HOST_WIDE_INT.
* options.c (gfc_handle_option): Same.

gcc/go/ChangeLog:

PR middle-end/82063
* go-lang.c (go_langhook_handle_option): Change function argument
to HOST_WIDE_INT.

gcc/lto/ChangeLog:

PR middle-end/82063
* lto-lang.c (lto_handle_option): Change function argument
to HOST_WIDE_INT.

gcc/testsuite/ChangeLog:

PR middle-end/82063
* gcc.dg/Walloc-size-larger-than-16.c: Adjust.
* gcc.dg/Walloca-larger-than.c: New test.
* gcc.dg/Wframe-larger-than-2.c: New test.
* gcc.dg/Wlarger-than3.c: New test.
* gcc.dg/Wvla-larger-than-3.c: New test.

gcc/ChangeLog:

PR middle-end/82063
* builtins.c (expand_builtin_alloca): Adjust.
* calls.c (alloc_max_size): Simplify.
* cgraphunit.c (cgraph_node::expand): Adjust.
* common.opt (larger_than_size, warn_frame_larger_than): Remove
variables.
(frame_larger_than_size): Same.
(-Wframe-larger-than, -Wlarger

Re: [PATCH] fix a couple of bugs in const string folding (PR 86532)

2018-07-22 Thread Martin Sebor

On 07/22/2018 02:00 AM, Bernd Edlinger wrote:

On 07/21/18 00:15, Martin Sebor wrote:

On 07/20/2018 08:51 AM, Bernd Edlinger wrote:

Martin,

when I look at tree-ssa-forwprop.c:

   str1 = string_constant (src1, &off1);
   if (str1 == NULL_TREE)
 break;
   if (!tree_fits_uhwi_p (off1)
   || compare_tree_int (off1, TREE_STRING_LENGTH (str1) - 1) > 0
   || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
  - tree_to_uhwi (off1)) > 0
   || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
   || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
  != TYPE_MODE (char_type_node))
 break;

I don't think it is a good idea to let string_constant return
strings which have not necessarily valid content after the first
NUL byte.  It looks like the content has to be valid up to
TREE_STRING_LENGTH.


I'm not sure I understand when this could happen.  From the patch
below it sounds like you are concerned about cases like:

   const char a[4] = "abc\000\000";

where the STRING_CST is bigger than the array.  But the string
constant has valid content here up to TREE_STRING_LENGTH.  Am
I missing something?  (A test case would be helpful.)



No, I mean something like:

$ cat y.c
const char a[2][3] = { "1234", "xyz" };
char b[6];

int main ()
{
   __builtin_memcpy(b, a, 4);
   __builtin_memset(b + 4, 'a', 2);
   __builtin_printf("%.6s\n", b);
}
$ gcc y.c
y.c:1:24: warning: initializer-string for array of chars is too long
  const char a[2][3] = { "1234", "xyz" };
 ^~
y.c:1:24: note: (near initialization for 'a[0]')
$ ./a.out
1234aa

but expected would be "123xaa".


Hmm.  I assumed this was undefined in C but after double
checking I'm not sure.  If it's in fact valid and the excess
elements are required to be ignored I'll of course fix it in
a subsequent patch.  Let me find out.


In any case, unless the concern is specifically related to
this bug fix let's discuss it separately so I can fix this
bug.  I'm not opposed to making further changes here (in
fact, I have one in the queue and two others that I raised
in Bugzilla in response to our discussion so far), I just
want to avoid mission creep.



I think when you touch a function you should fix it completely
or restrict it to the subset that is known to be safe, and not
leave lots of already known bugs behind.


I find it preferable to open a new bug for separate problems
and tackle each on its own.  That makes it possible to track
separate bugs independently, make sure each fix is adequately
tested, and backport patches to release branches as necessary.
Wholesale changes tend to make this more difficult.

If the code in your test case is in fact well-defined then
it's especially important that a test case be added for it
because none exists yet, and opening a separate bug makes
sure this happens.

Martin


Re: [PATCH] fix a couple of bugs in const string folding (PR 86532)

2018-07-22 Thread Martin Sebor

On 07/22/2018 03:03 AM, Bernd Edlinger wrote:

On 07/21/18 01:58, Martin Sebor wrote:

On 07/20/2018 03:11 PM, Bernd Edlinger wrote:

I think I have found a valid test case where the latest patch
does generate invalid code:


This is due to another bug in string_constant() that's latent
on trunk but that's exposed by the patch.  Trunk only "works"
because of a bug/limitation in c_strlen() that the patch fixes
or removes.



I am not sure if that falls under the definition of "latent" bug.
A latent bug would be something unexpected in a completely different
area of the compiler that is triggered by an improved optimization
or a fixed bug elsewhere.


The underlying root cause is the handling of POINTER_PLUS
expressions in string_constant().  The original code (before
the handling of aggregates was added) just dealt with string
constants.  The new code does much more but doesn't get it
quite right in these cases.



I think you should be much more careful with the expressions
you evaluate in string_constant.  For instance when you look
at get_addr_base_and_unit_offset, you'll see it walks through
all kinds of type casts, VIEW_CONVERT_EXPR and MEM_REF with
nonzero displacement.  When you see something like that do
not fold that on the assumption that the source code does not
have undefined behavior.

So I'd say you should add a check that there is no type
cast in the expression you parse.  If that is the case,
your optimization will certainly be wrong.


There are no casts here.  The pointer to array case is just
something I didn't think of, that's all.  The bug is in not
rejecting those.  As I explained, the original code handled
just string literals and constant character arrays.  Current
trunk deals with all kinds of constants and doesn't get all
the constraints right.

Martin


Re: [PATCH] fix a couple of bugs in const string folding (PR 86532)

2018-07-22 Thread Martin Sebor

On 07/22/2018 04:47 PM, Martin Sebor wrote:

On 07/22/2018 02:00 AM, Bernd Edlinger wrote:

On 07/21/18 00:15, Martin Sebor wrote:

On 07/20/2018 08:51 AM, Bernd Edlinger wrote:

Martin,

when I look at tree-ssa-forwprop.c:

   str1 = string_constant (src1, &off1);
   if (str1 == NULL_TREE)
 break;
   if (!tree_fits_uhwi_p (off1)
   || compare_tree_int (off1, TREE_STRING_LENGTH
(str1) - 1) > 0
   || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
  - tree_to_uhwi (off1))
> 0
   || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
   || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
  != TYPE_MODE (char_type_node))
 break;

I don't think it is a good idea to let string_constant return
strings which have not necessarily valid content after the first
NUL byte.  It looks like the content has to be valid up to
TREE_STRING_LENGTH.


I'm not sure I understand when this could happen.  From the patch
below it sounds like you are concerned about cases like:

   const char a[4] = "abc\000\000";

where the STRING_CST is bigger than the array.  But the string
constant has valid content here up to TREE_STRING_LENGTH.  Am
I missing something?  (A test case would be helpful.)



No, I mean something like:

$ cat y.c
const char a[2][3] = { "1234", "xyz" };
char b[6];

int main ()
{
   __builtin_memcpy(b, a, 4);
   __builtin_memset(b + 4, 'a', 2);
   __builtin_printf("%.6s\n", b);
}
$ gcc y.c
y.c:1:24: warning: initializer-string for array of chars is too long
  const char a[2][3] = { "1234", "xyz" };
 ^~
y.c:1:24: note: (near initialization for 'a[0]')
$ ./a.out
1234aa

but expected would be "123xaa".


Hmm.  I assumed this was undefined in C but after double
checking I'm not sure.  If it's in fact valid and the excess
elements are required to be ignored I'll of course fix it in
a subsequent patch.  Let me find out.


The WG14 convener confirmed that this is indeed undefined.
The words that apply to this case (as well as all the others)
are in 6.7.9, p2:

  No initializer shall attempt to provide a value for an object
  not contained within the entity being initialized.

If GCC wants to make this well-defined and guarantee that
the excess elements are stripped (I'm not opposed to it)
we need to treat it should be treated as an enhancement
request, so the feature can be documented and properly
tested (I'm not opposed to it but I'm not going to champion
it either.)  Otherwise, I see no reason for a change.

Martin