Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Bernd Edlinger
On 08/21/18 04:43, Martin Sebor wrote:
>> I must say that I don't like the return value optimization
>> on the sprintf pass, because it uses knowledge of the glibc implementation
>> of sprintf to do it's job (mind the 4K buffer limit).
> 
> Yet again, you don't know what you're talking about.  The 4K
> limit is a C standard thing.
> 

BTW:

I say I don't like this or that and why.
I did not say anything about you personally.

You say something personal and generalizing about
me as reply.  That is superfluous, please stop that.


Bernd.


Re: [PATCH] Make GO string literals properly NUL terminated

2018-08-20 Thread Bernd Edlinger
On 08/20/18 17:59, Bernd Edlinger wrote:
> On 08/20/18 15:19, Richard Biener wrote:
>> On Mon, 20 Aug 2018, Bernd Edlinger wrote:
>>
>>> On 08/20/18 13:01, Richard Biener wrote:
 On Wed, Aug 1, 2018 at 3:05 PM Bernd Edlinger  
 wrote:
>
>
>
> On 08/01/18 11:29, Richard Biener wrote:
>>
>> Hmm.  I think it would be nice if TREE_STRING_LENGTH would
>> match char[2] and TYPE_SIZE_UNIT even if that is inconvenient
>> for your check above.  Because the '\0' doesn't belong to the
>> string.  Then build_string internally appends a '\0' outside
>> of TREE_STRING_LENGTH.
>>
>
> Hmm. Yes, but the outside-0 byte is just one byte, not a wide
> character.

 That could be fixed though (a wide 0 is just N 0s).  Add a elsz = 1
 parameter to build_string and allocate as many extra 0s as needed.

     There are STRING_CSTs which are not string literals,
> for instance attribute tags, Pragmas, asm constrants, etc.
> They use the '\0' outside, and have probably no TREE_TYPE.
>
>>
>>> So I would like to be able to assume that the STRING_CST objects
>>> are internally always generated properly by the front end.
>>
>> Yeah, I guess we need to define what "properly" is ;)
>>
> Yes.
>
>>> And that the ARRAY_TYPE of the string literal either has the
>>> same length than the TREE_STRING_LENGTH or if it is shorter,
>>> this is always exactly one (wide) character size less than 
>>> TREE_STRING_LENGTH
>>
>> I think it should be always the same...
>>
>
> One could not differentiate between "\0" without zero-termination
> and "" with zero-termination, theoretically.

 Is that important?  Doesn't the C standard say how to parse string 
 literals?

> We also have char x[100] = "ab";
> that is TREE_STRING_LENGTH=3, and TYPE_SIZE_UNIT(TREE_TYPE(x)) = 100.
> Of course one could create it with a TREE_STRING_LENGTH = 100,
> but imagine char x[1000] = "ab"

 The question is more about TYPE_SIZE_UNIT (TREE_TYPE ("ab")) which I
 hope matches "ab" and not 'x'.  If it matches 'x' then I'd rather have it
 unconditionally be [], thus incomplete (because the literals "size" depends
 on the context/LHS it is used on).

>>>
>>> Sorry, but I must say, it is not at all like that.
>>>
>>> If I compile x.c:
>>> const char x[100] = "ab";
>>>
>>> and set a breakpoint at output_constant:
>>>
>>> Breakpoint 1, output_constant (exp=0x76ff9dc8, size=100, align=256,
>>>   reverse=false) at ../../gcc-trunk/gcc/varasm.c:4821
>>> 4821  if (size == 0 || flag_syntax_only)
>>> (gdb) p size
>>> $1 = 100
>>> (gdb) call debug(exp)
>>> "ab"
>>> (gdb) p *exp
>>> $2 = {base = {code = STRING_CST, side_effects_flag = 0, constant_flag = 1,
>>> (gdb) p exp->typed.type->type_common.size_unit
>>> $5 = (tree) 0x76ff9d80
>>> (gdb) call debug(exp->typed.type->type_common.size_unit)
>>> 100
>>> (gdb) p exp->string.length
>>> $6 = 3
>>> (gdb) p exp->string.str[0]
>>> $8 = 97 'a'
>>> (gdb) p exp->string.str[1]
>>> $9 = 98 'b'
>>> (gdb) p exp->string.str[2]
>>> $10 = 0 '\000'
>>> (gdb) p exp->string.str[3]
>>> $11 = 0 '\000'
>>>
>>>
>>> This is an important property of string_cst objects, that is used in 
>>> c_strlen:
>>>
>>> It folds c_strlen([4]) directly to 0, because every byte beyond 
>>> TREE_STRING_LENGTH
>>> is guaranteed to be zero up to the type size.
>>>
>>> I would not have spent one thought on implementing an optimization like 
>>> that,
>>> but that's how it is right now.
>>
>> Huh.  So somebody interpreted STRING_CSTs similar to CONSTRUCTORs aka
>> they have zero-padding up to its type size.  I don't see this documented
>> anywhere and it would suggest to "optimize" "ab\0\0\0\0" to "ab\0"
>> with appropriate TYPE_SIZE.
>>
>> This is also a relatively new thing on trunk (coming out of the added
>> mem_size parameter of string_constant).  That this looks at the STRING_CST
>> type like
>>
>>    if (TREE_CODE (array) == STRING_CST)
>>  {
>>    *ptr_offset = fold_convert (sizetype, offset);
>>    if (mem_size)
>>  *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
>>    return array;
>>
>> I'd call simply a bug.  As said, interpretation of STRING_CSTs should
>> depend on the context.  And for
>>
> 
> This use of the TYPE_SIZE_UNIT was pre-existing to r263607
> before that (but not in the gcc-8-branch) we had this in c_strlen:
> 
>    HOST_WIDE_INT maxelts = strelts;
>    tree type = TREE_TYPE (src);
>    if (tree size = TYPE_SIZE_UNIT (type))
>      if (tree_fits_shwi_p (size))
>    {
>     maxelts = tree_to_uhwi (size);
>     maxelts = maxelts / eltsize - 1;
>    }
> 
> which I moved to string_constant and return the result through memsize.
> 
> It seems to be working somehow, and I'd bet removing that will immediately
> break twenty or thirty of the strlenopt tests.
> 
> Obviously the tree 

Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Bernd Edlinger
On 08/21/18 01:23, Martin Sebor wrote:
> On 08/20/2018 04:17 PM, Jeff Law wrote:
>> On 08/18/2018 11:38 AM, Martin Sebor wrote:
>>> On 08/17/2018 09:32 PM, Jeff Law wrote:
 On 08/17/2018 02:17 PM, Martin Sebor wrote:
> On 08/17/2018 12:44 PM, Bernd Edlinger wrote:
>> On 08/17/18 20:23, Martin Sebor wrote:
>>> On 08/17/2018 06:14 AM, Joseph Myers wrote:
 On Fri, 17 Aug 2018, Jeff Law wrote:

> On 08/16/2018 05:01 PM, Joseph Myers wrote:
>> On Thu, 16 Aug 2018, Jeff Law wrote:
>>
>>> restores previous behavior.  The sprintf bits want to count
>>> element
>>> sized chunks, which for wchars is 4 bytes (that count will then be
>>
>>>    /* Compute the range the argument's length can be in.  */
>>> -  fmtresult slen = get_string_length (arg);
>>> +  int count_by = dir.specifier == 'S' || dir.modifier ==
>>> FMT_LEN_l ? 4 : 1;
>>
>> I don't see how a hardcoded 4 is correct here.  Surely you need to
>> example
>> wchar_type_node to determine its actual size for this target.
> We did kick this around a little.  IIRC Martin didn't think that it
> was
> worth handling the 2 byte wchar case.
>>>
>>> Sorry, I think we may have miscommunicated -- I didn't think it
>>> was useful to pass a size of the character type to the function.
>>> I agree that passing in a hardcoded constant doesn't seem right
>>> (even if GCC's wchar_t were always 4 bytes wide).
>>>
>>> I'm still not sure I see the benefit of passing in the expected
>>> element size given that the patch causes c_strlen() fail when
>>> the actual element size doesn't match ELTSIZE.  If the caller
>>> asks for the number of bytes in a const wchar_t array it should
>>> get back the number bytes.  (I could see it fail if the caller
>>> asked for the number of words in a char array whose size was
>>> not evenly divisible by wordsize.)
>>>
>>
>> I think in this case c_strlen should use the type which the %S format
>> uses at runtime, otherwise it will not have anything to do with
>> the reality.
>
> %S is not what I'm talking about.
>
> Failing in the case I described (a caller asking for the size
> in bytes of a constant object whose type is larger) prevents
> callers that don't care about the type from detecting the actual
> size of a constant.
>
> Specifically for sprintf, it means that the buffer overflow
> below is no longer diagnosed:
>
>   struct S { char a[2]; void (*pf)(void); };
>
>   void f (struct S *p)
>   {
>     const char *q = (char*)L"\x41424344\x45464748";
>
>     sprintf (p->a, "%s", q);
>   }
 I don't think this is in the testsuite, is it?  I verified that there
 was no regressions when I installed Bernd's patch and when I installed
 yours.
>>>
>>> No, there are very few tests that exercise these kinds of mixed
>>> argument types.  Code like that is most likely the result of
>>> a mistake, but it's not the kind of a bug I had even thought
>>> about until some of the codegen issues with mixed argument types
>>> were brought up (PR 86711/86714).
>> Phew.  I was worried I'd somehow missed the failure or tested the wrong
>> patch or who knows what.
>>
>> Can you add that test, xfailed for now to the testsuite?
> 
> Done in r263676.
> 
>>> I would just like the ability to get the length/size somehow
>>> so that the questionable code that started us down this path
>>> can be detected.  This is not just the sprintf(d, "%s", L"1")
>>> kind of a mismatch but also the missing nul detection in cases
>>> like:
>> [ ... ]
>> I know.  And ideally we'll be able to handle everything you want to.
>> But we also have to realize that sometimes we may have to punt.
>>
>> Also remember that incremental progress is (usually) good.
>>
>>
>>>
>>>   const wchar_t a[1] = L"\x";
>>>   strcpy(d, (char*)a);
>> This touches on both the representational issue (excess elements in the
>> initializer) and how to handle a non-terminated string.  Both are issues
>> we're debating right now.
>>
>>>
>>> I don't think this is necessarily an important use case to
>>> optimize for but it is one that GCC optimizes already nonetheless,
>>> and always has.  For example, this has always been folded into 4
>>> by GCC and still is even with the patch:
>>>
>>>   const __WCHAR_TYPE__ wc[] = L"\x12345678";
>>>
>>>   int f (void)
>>>   {
>>>     const char *p = (char*)wc;
>>>     return strlen (p);    // folded to 4
>>>   }
>>>
>>> It's optimized because fold_const_call() relies on c_getstr()
>>> which returns the underlying byte representation of the wide
>>> string, and despite c_strlen() now trying to prevent it.
>> And I think you're hitting on some of issues already raised in the thread.
>>
>> In this specific case though ISTM 4 is the right answer. 

Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Martin Sebor

On 08/20/2018 04:22 PM, Jeff Law wrote:

On 08/20/2018 04:16 PM, Joseph Myers wrote:

On Fri, 17 Aug 2018, Jeff Law wrote:


WCHAR_TYPE_SIZE is wrong because it doesn't account for flag_short_wchar.
As far as I can see only ada/gcc-interface/targtyps.c uses WCHAR_TYPE_SIZE
now.  TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT is what should be
used.

But that's specific to the c-family front-ends.

There's MODIFIED_WCHAR_TYPE which is ultimately used to build
wchar_type_node for the c-family front-ends.  Maybe we could construct
something from that.


If you do that, probably you want to move
fortran/trans-types.c:get_typenode_from_name (which converts the strings
used in target macros such as WCHAR_TYPE to the corresponding types) into
generic code.

I think we ultimately have to go down that path.  Or we have to make the
wchar types language independent.

My initial fooling around does something like this:

  count_by = 1;
  if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
{
  tree node = get_identifier (MODIFIED_WCHAR_TYPE);
  if (node)
count_by = TYPE_PRECISION (TREE_TYPE (node)) / BITS_PER_UNIT
}

Of course, I still have to fire up tests on AIX to know if that, or a
variant using get_typenode_from_name will DTRT.


I still believe it would be simpler, more robust, and safe
to pass in a flag to either count bytes (the default, for
all callers except sprintf %ls), or elements of the string
type (for sprintf %ls).

It would restore all the strxxx optimization (early folding)
for arrays of wide characters, make it work for
sprintf(d, "%s", L"...") and any other constant character
arrays, and make it possible to detect the missing nuls by
the same functions in constant wide strings.

Martin


Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Martin Sebor

On 08/20/2018 03:31 PM, Bernd Edlinger wrote:

On 08/20/18 22:42, Martin Sebor wrote:

On 08/20/2018 09:15 AM, Bernd Edlinger wrote:

On 08/20/18 16:26, Jeff Law wrote:

On 08/20/2018 04:23 AM, Bernd Edlinger wrote:

On 08/20/18 12:12, Richard Biener wrote:

On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:


On 08/10/2018 10:56 AM, Martin Sebor wrote:

On 08/08/2018 11:36 PM, Jeff Law wrote:

On 08/02/2018 09:42 AM, Martin Sebor wrote:


The warning bits are definitely not okay by me.  The purpose
of the warnings (-W{format,sprintf}-{overflow,truncation} is
to detect buffer overflows.  When a warning doesn't have access
to string length information for dynamically created strings
(like the strlen pass does) it uses array sizes as a proxy.
This is useful both to detect possible buffer overflows and
to prevent false positives for overflows that cannot happen
in correctly written programs.

So how much of this falling-back to array sizes as a proxy would become
unnecessary if sprintf had access to the strlen pass as an analysis
module?

As you know we've been kicking that around and from my investigations
that doesn't really look hard to do.  Encapsulate the data structures in
a class, break up the statement handling into analysis and optimization
and we should be good to go.  I'm hoping to start prototyping this week.

If we think that has a reasonable chance to eliminate the array-size
fallback, then that seems like the most promising path forward.


We discussed this idea this morning so let me respond here and
reiterate the answer.  Using the strlen data will help detect
buffer overflow where the array size isn't available but it
cannot replace the array size heuristic. Here's a simple
example:

struct S { char a[8]; };

char d[8];
void f (struct S *s, int i)
{
  sprintf (d, "%s-%i",  s[i].a, i);
}

We don't know the length of s->a but we do know that it can
be up to 7 bytes long (assuming it's nul-terminated of course)
so we know the sprintf call can overflow.  Conversely, if
the size of the destination is increased to 20  the sprintf
call cannot overflow so the diagnostic can be avoided.

Removing the array size heuristic would force us to either give
up on diagnosing the first case or issue false positives for
the second case.  I think the second alternative would make
the warning too noisy to be useful.

The strlen pass will help detect buffer overflows in cases
where the array size isn't known (e.g., with dynamically
allocated buffers) but where the length of the string store
in the array is known.  It will also help avoid false positives
in cases where the string stored in an array of known size is
known to be too short to cause an overflow.  For instance here:

struct S { char a[8]; };

char d[8];
void f (struct S *s, int i)
{
  if (strlen (s->a) < 4 && i >= 0 && i < 100)
sprintf (d, "%s-%i",  s->a, i);
}

ACK.  Thanks for explaining things here too.  I can't speak for others,
but seeing examples along with the explanation is easier for me to absorb.

For Bernd and others -- after kicking things around a bit with Martin,
what we're recommending is that compute_string_length we compute the
bounds using both GIMPLE and C semantics and return both.


But you can't do this because GIMPLE did transforms that are not valid in
C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
it as GIMPLE.  What you'd do is return GIMPLE semantics length
and "foobar" semantics length which doesn't match the original source.



If I understood that suggestion right, it means, we
live with some false positive or missing warnings due to those transformations.
That means, get_range_strlen with the 2-parameter overload is used
for warnings only.  And it returns most of the time a correct range info,
that is good enough for warnings.

Correct.  99.9% of the time using the ranges implied by the array types
is better for the warning code.  So the idea is to return two ranges.
One which uses GIMPLE semantics for code generation and optimization
purposes, the other which uses ranges implied by the array types for
warning purposes.

Martin suggested that we always compute and return both rather than
having a boolean argument to select between the behavior.




Okay, but there is already the "strict" parameter:

/* Determine the minimum and maximum value or string length that ARG
refers to and store each in the first two elements of MINMAXLEN.
For expressions that point to strings of unknown lengths that are
character arrays, use the upper bound of the array as the maximum
length.  For example, given an expression like 'x ? array : "xyz"'
and array declared as 'char array[8]', MINMAXLEN[0] will be set
to 0 and MINMAXLEN[1] to 7, the longest string that could be
stored in array.
Return 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 

Re: [libiberty patch] PEX-unix forking

2018-08-20 Thread Nathan Sidwell

On 08/20/2018 05:36 PM, Ian Lance Taylor wrote:


As a matter of style I don't personally like the pattern in which a
condition has both tests and actions.  It's too easy to miss the
action.  I would prefer to see this more like the original code:

 if (!bad_fn && in != STDIN_FILE_NO)
   {
 if (close(in) < 0)
 bad_fn = "close";
   }

This is OK with those changes.


Fair enough, committing the attached.  I've elided the unnecessary braces, as 
there are no trailing elses in this case.


nathan

--
Nathan Sidwell
2018-08-20  Nathan Sidwell  

	* pex-unix.c (pex_child_error): Delete.
	(pex_unix_exec_child): Commonize error paths to single message &
	exit.

Index: pex-unix.c
===
--- pex-unix.c	(revision 263676)
+++ pex-unix.c	(working copy)
@@ -298,8 +298,6 @@ pex_wait (struct pex_obj *obj, pid_t pid
 #endif /* ! defined (HAVE_WAITPID) */
 #endif /* ! defined (HAVE_WAIT4) */
 
-static void pex_child_error (struct pex_obj *, const char *, const char *, int)
- ATTRIBUTE_NORETURN;
 static int pex_unix_open_read (struct pex_obj *, const char *, int);
 static int pex_unix_open_write (struct pex_obj *, const char *, int, int);
 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
@@ -366,28 +364,6 @@ pex_unix_close (struct pex_obj *obj ATTR
   return close (fd);
 }
 
-/* Report an error from a child process.  We don't use stdio routines,
-   because we might be here due to a vfork call.  */
-
-static void
-pex_child_error (struct pex_obj *obj, const char *executable,
-		 const char *errmsg, int err)
-{
-  int retval = 0;
-#define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0)
-  writeerr (obj->pname);
-  writeerr (": error trying to exec '");
-  writeerr (executable);
-  writeerr ("': ");
-  writeerr (errmsg);
-  writeerr (": ");
-  writeerr (xstrerror (err));
-  writeerr ("\n");
-#undef writeerr
-  /* Exit with -2 if the error output failed, too.  */
-  _exit (retval == 0 ? -1 : -2);
-}
-
 /* Execute a child.  */
 
 #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE)
@@ -592,21 +568,22 @@ pex_unix_exec_child (struct pex_obj *obj
  int in, int out, int errdes,
 		 int toclose, const char **errmsg, int *err)
 {
-  pid_t pid;
+  pid_t pid = -1;
 
   /* We declare these to be volatile to avoid warnings from gcc about
  them being clobbered by vfork.  */
-  volatile int sleep_interval;
+  volatile int sleep_interval = 1;
   volatile int retries;
 
   /* We vfork and then set environ in the child before calling execvp.
  This clobbers the parent's environ so we need to restore it.
  It would be nice to use one of the exec* functions that takes an
- environment as a parameter, but that may have portability issues.  */
+ environment as a parameter, but that may have portability
+ issues.   */
   char **save_environ = environ;
 
-  sleep_interval = 1;
-  pid = -1;
+  const char *bad_fn = NULL;
+
   for (retries = 0; retries < 4; ++retries)
 {
   pid = vfork ();
@@ -625,57 +602,76 @@ pex_unix_exec_child (struct pex_obj *obj
 
 case 0:
   /* Child process.  */
-  if (in != STDIN_FILE_NO)
+  if (!bad_fn && in != STDIN_FILE_NO)
 	{
 	  if (dup2 (in, STDIN_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
-	  if (close (in) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "dup2";
+	  else if (close (in) < 0)
+	bad_fn = "close";
 	}
-  if (out != STDOUT_FILE_NO)
+  if (!bad_fn && out != STDOUT_FILE_NO)
 	{
 	  if (dup2 (out, STDOUT_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
-	  if (close (out) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "dup2";
+	  else if (close (out) < 0)
+	bad_fn = "close";
 	}
-  if (errdes != STDERR_FILE_NO)
+  if (!bad_fn && errdes != STDERR_FILE_NO)
 	{
 	  if (dup2 (errdes, STDERR_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
-	  if (close (errdes) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "dup2";
+	  else if (close (errdes) < 0)
+	bad_fn = "close";
 	}
-  if (toclose >= 0)
+  if (!bad_fn && toclose >= 0)
 	{
 	  if (close (toclose) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "close";
 	}
-  if ((flags & PEX_STDERR_TO_STDOUT) != 0)
+  if (!bad_fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
 	{
 	  if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
+	bad_fn = "dup2";
 	}
-
-  if (env)
+  if (!bad_fn)
 	{
-	  /* NOTE: In a standard vfork implementation this clobbers the
-	 parent's copy of environ "too" (in reality there's only one copy).
-	 This is ok as we restore it below.  */
-	  environ = (char**) env;
+	  if (env)
+	/* NOTE: In a standard vfork implementation this clobbers
+	   

Re: C++ PATCH for c++/86981, implement -Wpessimizing-move

2018-08-20 Thread David Malcolm
On Mon, 2018-08-20 at 18:54 -0400, Marek Polacek wrote:
> On Mon, Aug 20, 2018 at 05:18:49PM -0400, David Malcolm wrote:
> > As of r263675 it's now possible to tell the diagnostics subsystem
> > that
> > the warning and note are related by using an auto_diagnostic_group
> > instance [1], so please can this read:
> > 
> >   if (can_do_nrvo_p (arg, functype))
> > {
> >   auto_diagnostic_group d;
> >   if (warning (OPT_Wpessimizing_move, "moving a local
> > object "
> >"in a return statement prevents copy
> > elision"))
> > inform (input_location, "remove %
> > call");
> > }
> 
> Sure:
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

Thanks!  The changed part looks good, but I can't really speak to the
rest of the patch.

(BTW, could we emit a fix-it hint as part of that "inform" call?  How
good is the location information at this point?)

> 2018-08-20  Marek Polacek  
> 
>   PR c++/86981, Implement -Wpessimizing-move.
>   * c.opt (Wpessimizing-move): New option.
> 
>   * typeck.c (decl_in_std_namespace_p): New.
>   (is_std_move_p): New.
>   (can_do_nrvo_p): New, factored out of ...
>   (check_return_expr): ... here.  Warn about potentially harmful
>   std::move in a return statement.
> 
>   * doc/invoke.texi: Document -Wpessimizing-move.
> 
>   * g++.dg/cpp0x/Wpessimizing-move1.C: New test.
>   * g++.dg/cpp0x/Wpessimizing-move2.C: New test.
>   * g++.dg/cpp0x/Wpessimizing-move3.C: New test.
>   * g++.dg/cpp0x/Wpessimizing-move4.C: New test.
>   * g++.dg/cpp1z/Wpessimizing-move1.C: New test.
> 
> diff --git gcc/c-family/c.opt gcc/c-family/c.opt
> index 9980bfac11c..76840dd77ad 100644
> --- gcc/c-family/c.opt
> +++ gcc/c-family/c.opt
> @@ -937,6 +937,10 @@ Wpedantic
>  C ObjC C++ ObjC++ CPP(cpp_pedantic) CppReason(CPP_W_PEDANTIC)
> Warning
>  ; Documented in common.opt
>  
> +Wpessimizing-move
> +C++ ObjC++ Var(warn_pessimizing_move) Warning LangEnabledBy(C++
> ObjC++, Wall)
> +Warn about calling std::move on a local object in a return statement
> preventing copy elision.
> +
>  Wpmf-conversions
>  C++ ObjC++ Var(warn_pmf2ptr) Init(1) Warning
>  Warn when converting the type of pointers to member functions.
> diff --git gcc/cp/typeck.c gcc/cp/typeck.c
> index 8c13ae9b19b..5fe47299772 100644
> --- gcc/cp/typeck.c
> +++ gcc/cp/typeck.c
> @@ -9113,6 +9113,58 @@ maybe_warn_about_returning_address_of_local
> (tree retval)
>return false;
>  }
>  
> +/* Returns true if DECL is in the std namespace.  */
> +
> +static bool
> +decl_in_std_namespace_p (tree decl)
> +{
> +  return (decl != NULL_TREE
> +   && DECL_NAMESPACE_STD_P (decl_namespace_context (decl)));
> +}
> +
> +/* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
> +
> +static bool
> +is_std_move_p (tree fn)
> +{
> +  /* std::move only takes one argument.  */
> +  if (call_expr_nargs (fn) != 1)
> +return false;
> +
> +  tree fndecl = cp_get_callee_fndecl_nofold (fn);
> +  if (!decl_in_std_namespace_p (fndecl))
> +return false;
> +
> +  tree name = DECL_NAME (fndecl);
> +  return name && id_equal (name, "move");
> +}
> +
> +/* Returns true if RETVAL is a good candidate for the NRVO as per
> +   [class.copy.elision].  FUNCTYPE is the type the function is
> declared
> +   to return.  */
> +
> +static bool
> +can_do_nrvo_p (tree retval, tree functype)
> +{
> +  tree result = DECL_RESULT (current_function_decl);
> +  return (retval != NULL_TREE
> +   && !processing_template_decl
> +   /* Must be a local, automatic variable.  */
> +   && VAR_P (retval)
> +   && DECL_CONTEXT (retval) == current_function_decl
> +   && !TREE_STATIC (retval)
> +   /* And not a lambda or anonymous union proxy.  */
> +   && !DECL_HAS_VALUE_EXPR_P (retval)
> +   && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
> +   /* The cv-unqualified type of the returned value must be
> the
> +  same as the cv-unqualified return type of the
> +  function.  */
> +   && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
> +   (TYPE_MAIN_VARIANT (functype)))
> +   /* And the returned value must be non-volatile.  */
> +   && !TYPE_VOLATILE (TREE_TYPE (retval)));
> +}
> +
>  /* Check that returning RETVAL from the current function is valid.
> Return an expression explicitly showing all conversions required
> to
> change RETVAL into the function return type, and to assign it to
> @@ -9130,7 +9182,6 @@ check_return_expr (tree retval, bool
> *no_warning)
>   the declared type is incomplete.  */
>tree functype;
>int fn_returns_value_p;
> -  bool named_return_value_okay_p;
>  
>*no_warning = false;
>  
> @@ -9342,24 +9393,7 @@ check_return_expr (tree retval, bool
> *no_warning)
>  
>   See finish_function and finalize_nrv for the rest of this
> optimization.  */
>  
> -  named_return_value_okay_p = 
> -

[PATCH] fix some build breakage

2018-08-20 Thread Nathan Sidwell
Jeff alerted me to some build breakage on s390 and spu targets.  He's confirmed 
this patch unbreaks s390, so I expect spu is also good.  Committing to trunk.


Sorry for not deploying grep earlier.

nathan.
--
Nathan Sidwell
2018-08-20  Nathan Sidwell  
	Jeff Law 

	* config/s390/s390-c (s390_macro_to_expand): Use cpp_macro_p.
	* config/spu/spu-c.c (spu_macro_to_expand): Likewise.

Index: s390/s390-c.c
===
--- s390/s390-c.c	(revision 263673)
+++ s390/s390-c.c	(working copy)
@@ -233,7 +233,7 @@ s390_macro_to_expand (cpp_reader *pfile,
 
   rid_code = (enum rid)(ident->rid_code);
 
-  if (ident->type == NT_MACRO)
+  if (cpp_macro_p (ident))
 {
   /* Now actually fetch the tokens we "peeked" before and do a
 	 lookahead for the next.  */
Index: spu/spu-c.c
===
--- spu/spu-c.c	(revision 263673)
+++ spu/spu-c.c	(working copy)
@@ -64,7 +64,7 @@ spu_macro_to_expand (cpp_reader *pfile,
   if (ident)
 	{
 	  enum rid rid_code = (enum rid)(ident->rid_code);
-	  if (ident->type == NT_MACRO)
+	  if (cpp_macro_p (ident))
 	{
 	  (void) cpp_get_token (pfile);
 	  tok = cpp_peek_token (pfile, 0);


Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Martin Sebor

On 08/20/2018 04:17 PM, Jeff Law wrote:

On 08/18/2018 11:38 AM, Martin Sebor wrote:

On 08/17/2018 09:32 PM, Jeff Law wrote:

On 08/17/2018 02:17 PM, Martin Sebor wrote:

On 08/17/2018 12:44 PM, Bernd Edlinger wrote:

On 08/17/18 20:23, Martin Sebor wrote:

On 08/17/2018 06:14 AM, Joseph Myers wrote:

On Fri, 17 Aug 2018, Jeff Law wrote:


On 08/16/2018 05:01 PM, Joseph Myers wrote:

On Thu, 16 Aug 2018, Jeff Law wrote:


restores previous behavior.  The sprintf bits want to count
element
sized chunks, which for wchars is 4 bytes (that count will then be



   /* Compute the range the argument's length can be in.  */
-  fmtresult slen = get_string_length (arg);
+  int count_by = dir.specifier == 'S' || dir.modifier ==
FMT_LEN_l ? 4 : 1;


I don't see how a hardcoded 4 is correct here.  Surely you need to
example
wchar_type_node to determine its actual size for this target.

We did kick this around a little.  IIRC Martin didn't think that it
was
worth handling the 2 byte wchar case.


Sorry, I think we may have miscommunicated -- I didn't think it
was useful to pass a size of the character type to the function.
I agree that passing in a hardcoded constant doesn't seem right
(even if GCC's wchar_t were always 4 bytes wide).

I'm still not sure I see the benefit of passing in the expected
element size given that the patch causes c_strlen() fail when
the actual element size doesn't match ELTSIZE.  If the caller
asks for the number of bytes in a const wchar_t array it should
get back the number bytes.  (I could see it fail if the caller
asked for the number of words in a char array whose size was
not evenly divisible by wordsize.)



I think in this case c_strlen should use the type which the %S format
uses at runtime, otherwise it will not have anything to do with
the reality.


%S is not what I'm talking about.

Failing in the case I described (a caller asking for the size
in bytes of a constant object whose type is larger) prevents
callers that don't care about the type from detecting the actual
size of a constant.

Specifically for sprintf, it means that the buffer overflow
below is no longer diagnosed:

  struct S { char a[2]; void (*pf)(void); };

  void f (struct S *p)
  {
const char *q = (char*)L"\x41424344\x45464748";

sprintf (p->a, "%s", q);
  }

I don't think this is in the testsuite, is it?  I verified that there
was no regressions when I installed Bernd's patch and when I installed
yours.


No, there are very few tests that exercise these kinds of mixed
argument types.  Code like that is most likely the result of
a mistake, but it's not the kind of a bug I had even thought
about until some of the codegen issues with mixed argument types
were brought up (PR 86711/86714).

Phew.  I was worried I'd somehow missed the failure or tested the wrong
patch or who knows what.

Can you add that test, xfailed for now to the testsuite?


Done in r263676.


I would just like the ability to get the length/size somehow
so that the questionable code that started us down this path
can be detected.  This is not just the sprintf(d, "%s", L"1")
kind of a mismatch but also the missing nul detection in cases
like:

[ ... ]
I know.  And ideally we'll be able to handle everything you want to.
But we also have to realize that sometimes we may have to punt.

Also remember that incremental progress is (usually) good.




  const wchar_t a[1] = L"\x";
  strcpy(d, (char*)a);

This touches on both the representational issue (excess elements in the
initializer) and how to handle a non-terminated string.  Both are issues
we're debating right now.



I don't think this is necessarily an important use case to
optimize for but it is one that GCC optimizes already nonetheless,
and always has.  For example, this has always been folded into 4
by GCC and still is even with the patch:

  const __WCHAR_TYPE__ wc[] = L"\x12345678";

  int f (void)
  {
const char *p = (char*)wc;
return strlen (p);// folded to 4
  }

It's optimized because fold_const_call() relies on c_getstr()
which returns the underlying byte representation of the wide
string, and despite c_strlen() now trying to prevent it.

And I think you're hitting on some of issues already raised in the thread.

In this specific case though ISTM 4 is the right answer.  We casted to a
char *, so that's what we should be counting.  Or am I missing
something?  Also note that's the value we'd get from the strlen C
library call IIUC.


It is the right answer.  My point is that this is optimized
but the change to c_strlen() prevents the same optimization
in other similar cases.  For example, GCC 6 folds this into
memcpy:

  __builtin_strcpy (d, (char*)L"\x12345678");

GCC 7 and 8 do too but get the byte count wrong (my bad).

Current trunk doesn't optimize it.  If restoring the original
behavior is the intent (and not just fixing the counting bug)
then c_strlen() should be fixed to fold this again.

(I'm not a fan of the strcpy to memcpy transformation 

Re: [PATCH], PR target/87033, General LWAX on PowerPC

2018-08-20 Thread Segher Boessenkool
On Mon, Aug 20, 2018 at 06:45:37PM -0400, Michael Meissner wrote:
> In this patch earlier to improve switch behavior:
> https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01957.html
> 
> I noticed that the compiler wasn't generating the LWAX instruction.  I tracked
> this down to the "extendsi2" insn using the "Y" constraint when it can
> optimize a load + sign extend into a single load with sign extend.  The "Y"
> constraint is for DS-form offsettable addresses, and does not allow indexed
> addresses (i.e. X-form loads).  This patch adds the "Z" constraint as well,
> which allows indexed addresses.

This is okay for trunk, and for backports too.  Thanks!


> +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */

Maybe add a comment on why lp64 is needed here, it took me a minute :-)


Segher


Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Bernd Edlinger
On 08/18/18 20:01, Martin Sebor wrote:
> On 08/17/2018 05:01 PM, Bernd Edlinger wrote:
>> On 08/17/18 22:17, Martin Sebor wrote:
>>> On 08/17/2018 12:44 PM, Bernd Edlinger wrote:
 On 08/17/18 20:23, Martin Sebor wrote:
> On 08/17/2018 06:14 AM, Joseph Myers wrote:
>> On Fri, 17 Aug 2018, Jeff Law wrote:
>>
>>> On 08/16/2018 05:01 PM, Joseph Myers wrote:
 On Thu, 16 Aug 2018, Jeff Law wrote:

> restores previous behavior.  The sprintf bits want to count element
> sized chunks, which for wchars is 4 bytes (that count will then be

>    /* Compute the range the argument's length can be in.  */
> -  fmtresult slen = get_string_length (arg);
> +  int count_by = dir.specifier == 'S' || dir.modifier == FMT_LEN_l ? 
> 4 : 1;

 I don't see how a hardcoded 4 is correct here.  Surely you need to 
 example
 wchar_type_node to determine its actual size for this target.
>>> We did kick this around a little.  IIRC Martin didn't think that it was
>>> worth handling the 2 byte wchar case.
>
> Sorry, I think we may have miscommunicated -- I didn't think it
> was useful to pass a size of the character type to the function.
> I agree that passing in a hardcoded constant doesn't seem right
> (even if GCC's wchar_t were always 4 bytes wide).
>
> I'm still not sure I see the benefit of passing in the expected
> element size given that the patch causes c_strlen() fail when
> the actual element size doesn't match ELTSIZE.  If the caller
> asks for the number of bytes in a const wchar_t array it should
> get back the number bytes.  (I could see it fail if the caller
> asked for the number of words in a char array whose size was
> not evenly divisible by wordsize.)
>

 I think in this case c_strlen should use the type which the %S format
 uses at runtime, otherwise it will not have anything to do with
 the reality.
>>>
>>> %S is not what I'm talking about.
>>>
>>> Failing in the case I described (a caller asking for the size
>>> in bytes of a constant object whose type is larger) prevents
>>> callers that don't care about the type from detecting the actual
>>> size of a constant.
>>>
>>> Specifically for sprintf, it means that the buffer overflow
>>> below is no longer diagnosed:
>>>
>>>    struct S { char a[2]; void (*pf)(void); };
>>>
>>>    void f (struct S *p)
>>>    {
>>>  const char *q = (char*)L"\x41424344\x45464748";
>>>
>>>  sprintf (p->a, "%s", q);
>>>    }
>>>
>>> There may be no other analyses that would benefit from this
>>> ability today but there easily could be.  There certainly
>>> are optimizations that depend on c_getstr() returning
>>> a pointer to the constant object regardless of its type
>>> (memchr being one of them).
>>>
>>
>> Yes, I agree.
>>
>> Coincidentally that is exactly what in my follow-up patch implements.
>> See: https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01005.html
>>
>> If you call c_getstr(x) you get a valid zero-terminated single-byte
>> string or nothing.
>>
>> If you call c_getstr(x, ) you get a pointer to a memory
>> of the specified memsize, regardless of the underlying type.
>> and whether or not zero terminated.
> 
> Most functions in GCC call c_strlen() at some point to determine
> the length of a string.  They need to be able to detect the missing
> nul -- it would double the amount of processing to have them also
> call c_getstr() when c_strlen() fails to see if the failure happens
> to be due to a missing nul -- it the overwhelming majority of cases
> it won't be.
> 

Well, yes, if the c_strlen function fails, it would be cheap to have some
error code for the failure reason.

But that is something for later.


Bernd.


Re: [PATCH][Middle-end]patch for fixing PR 86519

2018-08-20 Thread Qing Zhao
Hi, Paul,

I was trying to repeat this issue on a mips machine today, but failed…

the only mips machines I can access are those in gcc compile farm, I chose 
gcc22, but failed to build GCC on this machine.

do you know any other machine in gcc compile farm that can repeat this issue?

thanks a lot.

Qing
> On Aug 17, 2018, at 10:43 PM, Paul Hua  wrote:
> 
> Hi Qing:
> 
>> 
>> the change has been committed as:
>> https://gcc.gnu.org/viewcvs/gcc?view=revision=263563 
>> 
>> 
>> Qing
>> 
> 
> The strcmpopt_6.c test still fails on mips64el target.
> 
> gcc.dg/strcmpopt_6.c: memcmp found 4 times
> FAIL: gcc.dg/strcmpopt_6.c scan-assembler-times memcmp 2
> 
> 
> The mips asm output have ".reloc" info.
> 
> -
>ld  $5,%got_page(.LC0)($28)
>ld  $25,%call16(memcmp)($28)
>li  $6,3# 0x3
>sd  $31,8($sp)
>.reloc  1f,R_MIPS_JALR,memcmp
> 1:  jalr$25
>daddiu  $5,$5,%got_ofst(.LC0)
> 
> 
> scan-assembler find "4" times.
> 
> Thanks
> Paul Hua



Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Bernd Edlinger
On 08/21/18 00:49, Joseph Myers wrote:
> On Mon, 20 Aug 2018, Jeff Law wrote:
> 
>>> If you do that, probably you want to move
>>> fortran/trans-types.c:get_typenode_from_name (which converts the strings
>>> used in target macros such as WCHAR_TYPE to the corresponding types) into
>>> generic code.
>> I think we ultimately have to go down that path.  Or we have to make the
>> wchar types language independent.
>>
>> My initial fooling around does something like this:
>>
>>count_by = 1;
>>if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
>>  {
>>tree node = get_identifier (MODIFIED_WCHAR_TYPE);
> 
> I expect this get_identifier use may only work properly in C-family
> languages.
> 

If that type is not available, you can set count_b = 0, then c_strlen will
not return wrong information.
For other languages that is certainly good enough.


> (There's another version of that get_typenode_from_name logic in
> tree.c:build_common_tree_nodes for SIZE_TYPE and PTRDIFF_TYPE, which only
> considers types of the right signedness in those cases, but does handle
> __intN types.)
> 


Re: C++ PATCH for c++/86981, implement -Wpessimizing-move

2018-08-20 Thread Marek Polacek
On Mon, Aug 20, 2018 at 05:18:49PM -0400, David Malcolm wrote:
> As of r263675 it's now possible to tell the diagnostics subsystem that
> the warning and note are related by using an auto_diagnostic_group
> instance [1], so please can this read:
> 
>   if (can_do_nrvo_p (arg, functype))
> {
>   auto_diagnostic_group d;
>   if (warning (OPT_Wpessimizing_move, "moving a local object "
>"in a return statement prevents copy elision"))
> inform (input_location, "remove % call");
> }

Sure:

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-08-20  Marek Polacek  

PR c++/86981, Implement -Wpessimizing-move.
* c.opt (Wpessimizing-move): New option.

* typeck.c (decl_in_std_namespace_p): New.
(is_std_move_p): New.
(can_do_nrvo_p): New, factored out of ...
(check_return_expr): ... here.  Warn about potentially harmful
std::move in a return statement.

* doc/invoke.texi: Document -Wpessimizing-move.

* g++.dg/cpp0x/Wpessimizing-move1.C: New test.
* g++.dg/cpp0x/Wpessimizing-move2.C: New test.
* g++.dg/cpp0x/Wpessimizing-move3.C: New test.
* g++.dg/cpp0x/Wpessimizing-move4.C: New test.
* g++.dg/cpp1z/Wpessimizing-move1.C: New test.

diff --git gcc/c-family/c.opt gcc/c-family/c.opt
index 9980bfac11c..76840dd77ad 100644
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -937,6 +937,10 @@ Wpedantic
 C ObjC C++ ObjC++ CPP(cpp_pedantic) CppReason(CPP_W_PEDANTIC) Warning
 ; Documented in common.opt
 
+Wpessimizing-move
+C++ ObjC++ Var(warn_pessimizing_move) Warning LangEnabledBy(C++ ObjC++, Wall)
+Warn about calling std::move on a local object in a return statement 
preventing copy elision.
+
 Wpmf-conversions
 C++ ObjC++ Var(warn_pmf2ptr) Init(1) Warning
 Warn when converting the type of pointers to member functions.
diff --git gcc/cp/typeck.c gcc/cp/typeck.c
index 8c13ae9b19b..5fe47299772 100644
--- gcc/cp/typeck.c
+++ gcc/cp/typeck.c
@@ -9113,6 +9113,58 @@ maybe_warn_about_returning_address_of_local (tree retval)
   return false;
 }
 
+/* Returns true if DECL is in the std namespace.  */
+
+static bool
+decl_in_std_namespace_p (tree decl)
+{
+  return (decl != NULL_TREE
+ && DECL_NAMESPACE_STD_P (decl_namespace_context (decl)));
+}
+
+/* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
+
+static bool
+is_std_move_p (tree fn)
+{
+  /* std::move only takes one argument.  */
+  if (call_expr_nargs (fn) != 1)
+return false;
+
+  tree fndecl = cp_get_callee_fndecl_nofold (fn);
+  if (!decl_in_std_namespace_p (fndecl))
+return false;
+
+  tree name = DECL_NAME (fndecl);
+  return name && id_equal (name, "move");
+}
+
+/* Returns true if RETVAL is a good candidate for the NRVO as per
+   [class.copy.elision].  FUNCTYPE is the type the function is declared
+   to return.  */
+
+static bool
+can_do_nrvo_p (tree retval, tree functype)
+{
+  tree result = DECL_RESULT (current_function_decl);
+  return (retval != NULL_TREE
+ && !processing_template_decl
+ /* Must be a local, automatic variable.  */
+ && VAR_P (retval)
+ && DECL_CONTEXT (retval) == current_function_decl
+ && !TREE_STATIC (retval)
+ /* And not a lambda or anonymous union proxy.  */
+ && !DECL_HAS_VALUE_EXPR_P (retval)
+ && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
+ /* The cv-unqualified type of the returned value must be the
+same as the cv-unqualified return type of the
+function.  */
+ && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
+ (TYPE_MAIN_VARIANT (functype)))
+ /* And the returned value must be non-volatile.  */
+ && !TYPE_VOLATILE (TREE_TYPE (retval)));
+}
+
 /* Check that returning RETVAL from the current function is valid.
Return an expression explicitly showing all conversions required to
change RETVAL into the function return type, and to assign it to
@@ -9130,7 +9182,6 @@ check_return_expr (tree retval, bool *no_warning)
  the declared type is incomplete.  */
   tree functype;
   int fn_returns_value_p;
-  bool named_return_value_okay_p;
 
   *no_warning = false;
 
@@ -9342,24 +9393,7 @@ check_return_expr (tree retval, bool *no_warning)
 
  See finish_function and finalize_nrv for the rest of this optimization.  
*/
 
-  named_return_value_okay_p = 
-(retval != NULL_TREE
- && !processing_template_decl
- /* Must be a local, automatic variable.  */
- && VAR_P (retval)
- && DECL_CONTEXT (retval) == current_function_decl
- && ! TREE_STATIC (retval)
- /* And not a lambda or anonymous union proxy.  */
- && !DECL_HAS_VALUE_EXPR_P (retval)
- && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
- /* The cv-unqualified type of the returned value must be the
-same as the cv-unqualified return type of the
-

[PATCH] Use c_getstr to get the format string in gimple-ssa-sprintf.c

2018-08-20 Thread Bernd Edlinger
Hi,


this simplifies get_format_string in gimple-ssa-sprintf.c
to use c_getstr.


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


Thanks
Bernd.
2018-08-21  Bernd Edlinger  

	* gimple-ssa-sprintf.c (decl_constant_value): Remove.
	(get_format_string): Refer to c_getstr.

diff -Npur gcc/gimple-ssa-sprintf.c gcc/gimple-ssa-sprintf.c
--- gcc/gimple-ssa-sprintf.c	2018-08-17 06:01:14.0 +0200
+++ gcc/gimple-ssa-sprintf.c	2018-08-20 22:54:08.724679430 +0200
@@ -443,152 +443,15 @@ target_strtol10 (const char **ps, const
   return val;
 }
 
-/* Return the constant initial value of DECL if available or DECL
-   otherwise.  Same as the synonymous function in c/c-typeck.c.  */
-
-static tree
-decl_constant_value (tree decl)
-{
-  if (/* Don't change a variable array bound or initial value to a constant
-	 in a place where a variable is invalid.  Note that DECL_INITIAL
-	 isn't valid for a PARM_DECL.  */
-  current_function_decl != 0
-  && TREE_CODE (decl) != PARM_DECL
-  && !TREE_THIS_VOLATILE (decl)
-  && TREE_READONLY (decl)
-  && DECL_INITIAL (decl) != 0
-  && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
-  /* This is invalid if initial value is not constant.
-	 If it has either a function call, a memory reference,
-	 or a variable, then re-evaluating it could give different results.  */
-  && TREE_CONSTANT (DECL_INITIAL (decl))
-  /* Check for cases where this is sub-optimal, even though valid.  */
-  && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
-return DECL_INITIAL (decl);
-  return decl;
-}
-
 /* Given FORMAT, set *PLOC to the source location of the format string
and return the format string if it is known or null otherwise.  */
 
 static const char*
 get_format_string (tree format, location_t *ploc)
 {
-  if (VAR_P (format))
-{
-  /* Pull out a constant value if the front end didn't.  */
-  format = decl_constant_value (format);
-  STRIP_NOPS (format);
-}
-
-  if (integer_zerop (format))
-{
-  /* FIXME: Diagnose null format string if it hasn't been diagnosed
-	 by -Wformat (the latter diagnoses only nul pointer constants,
-	 this pass can do better).  */
-  return NULL;
-}
-
-  HOST_WIDE_INT offset = 0;
-
-  if (TREE_CODE (format) == POINTER_PLUS_EXPR)
-{
-  tree arg0 = TREE_OPERAND (format, 0);
-  tree arg1 = TREE_OPERAND (format, 1);
-  STRIP_NOPS (arg0);
-  STRIP_NOPS (arg1);
-
-  if (TREE_CODE (arg1) != INTEGER_CST)
-	return NULL;
-
-  format = arg0;
-
-  /* POINTER_PLUS_EXPR offsets are to be interpreted signed.  */
-  if (!cst_and_fits_in_hwi (arg1))
-	return NULL;
-
-  offset = int_cst_value (arg1);
-}
-
-  if (TREE_CODE (format) != ADDR_EXPR)
-return NULL;
-
   *ploc = EXPR_LOC_OR_LOC (format, input_location);
 
-  format = TREE_OPERAND (format, 0);
-
-  if (TREE_CODE (format) == ARRAY_REF
-  && tree_fits_shwi_p (TREE_OPERAND (format, 1))
-  && (offset += tree_to_shwi (TREE_OPERAND (format, 1))) >= 0)
-format = TREE_OPERAND (format, 0);
-
-  if (offset < 0)
-return NULL;
-
-  tree array_init;
-  tree array_size = NULL_TREE;
-
-  if (VAR_P (format)
-  && TREE_CODE (TREE_TYPE (format)) == ARRAY_TYPE
-  && (array_init = decl_constant_value (format)) != format
-  && TREE_CODE (array_init) == STRING_CST)
-{
-  /* Extract the string constant initializer.  Note that this may
-	 include a trailing NUL character that is not in the array (e.g.
-	 const char a[3] = "foo";).  */
-  array_size = DECL_SIZE_UNIT (format);
-  format = array_init;
-}
-
-  if (TREE_CODE (format) != STRING_CST)
-return NULL;
-
-  tree type = TREE_TYPE (format);
-
-  scalar_int_mode char_mode;
-  if (!is_int_mode (TYPE_MODE (TREE_TYPE (type)), _mode)
-  || GET_MODE_SIZE (char_mode) != 1)
-{
-  /* Wide format string.  */
-  return NULL;
-}
-
-  const char *fmtstr = TREE_STRING_POINTER (format);
-  unsigned fmtlen = TREE_STRING_LENGTH (format);
-
-  if (array_size)
-{
-  /* Variable length arrays can't be initialized.  */
-  gcc_assert (TREE_CODE (array_size) == INTEGER_CST);
-
-  if (tree_fits_shwi_p (array_size))
-	{
-	  HOST_WIDE_INT array_size_value = tree_to_shwi (array_size);
-	  if (array_size_value > 0
-	  && array_size_value == (int) array_size_value
-	  && fmtlen > array_size_value)
-	fmtlen = array_size_value;
-	}
-}
-  if (offset)
-{
-  if (offset >= fmtlen)
-	return NULL;
-
-  fmtstr += offset;
-  fmtlen -= offset;
-}
-
-  if (fmtlen < 1 || fmtstr[--fmtlen] != 0)
-{
-  /* FIXME: Diagnose an unterminated format string if it hasn't been
-	 diagnosed by -Wformat.  Similarly to a null format pointer,
-	 -Wformay diagnoses only nul pointer constants, this pass can
-	 do better).  */
-  return NULL;
-}
-
-  return fmtstr;
+  return c_getstr (format);
 }
 
 /* For convenience and brevity, shorter named entrypoints of


Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Joseph Myers
On Mon, 20 Aug 2018, Jeff Law wrote:

> > If you do that, probably you want to move 
> > fortran/trans-types.c:get_typenode_from_name (which converts the strings 
> > used in target macros such as WCHAR_TYPE to the corresponding types) into 
> > generic code.
> I think we ultimately have to go down that path.  Or we have to make the
> wchar types language independent.
> 
> My initial fooling around does something like this:
> 
>   count_by = 1;
>   if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
> {
>   tree node = get_identifier (MODIFIED_WCHAR_TYPE);

I expect this get_identifier use may only work properly in C-family 
languages.

(There's another version of that get_typenode_from_name logic in 
tree.c:build_common_tree_nodes for SIZE_TYPE and PTRDIFF_TYPE, which only 
considers types of the right signedness in those cases, but does handle 
__intN types.)

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH], PR target/87033, General LWAX on PowerPC

2018-08-20 Thread Michael Meissner
In this patch earlier to improve switch behavior:
https://gcc.gnu.org/ml/gcc-patches/2018-07/msg01957.html

I noticed that the compiler wasn't generating the LWAX instruction.  I tracked
this down to the "extendsi2" insn using the "Y" constraint when it can
optimize a load + sign extend into a single load with sign extend.  The "Y"
constraint is for DS-form offsettable addresses, and does not allow indexed
addresses (i.e. X-form loads).  This patch adds the "Z" constraint as well,
which allows indexed addresses.

I have down trunk builds with/without this patch and there were no regressions.
Can I apply this patch to the trunk?  Can I backport this patch to GCC 7 and
GCC 8 as well with a suitable delay to catch any problems?

[gcc]
2018-08-20  Michael Meissner  

PR target/87033
* config/rs6000/rs6000.md (extendsi2): Change constraints
from 'Y' to 'YZ' to enable the LWAX instruction to be generated
for indexed loads.

[gcc/testsuite]
2018-08-20  Michael Meissner  

PR target/87033
* gcc.target/powerpc/pr87033.c: New test.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797
Index: gcc/config/rs6000/rs6000.md
===
--- gcc/config/rs6000/rs6000.md (revision 263672)
+++ gcc/config/rs6000/rs6000.md (working copy)
@@ -988,7 +988,7 @@ (define_insn "extendsi2"
 "=r, r,   wl,wu,wj,wK, wH,wr")
 
(sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
-"Y,  r,   Z, Z, r, wK, wH,?wIwH")))]
+"YZ, r,   Z, Z, r, wK, wH,?wIwH")))]
   ""
   "@
lwa%U1%X1 %0,%1
Index: gcc/testsuite/gcc.target/powerpc/pr87033.c
===
--- gcc/testsuite/gcc.target/powerpc/pr87033.c  (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr87033.c  (working copy)
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-options "-O2" } */
+
+/* Insure that a LWAX is generated instead of ADD + LWA.  */
+long func (int *p, unsigned long n)
+{
+  return p[n];
+}
+
+/* { dg-final { scan-assembler {\mlwax\M} } } */
+/* { dg-final { scan-assembler-not {\mlwa\M}  } } */


Re: VRP: abstract out MIN/MAX/ABS wide int code

2018-08-20 Thread Jeff Law
On 08/17/2018 01:11 AM, Aldy Hernandez wrote:
> No change in functionality, just a straight up conversion.
> 
> OK for trunk?
> 
> curr.patch
> 
> 
> gcc/
> 
>   * wide-int-range.cc (wide_int_range_abs): New.
>   (wide_int_range_order_set): Rename from wide_int_range_min_max.
>   * wide-int-range.h (wide_int_range_abs): New.
>   (wide_int_range_min_max): New.
>   * tree-vrp.c (extract_range_from_unary_expr): Rewrite ABS_EXPR
>   case to call wide_int_range_abs.
>   Rewrite MIN/MAX_EXPR to call wide_int_range_min_max.
>   (extract_range_from_abs_expr): Delete.
OK.  It was a bit hard to follow because parts of the original
implementation were split and handled in different places.  But AFAICT
it looks like everything got transferred to their new locations.

jeff


Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Bernd Edlinger
On 08/21/18 00:22, Jeff Law wrote:
> On 08/20/2018 04:16 PM, Joseph Myers wrote:
>> On Fri, 17 Aug 2018, Jeff Law wrote:
>>
 WCHAR_TYPE_SIZE is wrong because it doesn't account for flag_short_wchar.
 As far as I can see only ada/gcc-interface/targtyps.c uses WCHAR_TYPE_SIZE
 now.  TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT is what should be
 used.
>>> But that's specific to the c-family front-ends.
>>>
>>> There's MODIFIED_WCHAR_TYPE which is ultimately used to build
>>> wchar_type_node for the c-family front-ends.  Maybe we could construct
>>> something from that.
>>
>> If you do that, probably you want to move
>> fortran/trans-types.c:get_typenode_from_name (which converts the strings
>> used in target macros such as WCHAR_TYPE to the corresponding types) into
>> generic code.
> I think we ultimately have to go down that path.  Or we have to make the
> wchar types language independent.
> 
> My initial fooling around does something like this:
> 
>count_by = 1;
>if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
>  {
>tree node = get_identifier (MODIFIED_WCHAR_TYPE);
>if (node)
>  count_by = TYPE_PRECISION (TREE_TYPE (node)) / BITS_PER_UNIT
>  }
> 
> Of course, I still have to fire up tests on AIX to know if that, or a
> variant using get_typenode_from_name will DTRT.
> 

+1

Bernd.
> Jeff
> 


Re: [Patch][GCC] Document and fix -r (partial linking)

2018-08-20 Thread Joseph Myers
On Fri, 3 Aug 2018, Allan Sandfeld Jensen wrote:

> > I think you're changing the wrong place for this.  If you want -r to be
> > usable with GCC without using -nostdlib (which is an interesting
> > question), you actually need to change LINK_COMMAND_SPEC (also sometimes
> > overridden for targets) to handle -r more like -nostdlib -nostartfiles.
> > 
> Okay, so like this?

Could you confirm if this has passed a bootstrap and testsuite run, with 
no testsuite regressions compared to GCC without the patch applied?  I 
think it looks mostly OK (modulo ChangeLog rewrites and a missing second 
space after '.' in the manual change) but I'd like to make sure it's 
passed the usual testing before preparing it for commit.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH v2][C][ADA] use function descriptors instead of trampolines in C

2018-08-20 Thread Joseph Myers
On Mon, 20 Aug 2018, Uecker, Martin wrote:

> This is a new version which adds proper changelog entries and
> a test case (no actual code changes).

Please include the overall description of a change in every version 
submitted.  That is, the patch submission message should both include a 
description of the current version (as in a git-style commit message) and, 
if relevant, a description of what changed relative to the previous 
version of the patch (which would not go in the commit message).

A key thing I'm not clear on is what the user-visible difference in 
compiler behavior is supposed to be with this patch.  Whatever that 
user-visible difference is, I'd expect it to result in some change to the 
documentation of -ftrampolines in invoke.texi (describing the new feature, 
or changing a description of a limitation of an existing feature, or 
something like that).

> +/* { dg-do run { target x86_64-*-* } } */

It is always wrong for a test to use x86_64-*-* like that, because 
anything that should be tested for 64-bit code generation for an x86_64 
target should also be tested for i[34567]86-*-* -m64, and if you don't 
want to test for 32-bit code generation, you need to avoid testing for 
x86_64-*-* -m32, which that test would test for.  Anything genuinely 
x86-specific should go in gcc.target/i386 and then be conditioned on 
effective-target keywords such as lp64 if necessary.

I don't see why this is target-specific (if it is, the documentation for 
users in invoke.texi should explain what targets it works for and what it 
doesn't work for) anyway.  I'd expect it to be a target-independent 
feature with a target-independent test or tests.

Once there is sufficient user-level documentation showing what the 
intended semantics are, then it may be possible to evaluate how the 
implementation achieves that.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Jeff Law
On 08/20/2018 04:16 PM, Joseph Myers wrote:
> On Fri, 17 Aug 2018, Jeff Law wrote:
> 
>>> WCHAR_TYPE_SIZE is wrong because it doesn't account for flag_short_wchar.  
>>> As far as I can see only ada/gcc-interface/targtyps.c uses WCHAR_TYPE_SIZE 
>>> now.  TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT is what should be 
>>> used.
>> But that's specific to the c-family front-ends.
>>
>> There's MODIFIED_WCHAR_TYPE which is ultimately used to build
>> wchar_type_node for the c-family front-ends.  Maybe we could construct
>> something from that.
> 
> If you do that, probably you want to move 
> fortran/trans-types.c:get_typenode_from_name (which converts the strings 
> used in target macros such as WCHAR_TYPE to the corresponding types) into 
> generic code.
I think we ultimately have to go down that path.  Or we have to make the
wchar types language independent.

My initial fooling around does something like this:

  count_by = 1;
  if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
{
  tree node = get_identifier (MODIFIED_WCHAR_TYPE);
  if (node)
count_by = TYPE_PRECISION (TREE_TYPE (node)) / BITS_PER_UNIT
}

Of course, I still have to fire up tests on AIX to know if that, or a
variant using get_typenode_from_name will DTRT.

Jeff


Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Jeff Law
On 08/18/2018 11:38 AM, Martin Sebor wrote:
> On 08/17/2018 09:32 PM, Jeff Law wrote:
>> On 08/17/2018 02:17 PM, Martin Sebor wrote:
>>> On 08/17/2018 12:44 PM, Bernd Edlinger wrote:
 On 08/17/18 20:23, Martin Sebor wrote:
> On 08/17/2018 06:14 AM, Joseph Myers wrote:
>> On Fri, 17 Aug 2018, Jeff Law wrote:
>>
>>> On 08/16/2018 05:01 PM, Joseph Myers wrote:
 On Thu, 16 Aug 2018, Jeff Law wrote:

> restores previous behavior.  The sprintf bits want to count
> element
> sized chunks, which for wchars is 4 bytes (that count will then be

>    /* Compute the range the argument's length can be in.  */
> -  fmtresult slen = get_string_length (arg);
> +  int count_by = dir.specifier == 'S' || dir.modifier ==
> FMT_LEN_l ? 4 : 1;

 I don't see how a hardcoded 4 is correct here.  Surely you need to
 example
 wchar_type_node to determine its actual size for this target.
>>> We did kick this around a little.  IIRC Martin didn't think that it
>>> was
>>> worth handling the 2 byte wchar case.
>
> Sorry, I think we may have miscommunicated -- I didn't think it
> was useful to pass a size of the character type to the function.
> I agree that passing in a hardcoded constant doesn't seem right
> (even if GCC's wchar_t were always 4 bytes wide).
>
> I'm still not sure I see the benefit of passing in the expected
> element size given that the patch causes c_strlen() fail when
> the actual element size doesn't match ELTSIZE.  If the caller
> asks for the number of bytes in a const wchar_t array it should
> get back the number bytes.  (I could see it fail if the caller
> asked for the number of words in a char array whose size was
> not evenly divisible by wordsize.)
>

 I think in this case c_strlen should use the type which the %S format
 uses at runtime, otherwise it will not have anything to do with
 the reality.
>>>
>>> %S is not what I'm talking about.
>>>
>>> Failing in the case I described (a caller asking for the size
>>> in bytes of a constant object whose type is larger) prevents
>>> callers that don't care about the type from detecting the actual
>>> size of a constant.
>>>
>>> Specifically for sprintf, it means that the buffer overflow
>>> below is no longer diagnosed:
>>>
>>>   struct S { char a[2]; void (*pf)(void); };
>>>
>>>   void f (struct S *p)
>>>   {
>>>     const char *q = (char*)L"\x41424344\x45464748";
>>>
>>>     sprintf (p->a, "%s", q);
>>>   }
>> I don't think this is in the testsuite, is it?  I verified that there
>> was no regressions when I installed Bernd's patch and when I installed
>> yours.
> 
> No, there are very few tests that exercise these kinds of mixed
> argument types.  Code like that is most likely the result of
> a mistake, but it's not the kind of a bug I had even thought
> about until some of the codegen issues with mixed argument types
> were brought up (PR 86711/86714).
Phew.  I was worried I'd somehow missed the failure or tested the wrong
patch or who knows what.

Can you add that test, xfailed for now to the testsuite?

>
> I would just like the ability to get the length/size somehow
> so that the questionable code that started us down this path
> can be detected.  This is not just the sprintf(d, "%s", L"1")
> kind of a mismatch but also the missing nul detection in cases
> like:
[ ... ]
I know.  And ideally we'll be able to handle everything you want to.
But we also have to realize that sometimes we may have to punt.

Also remember that incremental progress is (usually) good.


> 
>   const wchar_t a[1] = L"\x";
>   strcpy(d, (char*)a);
This touches on both the representational issue (excess elements in the
initializer) and how to handle a non-terminated string.  Both are issues
we're debating right now.

> 
> I don't think this is necessarily an important use case to
> optimize for but it is one that GCC optimizes already nonetheless,
> and always has.  For example, this has always been folded into 4
> by GCC and still is even with the patch:
> 
>   const __WCHAR_TYPE__ wc[] = L"\x12345678";
> 
>   int f (void)
>   {
>     const char *p = (char*)wc;
>     return strlen (p);    // folded to 4
>   }
> 
> It's optimized because fold_const_call() relies on c_getstr()
> which returns the underlying byte representation of the wide
> string, and despite c_strlen() now trying to prevent it.
And I think you're hitting on some of issues already raised in the thread.

In this specific case though ISTM 4 is the right answer.  We casted to a
char *, so that's what we should be counting.  Or am I missing
something?  Also note that's the value we'd get from the strlen C
library call IIUC.



> 
> The missing nul variant of the same test case isn't folded (it
> ends up calling the library strlen) but the bug cannot be
> detected using the modified c_strlen():
> 

Re: [PATCH] Add a character size parameter to c_strlen/get_range_strlen

2018-08-20 Thread Joseph Myers
On Fri, 17 Aug 2018, Jeff Law wrote:

> > WCHAR_TYPE_SIZE is wrong because it doesn't account for flag_short_wchar.  
> > As far as I can see only ada/gcc-interface/targtyps.c uses WCHAR_TYPE_SIZE 
> > now.  TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT is what should be 
> > used.
> But that's specific to the c-family front-ends.
> 
> There's MODIFIED_WCHAR_TYPE which is ultimately used to build
> wchar_type_node for the c-family front-ends.  Maybe we could construct
> something from that.

If you do that, probably you want to move 
fortran/trans-types.c:get_typenode_from_name (which converts the strings 
used in target macros such as WCHAR_TYPE to the corresponding types) into 
generic code.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH, rs6000] Improve TREE_TYPE comparisons in fold_mergehl_helper()

2018-08-20 Thread Segher Boessenkool
Hi Will,

On Mon, Aug 20, 2018 at 04:40:35PM -0500, Will Schmidt wrote:
> This is a follow-up to an earlier patch that enabled gimple folding of
> vec_mergeh and vec_mergel for the float and double data types.
> 
> Per feedback from Richard, use the types_compatible_p helper to ensure
> we also catch any qualified types matching the V2DF_ or V4SF_ types.

That looks fine; if no one hollers, please commit.  Thanks!

I note we use lang_hooks.types_compatible_p a lot, which is a totally
different thing?  How confusing :-/


Segher


> 2018-08-20  Will Schmidt  
> 
>   * config/rs6000/rs6000.c (fold_mergehl_helper): Add types_compatible_p
>   wrappers around TREE_TYPE comparisons.
> 
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 97b922f..5f77afd 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -15135,13 +15135,15 @@ fold_mergehl_helper (gimple_stmt_iterator *gsi, 
> gimple *stmt, int use_high)
>tree permute_type;
>if (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type)))
>  permute_type = lhs_type;
>else
>  {
> -  if (TREE_TYPE (lhs_type) == TREE_TYPE (V2DF_type_node))
> +  if (types_compatible_p (TREE_TYPE (lhs_type),
> +   TREE_TYPE (V2DF_type_node)))
>   permute_type = V2DI_type_node;
> -  else if (TREE_TYPE (lhs_type) == TREE_TYPE (V4SF_type_node))
> +  else if (types_compatible_p (TREE_TYPE (lhs_type),
> +TREE_TYPE (V4SF_type_node)))
>   permute_type = V4SI_type_node;
>else
>   gcc_unreachable ();
>  }
>tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
> 


[PATCH, RFC, rs6000, v3] enable early gimple-folding of vec_splat

2018-08-20 Thread Will Schmidt
Hi
Enable GIMPLE folding of the vec_splat() intrinsic. (v3).

This uses the tree_vec_extract() function out of tree-vect-generic.c
to retrieve the splat value, which is a BIT_FIELD_REF.   That function is
made non-static as part of this change.

Testcases are already in-tree.

V2 updates, per feedback previously received.
Forced arg1 into range (modulo #elements) before attempting to extract
the splat value.
Removed the (now unnecessary) code that did bounds-checking before calling
the tree_vec_extract helper.
Used arg0_type rather than lhs_type for calculating the tree size.

V3 updates, inspired by additional offline discussion with Segher.
Noting that for vec_splat(arg1,arg2), the ABI describes ARG2 as an element
number less than the number of elements supported by the respective ARG1
type, so we do not attempt to gimple-fold the intrinsic if we determine our
value is out of range. Thus, the initial check ensures that ARG1 is both
constant and has a valid index into ARG0.
The subsequent modulo operation is no longer necessary, and has been removed.
Also eliminated a few now-unused variables.

Sniff-tests pass.  full regtest against powerpc platforms is in the queue.
OK for trunk with passing test results?

Thanks,
-Will

[gcc]

2018-08-20  Will Schmidt  

* config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add support for
  early gimple folding of vec_splat().
* tree-vect-generic.c: Remove static from tree_vec_extract() definition.
* gimple-fold.h:  Add an extern define for tree_vec_extract().

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5f77afd..4c3257f 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -15768,10 +15768,52 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
 tree splat_tree = build_vector_from_val (TREE_TYPE (lhs), splat_value);
 g = gimple_build_assign (lhs, splat_tree);
 gimple_set_location (g, gimple_location (stmt));
 gsi_replace (gsi, g, true);
 return true;
+   }
+
+/* Flavors of vec_splat.  */
+/* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...};  */
+case ALTIVEC_BUILTIN_VSPLTB:
+case ALTIVEC_BUILTIN_VSPLTH:
+case ALTIVEC_BUILTIN_VSPLTW:
+case VSX_BUILTIN_XXSPLTD_V2DI:
+case VSX_BUILTIN_XXSPLTD_V2DF:
+  {
+   arg0 = gimple_call_arg (stmt, 0); /* input vector.  */
+   arg1 = gimple_call_arg (stmt, 1); /* index into arg0.  */
+   /* Only fold the vec_splat_*() if arg1 is both a constant value, and a 
valid
+index into the arg0 vector.  */
+   unsigned int n_elts = VECTOR_CST_NELTS (arg0);
+   if (TREE_CODE (arg1) != INTEGER_CST
+   || TREE_INT_CST_LOW (arg1) > (n_elts -1))
+ return false;
+   lhs = gimple_call_lhs (stmt);
+   tree lhs_type = TREE_TYPE (lhs);
+   tree arg0_type = TREE_TYPE (arg0);
+   tree splat;
+   if (TREE_CODE (arg0) == VECTOR_CST)
+ splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1));
+   else
+ {
+   /* Determine (in bits) the length and start location of the
+  splat value for a call to the tree_vec_extract helper.  */
+   int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type))
+   * BITS_PER_UNIT / n_elts;
+   int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size;
+   tree len = build_int_cst (bitsizetype, splat_elem_size);
+   tree start = build_int_cst (bitsizetype, splat_start_bit);
+   splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0,
+ len, start);
+ }
+   /* And finally, build the new vector.  */
+   tree splat_tree = build_vector_from_val (lhs_type, splat);
+   g = gimple_build_assign (lhs, splat_tree);
+   gimple_set_location (g, gimple_location (stmt));
+   gsi_replace (gsi, g, true);
+   return true;
   }
 
 /* vec_mergel (integrals).  */
 case ALTIVEC_BUILTIN_VMRGLH:
 case ALTIVEC_BUILTIN_VMRGLW:
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
index 04e9bfa..e634180 100644
--- a/gcc/gimple-fold.h
+++ b/gcc/gimple-fold.h
@@ -59,10 +59,11 @@ extern tree gimple_fold_indirect_ref (tree);
 extern bool gimple_fold_builtin_sprintf (gimple_stmt_iterator *);
 extern bool gimple_fold_builtin_snprintf (gimple_stmt_iterator *);
 extern bool arith_code_with_undefined_signed_overflow (tree_code);
 extern gimple_seq rewrite_to_defined_overflow (gimple *);
 extern void replace_call_with_value (gimple_stmt_iterator *, tree);
+extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree);
 
 /* gimple_build, functionally matching fold_buildN, outputs stmts
int the provided sequence, matching and simplifying them on-the-fly.
Supposed to replace force_gimple_operand (fold_buildN (...), ...).  */
 extern tree gimple_build (gimple_seq *, 

[PATCH, rs6000] Improve TREE_TYPE comparisons in fold_mergehl_helper()

2018-08-20 Thread Will Schmidt
Hi,
This is a follow-up to an earlier patch that enabled gimple folding of
vec_mergeh and vec_mergel for the float and double data types.

Per feedback from Richard, use the types_compatible_p helper to ensure
we also catch any qualified types matching the V2DF_ or V4SF_ types.

Regtests ran clean.   OK for trunk?

Thanks,
-Will

[gcc]

2018-08-20  Will Schmidt  

* config/rs6000/rs6000.c (fold_mergehl_helper): Add types_compatible_p
wrappers around TREE_TYPE comparisons.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 97b922f..5f77afd 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -15135,13 +15135,15 @@ fold_mergehl_helper (gimple_stmt_iterator *gsi, 
gimple *stmt, int use_high)
   tree permute_type;
   if (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type)))
 permute_type = lhs_type;
   else
 {
-  if (TREE_TYPE (lhs_type) == TREE_TYPE (V2DF_type_node))
+  if (types_compatible_p (TREE_TYPE (lhs_type),
+ TREE_TYPE (V2DF_type_node)))
permute_type = V2DI_type_node;
-  else if (TREE_TYPE (lhs_type) == TREE_TYPE (V4SF_type_node))
+  else if (types_compatible_p (TREE_TYPE (lhs_type),
+  TREE_TYPE (V4SF_type_node)))
permute_type = V4SI_type_node;
   else
gcc_unreachable ();
 }
   tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);




Re: [libiberty patch] PEX-unix forking

2018-08-20 Thread Ian Lance Taylor via gcc-patches
On Mon, Aug 20, 2018 at 10:38 AM, Nathan Sidwell  wrote:
>
> This is the first of a pair of patches I've had on the modules branch for a
> while.  They improve the error behaviour in the case of child failure when
> vfork is the forking mechanism.
>
> This one commonizes the error paths in the parent and child to a pair of
> single blocks that print or return the error respectively.  Currently each
> error case calls pex_child_error, or returns the error in the parent.
>
> The patch records the name of a failing system call, and uses that to print
> or return the error.  It doesn't change functionality but will simplify the
> next patch that does.
>
> booted on x86_64-linux (which uses vfork), ok?


+  if (!bad_fn && in != STDIN_FILE_NO && close (in) < 0)
+bad_fn = "close";

As a matter of style I don't personally like the pattern in which a
condition has both tests and actions.  It's too easy to miss the
action.  I would prefer to see this more like the original code:

if (!bad_fn && in != STDIN_FILE_NO)
  {
if (close(in) < 0)
bad_fn = "close";
  }

This is OK with those changes.

Thanks.

Ian


Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Bernd Edlinger
On 08/20/18 22:42, Martin Sebor wrote:
> On 08/20/2018 09:15 AM, Bernd Edlinger wrote:
>> On 08/20/18 16:26, Jeff Law wrote:
>>> On 08/20/2018 04:23 AM, Bernd Edlinger wrote:
 On 08/20/18 12:12, Richard Biener wrote:
> On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:
>>
>> On 08/10/2018 10:56 AM, Martin Sebor wrote:
>>> On 08/08/2018 11:36 PM, Jeff Law wrote:
 On 08/02/2018 09:42 AM, Martin Sebor wrote:

> The warning bits are definitely not okay by me.  The purpose
> of the warnings (-W{format,sprintf}-{overflow,truncation} is
> to detect buffer overflows.  When a warning doesn't have access
> to string length information for dynamically created strings
> (like the strlen pass does) it uses array sizes as a proxy.
> This is useful both to detect possible buffer overflows and
> to prevent false positives for overflows that cannot happen
> in correctly written programs.
 So how much of this falling-back to array sizes as a proxy would become
 unnecessary if sprintf had access to the strlen pass as an analysis
 module?

 As you know we've been kicking that around and from my investigations
 that doesn't really look hard to do.  Encapsulate the data structures 
 in
 a class, break up the statement handling into analysis and optimization
 and we should be good to go.  I'm hoping to start prototyping this 
 week.

 If we think that has a reasonable chance to eliminate the array-size
 fallback, then that seems like the most promising path forward.
>>>
>>> We discussed this idea this morning so let me respond here and
>>> reiterate the answer.  Using the strlen data will help detect
>>> buffer overflow where the array size isn't available but it
>>> cannot replace the array size heuristic. Here's a simple
>>> example:
>>>
>>>     struct S { char a[8]; };
>>>
>>>     char d[8];
>>>     void f (struct S *s, int i)
>>>     {
>>>   sprintf (d, "%s-%i",  s[i].a, i);
>>>     }
>>>
>>> We don't know the length of s->a but we do know that it can
>>> be up to 7 bytes long (assuming it's nul-terminated of course)
>>> so we know the sprintf call can overflow.  Conversely, if
>>> the size of the destination is increased to 20  the sprintf
>>> call cannot overflow so the diagnostic can be avoided.
>>>
>>> Removing the array size heuristic would force us to either give
>>> up on diagnosing the first case or issue false positives for
>>> the second case.  I think the second alternative would make
>>> the warning too noisy to be useful.
>>>
>>> The strlen pass will help detect buffer overflows in cases
>>> where the array size isn't known (e.g., with dynamically
>>> allocated buffers) but where the length of the string store
>>> in the array is known.  It will also help avoid false positives
>>> in cases where the string stored in an array of known size is
>>> known to be too short to cause an overflow.  For instance here:
>>>
>>>     struct S { char a[8]; };
>>>
>>>     char d[8];
>>>     void f (struct S *s, int i)
>>>     {
>>>   if (strlen (s->a) < 4 && i >= 0 && i < 100)
>>>     sprintf (d, "%s-%i",  s->a, i);
>>>     }
>> ACK.  Thanks for explaining things here too.  I can't speak for others,
>> but seeing examples along with the explanation is easier for me to 
>> absorb.
>>
>> For Bernd and others -- after kicking things around a bit with Martin,
>> what we're recommending is that compute_string_length we compute the
>> bounds using both GIMPLE and C semantics and return both.
>
> But you can't do this because GIMPLE did transforms that are not valid in
> C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
> it as GIMPLE.  What you'd do is return GIMPLE semantics length
> and "foobar" semantics length which doesn't match the original source.
>

 If I understood that suggestion right, it means, we
 live with some false positive or missing warnings due to those 
 transformations.
 That means, get_range_strlen with the 2-parameter overload is used
 for warnings only.  And it returns most of the time a correct range info,
 that is good enough for warnings.
>>> Correct.  99.9% of the time using the ranges implied by the array types
>>> is better for the warning code.  So the idea is to return two ranges.
>>> One which uses GIMPLE semantics for code generation and optimization
>>> purposes, the other which uses ranges implied by the array types for
>>> warning purposes.
>>>
>>> Martin suggested that we always compute and return both rather than
>>> having a boolean argument to select between the behavior.
>>>
>>>
>>
>> Okay, but there is already the 

Re: C++ PATCH for c++/86981, implement -Wpessimizing-move

2018-08-20 Thread David Malcolm
On Mon, 2018-08-20 at 17:08 -0400, Marek Polacek wrote:
> This patch implements -Wpessimizing-move, a C++-specific warning that
> warns
> when using std::move in a return statement precludes the
> NRVO.  Consider:
> 
> struct T { };
> 
> T f()
> {
>   T t;
>   return std::move(t);
> }
> 
> where we could elide the copy were it not for the move call; the
> standard
> requires that the expression be the name of a non-volatile automatic
> object, so
> no function call would work there.
> Had 't' been a parameter, the move would have been merely redundant,
> but that's
> for another warning, -Wredundant-move, which should be a fairly easy
> extension
> of this one.
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

[...snip...]

> +   /* Warn if we could do copy elision were it not for the
> move.  */
> +   if (can_do_nrvo_p (arg, functype)
> +   && warning (OPT_Wpessimizing_move, "moving a local object "
> +   "in a return statement prevents copy elision"))
> + inform (input_location, "remove % call");
> + }
> +}

As of r263675 it's now possible to tell the diagnostics subsystem that
the warning and note are related by using an auto_diagnostic_group
instance [1], so please can this read:

  if (can_do_nrvo_p (arg, functype))
{
  auto_diagnostic_group d;
  if (warning (OPT_Wpessimizing_move, "moving a local object "
   "in a return statement prevents copy elision"))
inform (input_location, "remove % call");
}

Dave

[1] see https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01190.html

Not that this does much yet, but I'm hoping to make it do so,
especially for cases like this where both diagnostics share the same
location



PING^1: V3 [PATCH] C/C++: Add -Waddress-of-packed-member

2018-08-20 Thread H.J. Lu
On Mon, Jul 23, 2018 at 2:24 PM, H.J. Lu  wrote:
> On Mon, Jun 18, 2018 at 12:26 PM, Joseph Myers  
> wrote:
>> On Mon, 18 Jun 2018, Jason Merrill wrote:
>>
>>> On Mon, Jun 18, 2018 at 11:59 AM, Joseph Myers  
>>> wrote:
>>> > On Mon, 18 Jun 2018, Jason Merrill wrote:
>>> >
>>> >> > +  if (TREE_CODE (rhs) == COND_EXPR)
>>> >> > +{
>>> >> > +  /* Check the THEN path first.  */
>>> >> > +  tree op1 = TREE_OPERAND (rhs, 1);
>>> >> > +  context = check_address_of_packed_member (type, op1);
>>> >>
>>> >> This should handle the GNU extension of re-using operand 0 if operand
>>> >> 1 is omitted.
>>> >
>>> > Doesn't that just use a SAVE_EXPR?
>>>
>>> Hmm, I suppose it does, but many places in the compiler seem to expect
>>> that it produces a COND_EXPR with TREE_OPERAND 1 as NULL_TREE.
>>
>> Maybe that's used somewhere inside the C++ front end.  For C a SAVE_EXPR
>> is produced directly.
>>
>
> Here is the updated patch.  Changes from the last one:
>
> 1. Handle COMPOUND_EXPR.
> 2. Fixed typos in comments.
> 3. Combined warn_for_pointer_of_packed_member and
> warn_for_address_of_packed_member into
> warn_for_address_or_pointer_of_packed_member.
>
> Tested on Linux/x86-64 and Linux/i686.  OK for trunk.
>

PING^1.


-- 
H.J.


[committed] Add support for grouping of related diagnostics (PR other/84889)

2018-08-20 Thread David Malcolm
We often emit logically-related groups of diagnostics.

A relatively simple case is this:

  if (warning_at (body_loc, OPT_Wmultistatement_macros,
  "macro expands to multiple statements"))
inform (guard_loc, "some parts of macro expansion are not guarded by "
"this %qs clause", guard_tinfo_to_string (keyword));

where the "note" diagnostic issued by the "inform" call
is guarded by the -Wmultistatement_macros warning.

More complicated examples can be seen in the C++ frontend,
where e.g. print_z_candidates can lead to numerous "note"
diagnostics being emitted.

I'm looking at various ways to improve how we handle such related
diagnostics, but, prior to this patch, there was no explicit
relationship between these diagnostics: the diagnostics subsystem
had no way of "knowing" that these were related.

This patch introduces a simple way to group the diagnostics:
an auto_diagnostic_group class: all diagnostics emitted within
the lifetime of an auto_diagnostic_group instance are logically
grouped.

Hence in the above example, the two diagnostics can be grouped
by simply adding an auto_diagnostic_group instance:

  auto_diagnostic_group d;
  if (warning_at (body_loc, OPT_Wmultistatement_macros,
  "macro expands to multiple statements"))
inform (guard_loc, "some parts of macro expansion are not guarded by "
"this %qs clause", guard_tinfo_to_string (keyword));

Some more awkard cases are of the form:

  if (some_condition
  && warning_at (...)
  && more_conditions)
inform (...);

which thus need restructuring to:

  if (some_condition)
{
  auto_diagnostic_group d;
  warning_at (...);
  if (more_conditions)
inform (...);
}

so that the lifetime of the auto_diagnostic_group groups the
warning_at and the inform call.

Nesting is handled by simply tracking a nesting depth within the
diagnostic_context.: all diagnostics are treated as grouped until the
final auto_diagnostic_group is popped.

diagnostic.c uses this internally, so that all diagnostics are part of
a group - those that are "by themselves" are treated as being part of
a group with one element.

The diagnostic_context gains optional callbacks for displaying the
start of a group (when the first diagnostic is emitted within it), and
the end of a group (for when the group was non-empty); these callbacks
are unused by default, but a test plugin demonstrates them (and verifies
that the machinery is working).

As noted above, I'm looking at various ways to use the grouping to
improve how we output the diagnostics.

FWIW, I experimented with a more involved implementation, of the form:

  diagnostic_group d;
  if (d.warning_at (body_loc, OPT_Wmultistatement_macros,
"macro expands to multiple statements"))
d.inform (guard_loc, "some parts of macro expansion are not guarded by "
  "this %qs clause", guard_tinfo_to_string (keyword));

which had the advantage of allowing auto-detection of the places where
groups were needed (by converting ::warning_at's return type to bool),
but it was a much more invasive patch, especially when dealing with
the places in the C++ frontend that can emit numerous notes after
an error or warning (and thus having to pass the group around)
Hence I went with this simpler approach.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu; adds
4 PASS results to gcc.sum.

Committed to trunk as r263675.

gcc/c-family/ChangeLog:
PR other/84889
* c-attribs.c (common_handle_aligned_attribute): Add
auto_diagnostic_group instance.
* c-indentation.c (warn_for_misleading_indentation): Likewise.
* c-opts.c (c_common_post_options): Likewise.
* c-warn.c (warn_logical_not_parentheses): Likewise.
(warn_duplicated_cond_add_or_warn): Likewise.
(warn_for_multistatement_macros): Likewise.

gcc/c/ChangeLog:
PR other/84889
* c-decl.c (pushtag): Add auto_diagnostic_group instance.
(diagnose_mismatched_decls): Likewise, in various places.
(warn_if_shadowing): Likewise.
(implicit_decl_warning): Likewise.
(implicitly_declare): Likewise.
(undeclared_variable): Likewise.
(declare_label): Likewise.
(grokdeclarator): Likewise.
(start_function): Likewise.
* c-parser.c (c_parser_declaration_or_fndef): Likewise.
(c_parser_parameter_declaration): Likewise.
(c_parser_binary_expression): Likewise.
* c-typeck.c (c_expr_sizeof_expr): Likewise.
(parser_build_binary_op): Likewise.
(build_unary_op): Likewise.
(error_init): Likewise.
(pedwarn_init): Likewise.
(warning_init): Likewise.
(convert_for_assignment): Likewise.

gcc/cp/ChangeLog:
PR other/84889
* call.c (build_user_type_conversion_1): Add auto_diagnostic_group
instance(s).
(print_error_for_call_failure): Likewise.

C++ PATCH for c++/86981, implement -Wpessimizing-move

2018-08-20 Thread Marek Polacek
This patch implements -Wpessimizing-move, a C++-specific warning that warns
when using std::move in a return statement precludes the NRVO.  Consider:

struct T { };

T f()
{
  T t;
  return std::move(t);
}

where we could elide the copy were it not for the move call; the standard
requires that the expression be the name of a non-volatile automatic object, so
no function call would work there.
Had 't' been a parameter, the move would have been merely redundant, but that's
for another warning, -Wredundant-move, which should be a fairly easy extension
of this one.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-08-20  Marek Polacek  

PR c++/86981, Implement -Wpessimizing-move.
* c.opt (Wpessimizing-move): New option.

* typeck.c (decl_in_std_namespace_p): New.
(is_std_move_p): New.
(can_do_nrvo_p): New, factored out of ...
(check_return_expr): ... here.  Warn about potentially harmful
std::move in a return statement.

* doc/invoke.texi: Document -Wpessimizing-move.

* g++.dg/cpp0x/Wpessimizing-move1.C: New test.
* g++.dg/cpp0x/Wpessimizing-move2.C: New test.
* g++.dg/cpp0x/Wpessimizing-move3.C: New test.
* g++.dg/cpp0x/Wpessimizing-move4.C: New test.
* g++.dg/cpp1z/Wpessimizing-move1.C: New test.

diff --git gcc/c-family/c.opt gcc/c-family/c.opt
index 9980bfac11c..76840dd77ad 100644
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -937,6 +937,10 @@ Wpedantic
 C ObjC C++ ObjC++ CPP(cpp_pedantic) CppReason(CPP_W_PEDANTIC) Warning
 ; Documented in common.opt
 
+Wpessimizing-move
+C++ ObjC++ Var(warn_pessimizing_move) Warning LangEnabledBy(C++ ObjC++, Wall)
+Warn about calling std::move on a local object in a return statement 
preventing copy elision.
+
 Wpmf-conversions
 C++ ObjC++ Var(warn_pmf2ptr) Init(1) Warning
 Warn when converting the type of pointers to member functions.
diff --git gcc/cp/typeck.c gcc/cp/typeck.c
index 8c13ae9b19b..e7504d5a246 100644
--- gcc/cp/typeck.c
+++ gcc/cp/typeck.c
@@ -9113,6 +9113,58 @@ maybe_warn_about_returning_address_of_local (tree retval)
   return false;
 }
 
+/* Returns true if DECL is in the std namespace.  */
+
+static bool
+decl_in_std_namespace_p (tree decl)
+{
+  return (decl != NULL_TREE
+ && DECL_NAMESPACE_STD_P (decl_namespace_context (decl)));
+}
+
+/* Returns true if FN, a CALL_EXPR, is a call to std::move.  */
+
+static bool
+is_std_move_p (tree fn)
+{
+  /* std::move only takes one argument.  */
+  if (call_expr_nargs (fn) != 1)
+return false;
+
+  tree fndecl = cp_get_callee_fndecl_nofold (fn);
+  if (!decl_in_std_namespace_p (fndecl))
+return false;
+
+  tree name = DECL_NAME (fndecl);
+  return name && id_equal (name, "move");
+}
+
+/* Returns true if RETVAL is a good candidate for the NRVO as per
+   [class.copy.elision].  FUNCTYPE is the type the function is declared
+   to return.  */
+
+static bool
+can_do_nrvo_p (tree retval, tree functype)
+{
+  tree result = DECL_RESULT (current_function_decl);
+  return (retval != NULL_TREE
+ && !processing_template_decl
+ /* Must be a local, automatic variable.  */
+ && VAR_P (retval)
+ && DECL_CONTEXT (retval) == current_function_decl
+ && !TREE_STATIC (retval)
+ /* And not a lambda or anonymous union proxy.  */
+ && !DECL_HAS_VALUE_EXPR_P (retval)
+ && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
+ /* The cv-unqualified type of the returned value must be the
+same as the cv-unqualified return type of the
+function.  */
+ && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
+ (TYPE_MAIN_VARIANT (functype)))
+ /* And the returned value must be non-volatile.  */
+ && !TYPE_VOLATILE (TREE_TYPE (retval)));
+}
+
 /* Check that returning RETVAL from the current function is valid.
Return an expression explicitly showing all conversions required to
change RETVAL into the function return type, and to assign it to
@@ -9130,7 +9182,6 @@ check_return_expr (tree retval, bool *no_warning)
  the declared type is incomplete.  */
   tree functype;
   int fn_returns_value_p;
-  bool named_return_value_okay_p;
 
   *no_warning = false;
 
@@ -9342,24 +9393,7 @@ check_return_expr (tree retval, bool *no_warning)
 
  See finish_function and finalize_nrv for the rest of this optimization.  
*/
 
-  named_return_value_okay_p = 
-(retval != NULL_TREE
- && !processing_template_decl
- /* Must be a local, automatic variable.  */
- && VAR_P (retval)
- && DECL_CONTEXT (retval) == current_function_decl
- && ! TREE_STATIC (retval)
- /* And not a lambda or anonymous union proxy.  */
- && !DECL_HAS_VALUE_EXPR_P (retval)
- && (DECL_ALIGN (retval) <= DECL_ALIGN (result))
- /* The cv-unqualified type of the returned value must be the
-same as the cv-unqualified return type of the
-function.  */
- && 

Re: [PATCH], Improve PowerPC switch behavior on medium code model system

2018-08-20 Thread Michael Meissner
On Fri, Aug 10, 2018 at 11:04:50AM -0500, Segher Boessenkool wrote:
> On Tue, Jul 31, 2018 at 10:39:21AM -0400, Michael Meissner wrote:
> > This patch adds an insn to load a LABEL_REF into a GPR.  This is needed so 
> > the
> > FWPROP1 pass can convert the load the of the label address from the TOC to a
> > direct load to a GPR.
> 
> I don't see why you need a separate RTL insn for this.  It seems to me
> that some more generic pattern should accept label_refs.

I'm not aware of any.

> > While working on the patch, I discovered that the LWA instruction did not
> > support indexed loads.  This was due to it using the 'Y' constraint, which
> > accepts DS-form offsettable addresses, but not X-form indexed addresses.  I
> > added the Z constraint so that the indexed form is accepted.
> 
> This part is fine.  Please split it out to a separate patch.

I just added PR target/87033 for this, and I will submit the patch shortly.

> > * config/rs6000/rs6000.md (extendsi2): Allow reg+reg indexed
> > addressing.
> 
> This should say it is changing the constraints.
> 
> > (labelref): New insn to optimize loading a label address into
> > registers on a medium code system.
> 
> (*labelref) btw.

Yes.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797



Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Martin Sebor

On 08/20/2018 09:15 AM, Bernd Edlinger wrote:

On 08/20/18 16:26, Jeff Law wrote:

On 08/20/2018 04:23 AM, Bernd Edlinger wrote:

On 08/20/18 12:12, Richard Biener wrote:

On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:


On 08/10/2018 10:56 AM, Martin Sebor wrote:

On 08/08/2018 11:36 PM, Jeff Law wrote:

On 08/02/2018 09:42 AM, Martin Sebor wrote:


The warning bits are definitely not okay by me.  The purpose
of the warnings (-W{format,sprintf}-{overflow,truncation} is
to detect buffer overflows.  When a warning doesn't have access
to string length information for dynamically created strings
(like the strlen pass does) it uses array sizes as a proxy.
This is useful both to detect possible buffer overflows and
to prevent false positives for overflows that cannot happen
in correctly written programs.

So how much of this falling-back to array sizes as a proxy would become
unnecessary if sprintf had access to the strlen pass as an analysis
module?

As you know we've been kicking that around and from my investigations
that doesn't really look hard to do.  Encapsulate the data structures in
a class, break up the statement handling into analysis and optimization
and we should be good to go.  I'm hoping to start prototyping this week.

If we think that has a reasonable chance to eliminate the array-size
fallback, then that seems like the most promising path forward.


We discussed this idea this morning so let me respond here and
reiterate the answer.  Using the strlen data will help detect
buffer overflow where the array size isn't available but it
cannot replace the array size heuristic. Here's a simple
example:

struct S { char a[8]; };

char d[8];
void f (struct S *s, int i)
{
  sprintf (d, "%s-%i",  s[i].a, i);
}

We don't know the length of s->a but we do know that it can
be up to 7 bytes long (assuming it's nul-terminated of course)
so we know the sprintf call can overflow.  Conversely, if
the size of the destination is increased to 20  the sprintf
call cannot overflow so the diagnostic can be avoided.

Removing the array size heuristic would force us to either give
up on diagnosing the first case or issue false positives for
the second case.  I think the second alternative would make
the warning too noisy to be useful.

The strlen pass will help detect buffer overflows in cases
where the array size isn't known (e.g., with dynamically
allocated buffers) but where the length of the string store
in the array is known.  It will also help avoid false positives
in cases where the string stored in an array of known size is
known to be too short to cause an overflow.  For instance here:

struct S { char a[8]; };

char d[8];
void f (struct S *s, int i)
{
  if (strlen (s->a) < 4 && i >= 0 && i < 100)
sprintf (d, "%s-%i",  s->a, i);
}

ACK.  Thanks for explaining things here too.  I can't speak for others,
but seeing examples along with the explanation is easier for me to absorb.

For Bernd and others -- after kicking things around a bit with Martin,
what we're recommending is that compute_string_length we compute the
bounds using both GIMPLE and C semantics and return both.


But you can't do this because GIMPLE did transforms that are not valid in
C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
it as GIMPLE.  What you'd do is return GIMPLE semantics length
and "foobar" semantics length which doesn't match the original source.



If I understood that suggestion right, it means, we
live with some false positive or missing warnings due to those transformations.
That means, get_range_strlen with the 2-parameter overload is used
for warnings only.  And it returns most of the time a correct range info,
that is good enough for warnings.

Correct.  99.9% of the time using the ranges implied by the array types
is better for the warning code.  So the idea is to return two ranges.
One which uses GIMPLE semantics for code generation and optimization
purposes, the other which uses ranges implied by the array types for
warning purposes.

Martin suggested that we always compute and return both rather than
having a boolean argument to select between the behavior.




Okay, but there is already the "strict" parameter:

/* Determine the minimum and maximum value or string length that ARG
refers to and store each in the first two elements of MINMAXLEN.
For expressions that point to strings of unknown lengths that are
character arrays, use the upper bound of the array as the maximum
length.  For example, given an expression like 'x ? array : "xyz"'
and array declared as 'char array[8]', MINMAXLEN[0] will be set
to 0 and MINMAXLEN[1] to 7, the longest string that could be
stored in array.
Return 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
due to it being used as a 

Re: P0646R1 for Debug mode

2018-08-20 Thread François Dumont
Right after I hit the send button I realized that I had forgotten to 
remove the definition of __cpp_lib_list_remove_return_type on the Debug 
forward_list side.


I haven't plan to define this macro in this context, I prefer to leave 
it to normal implementation.


So here is the updated patch.


On 20/08/2018 22:26, François Dumont wrote:

This patch implements P0646R1 for Debug mode containers.

It fixes tests:

23_containers/forward_list/operations/remove_cxx20_return.cc
23_containers/forward_list/operations/unique_cxx20_return.cc
23_containers/list/operations/remove_cxx20_return.cc
23_containers/list/operations/unique_cxx20_return.cc

Note that it also adopt the Lib Defects 526 which had been implemented 
only for the normal mode.


I'll commit this tomorrow if not told otherwise.

    P0646R1 Improving the Return Value of Erase-Like Algorithms I
    * include/debug/forward_list (forward_list::__remove_return_type):
    Define typedef as size_type or void, according to __cplusplus value.
    (_GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
    empty, according to __cplusplus value.
    (_GLIBCXX20_ONLY): Define macro.
    (forward_list::remove, forward_list::unique): Use typedef and macro
    to change return type and add abi-tag for C++2a. Return number of
    removed elements for C++2a.
    (forward_list::remove_if, forward_list::unique): Use
    typedef to change return type for C++2a. Return number of removed
    elements for C++2a.
    * include/debug/list (list::__remove_return_type): Define typedef as
    size_type or void, according to __cplusplus value.
    (_GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
    empty, according to __cplusplus value.
    (_GLIBCXX20_ONLY): Define macro.
    (list::remove, list::unique): Use typedef and macro to change return
    type and add abi-tag for C++2a. Return number of removed elements for
    C++2a.
    (list::remove_if, list::unique): Use 
typedef
    to change return type for C++2a. Return number of removed elements 
for

    C++2a.

François



diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index e5ac09e8..840ed09 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -656,70 +656,113 @@ namespace __debug
 		   const_iterator __before, const_iterator __last)
   { splice_after(__pos, std::move(__list), __before, __last); }
 
-  void
+private:
+#if __cplusplus > 201703L
+  using __remove_return_type = size_type;
+# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG \
+  __attribute__((__abi_tag__("__cxx20")))
+# define _GLIBCXX20_ONLY(__expr) __expr
+#else
+  using __remove_return_type = void;
+# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
+# define _GLIBCXX20_ONLY(__expr)
+#endif
+
+public:
+  _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
+  __remove_return_type
   remove(const _Tp& __val)
   {
+	if (!this->_M_iterators && !this->_M_const_iterators)
+	  return _Base::remove(__val);
+
+	size_type __removed __attribute__((__unused__)) = 0;
 	_Base_iterator __x = _Base::before_begin();
 	_Base_iterator __old = __x++;
+	_Base_iterator __extra = _Base::end();
 	while (__x != _Base::end())
 	  {
 	if (*__x == __val)
-	  __x = _M_erase_after(__old);
-	else
-	  __old = __x++;
+	  {
+		if (std::__addressof(*__x) != std::__addressof(__val))
+		  {
+		__x = _M_erase_after(__old);
+		_GLIBCXX20_ONLY( __removed++ );
+		continue;
+		  }
+		else
+		  __extra = __old;
+	  }
+	__old = __x++;
 	  }
+
+	if (__extra != _Base::end())
+	  {
+	this->_M_erase_after(__extra);
+	_GLIBCXX20_ONLY( __removed++ );
+	  }
+
+	return _GLIBCXX20_ONLY( __removed );
   }
 
   template
-	void
+	__remove_return_type
 	remove_if(_Pred __pred)
 	{
+	  if (!this->_M_iterators && !this->_M_const_iterators)
+	return _Base::remove_if(__pred);
+
+	  size_type __removed __attribute__((__unused__)) = 0;
 	  _Base_iterator __x = _Base::before_begin();
 	  _Base_iterator __old = __x++;
 	  while (__x != _Base::end())
-	{
-	  if (__pred(*__x))
+	if (__pred(*__x))
+	  {
 		__x = _M_erase_after(__old);
-	  else
-		__old = __x++;
-	}
+		_GLIBCXX20_ONLY( __removed++ );
+	  }
+	else
+	  __old = __x++;
+
+	  return _GLIBCXX20_ONLY( __removed );
 	}
 
-  void
+  _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
+  __remove_return_type
   unique()
-  {
-	_Base_iterator __first = _Base::begin();
-	_Base_iterator __last = _Base::end();
-	if (__first == __last)
-	  return;
-	_Base_iterator __next = std::next(__first);
-	while (__next != __last)
-	  {
-	if (*__first == *__next)
-	  __next = _M_erase_after(__first);
-	else
-	  __first = __next++;
-	  }
-  }
+  { return unique(std::equal_to<_Tp>()); }
 
   template
-	void
+	__remove_return_type
 	unique(_BinPred __binary_pred)
 	{
+	  if (!this->_M_iterators && 

P0646R1 for Debug mode

2018-08-20 Thread François Dumont

This patch implements P0646R1 for Debug mode containers.

It fixes tests:

23_containers/forward_list/operations/remove_cxx20_return.cc
23_containers/forward_list/operations/unique_cxx20_return.cc
23_containers/list/operations/remove_cxx20_return.cc
23_containers/list/operations/unique_cxx20_return.cc

Note that it also adopt the Lib Defects 526 which had been implemented 
only for the normal mode.


I'll commit this tomorrow if not told otherwise.

    P0646R1 Improving the Return Value of Erase-Like Algorithms I
    * include/debug/forward_list (forward_list::__remove_return_type):
    Define typedef as size_type or void, according to __cplusplus value.
    (_GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
    empty, according to __cplusplus value.
    (_GLIBCXX20_ONLY): Define macro.
    (forward_list::remove, forward_list::unique): Use typedef and macro
    to change return type and add abi-tag for C++2a. Return number of
    removed elements for C++2a.
    (forward_list::remove_if, forward_list::unique): Use
    typedef to change return type for C++2a. Return number of removed
    elements for C++2a.
    * include/debug/list (list::__remove_return_type): Define typedef as
    size_type or void, according to __cplusplus value.
    (_GLIBCXX_LIST_REMOVE_RETURN_TYPE_TAG): Define macro as abi-tag or
    empty, according to __cplusplus value.
    (_GLIBCXX20_ONLY): Define macro.
    (list::remove, list::unique): Use typedef and macro to change return
    type and add abi-tag for C++2a. Return number of removed elements for
    C++2a.
    (list::remove_if, list::unique): Use 
typedef

    to change return type for C++2a. Return number of removed elements for
    C++2a.

François

diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index e5ac09e8..2340962 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -656,70 +656,114 @@ namespace __debug
 		   const_iterator __before, const_iterator __last)
   { splice_after(__pos, std::move(__list), __before, __last); }
 
-  void
+private:
+#if __cplusplus > 201703L
+# define __cpp_lib_list_remove_return_type 201806L
+  using __remove_return_type = size_type;
+# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG \
+  __attribute__((__abi_tag__("__cxx20")))
+# define _GLIBCXX20_ONLY(__expr) __expr
+#else
+  using __remove_return_type = void;
+# define _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
+# define _GLIBCXX20_ONLY(__expr)
+#endif
+
+public:
+  _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
+  __remove_return_type
   remove(const _Tp& __val)
   {
+	if (!this->_M_iterators && !this->_M_const_iterators)
+	  return _Base::remove(__val);
+
+	size_type __removed __attribute__((__unused__)) = 0;
 	_Base_iterator __x = _Base::before_begin();
 	_Base_iterator __old = __x++;
+	_Base_iterator __extra = _Base::end();
 	while (__x != _Base::end())
 	  {
 	if (*__x == __val)
-	  __x = _M_erase_after(__old);
-	else
-	  __old = __x++;
+	  {
+		if (std::__addressof(*__x) != std::__addressof(__val))
+		  {
+		__x = _M_erase_after(__old);
+		_GLIBCXX20_ONLY( __removed++ );
+		continue;
+		  }
+		else
+		  __extra = __old;
+	  }
+	__old = __x++;
 	  }
+
+	if (__extra != _Base::end())
+	  {
+	this->_M_erase_after(__extra);
+	_GLIBCXX20_ONLY( __removed++ );
+	  }
+
+	return _GLIBCXX20_ONLY( __removed );
   }
 
   template
-	void
+	__remove_return_type
 	remove_if(_Pred __pred)
 	{
+	  if (!this->_M_iterators && !this->_M_const_iterators)
+	return _Base::remove_if(__pred);
+
+	  size_type __removed __attribute__((__unused__)) = 0;
 	  _Base_iterator __x = _Base::before_begin();
 	  _Base_iterator __old = __x++;
 	  while (__x != _Base::end())
-	{
-	  if (__pred(*__x))
+	if (__pred(*__x))
+	  {
 		__x = _M_erase_after(__old);
-	  else
-		__old = __x++;
-	}
+		_GLIBCXX20_ONLY( __removed++ );
+	  }
+	else
+	  __old = __x++;
+
+	  return _GLIBCXX20_ONLY( __removed );
 	}
 
-  void
+  _GLIBCXX_FWDLIST_REMOVE_RETURN_TYPE_TAG
+  __remove_return_type
   unique()
-  {
-	_Base_iterator __first = _Base::begin();
-	_Base_iterator __last = _Base::end();
-	if (__first == __last)
-	  return;
-	_Base_iterator __next = std::next(__first);
-	while (__next != __last)
-	  {
-	if (*__first == *__next)
-	  __next = _M_erase_after(__first);
-	else
-	  __first = __next++;
-	  }
-  }
+  { return unique(std::equal_to<_Tp>()); }
 
   template
-	void
+	__remove_return_type
 	unique(_BinPred __binary_pred)
 	{
+	  if (!this->_M_iterators && !this->_M_const_iterators)
+	return _Base::unique(__binary_pred);
+
 	  _Base_iterator __first = _Base::begin();
 	  _Base_iterator __last = _Base::end();
 	  if (__first == __last)
-	return;
+	return _GLIBCXX20_ONLY(0);
+
+	  size_type __removed __attribute__((__unused__)) = 0;
 	  

Re: [PATCH] XFAIL 18_support/new_nothrow.cc on AIX

2018-08-20 Thread Jonathan Wakely

On 20/08/18 13:09 -0400, David Edelsohn wrote:

18_support/new_nothrow.cc relies upon overriding operator new.  This is not
enabled by default in libstdc++ on AIX.  This patch XFAILs the testcase.

Bootstrapped on powerpc-ibm-aix7.2.0.0

Okay?


OK, thanks.




Re: [PING][PATCH] Make function clone name numbering independent.

2018-08-20 Thread Jeff Law
On 08/13/2018 05:58 PM, Michael Ploujnikov wrote:
> Ping and I've updated the patch since last time as follows:
> 
>   - unittest scans assembly rather than the constprop dump because its
> forward changed
>   - unittests should handle different hosts where any of
> NO_DOT_IN_LABEL, NO_DOLLAR_IN_LABEL or __USER_LABEL_PREFIX__ may
> be defined
>   - not 100% it's safe to change DECL_NAME to DECL_ASSEMBLER_NAME in
> cgraph_node::create_virtual_clone, but I've attempted to reduce
> some code duplication
>   - lto-partition.c: privatize_symbol_name_1 *does* need numbered
> names
>   - but cold sections don't
>   - Expecting an IDENTIFIER_NODE in clone_function_name_1 avoids
> unreliable string pointer use as pointed out in the first review
>   - renamed clone_function_name_1 and clone_function_name to
> numbered_clone_function_name_1 and numbered_clone_function_name to
> clarify purpose and discourage future unintended uses
Richi has more state here than I do, so I'm going to let him own it.  I
know he's just returning from PTO, so it's going to take him a bit of
time to catch up.

jeff


Re: patch to bug #86829

2018-08-20 Thread Jeff Law
On 08/04/2018 07:22 AM, Giuliano Augusto Faulin Belinassi wrote:
> Closes bug #86829
> 
> Description: Adds substitution rules for both sin(atan(x)) and
> cos(atan(x)). These formulas are replaced by x / sqrt(x*x + 1) and 1 /
> sqrt(x*x + 1) respectively, providing up to 10x speedup. This identity
> can be proved mathematically.
> 
> Changelog:
> 
> 2018-08-03  Giuliano Belinassi 
> 
> * match.pd: add simplification rules to sin(atan(x)) and cos(atan(x)).
> 
> Bootstrap and Testing:
> There were no unexpected failures in a proper testing in GCC 8.1.0
> under a x86_64 running Ubuntu 18.04.
I understand these are mathematical identities.  But floating point
arthmetic in a compiler isn't nearly that clean :-)  We have to worry
about overflows, underflows, rounding, and the simple fact that many
floating point numbers can't be exactly represented.

Just as an example, compare the results for
x = 0x1.fp1023

I think sin(atan (x)) is well defined in that case.  But the x*x isn't
because it overflows.

So  I think this has to be somewhere under the -ffast-math umbrella.
And the testing requirements for that are painful -- you have to verify
it doesn't break the spec benchmark.

I know Richi acked in the PR, but that might have been premature.

jeff





Re: [PATCH] x86: Always update EH return address in word_mode

2018-08-20 Thread H.J. Lu
On Mon, Aug 20, 2018 at 11:40 AM, Uros Bizjak  wrote:
> On Mon, Aug 20, 2018 at 8:19 PM, H.J. Lu  wrote:
>> On x86, return address is always popped in word_mode.  eh_return needs
>> to put EH return address in word_mode on stack.
>>
>> Tested on x86-64 with x32. OK for trunk and release branches?
>
> OK. Perhaps the testcase should go into g++.dg/torture, since it is
> sensitive to optimization level?

Sure.  This is the patch I am checking in.

Thanks.

-- 
H.J.
From 62605355f506d4f163b6102ae0db67b19c3df756 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" 
Date: Mon, 20 Aug 2018 10:04:35 -0700
Subject: [PATCH] x86: Always update EH return address in word_mode

On x86, return address is always popped in word_mode.  eh_return needs
to put EH return address in word_mode on stack.

gcc/

	PR target/87014
	* config/i386/i386.md (eh_return): Always update EH return
	address in word_mode.

gcc/testsuite/

	PR target/87014
	* g++.dg/torture/pr87014.C: New file.
---
 gcc/config/i386/i386.md|  5 +++-
 gcc/testsuite/g++.dg/torture/pr87014.C | 37 ++
 2 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr87014.C

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 918241d953a..71faa218ffa 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13612,7 +13612,10 @@
  stack address we wish to restore.  */
   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
-  tmp = gen_rtx_MEM (Pmode, tmp);
+  /* Return address is always in word_mode.  */
+  tmp = gen_rtx_MEM (word_mode, tmp);
+  if (GET_MODE (ra) != word_mode)
+ra = convert_to_mode (word_mode, ra, 1);
   emit_move_insn (tmp, ra);
 
   emit_jump_insn (gen_eh_return_internal ());
diff --git a/gcc/testsuite/g++.dg/torture/pr87014.C b/gcc/testsuite/g++.dg/torture/pr87014.C
new file mode 100644
index 000..614954ef464
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr87014.C
@@ -0,0 +1,37 @@
+// { dg-do run }
+
+void
+fillstack ()
+{
+  long long foo[] =
+{
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+}
+
+void
+f (long long=-1,long long=-1,long long=-1,long long=-1,
+   long long=-1,long long=-1,long long arg7_on_stack=-1)
+{
+  throw 0;
+}
+
+void
+g()
+{
+  try
+{
+  f ();
+}
+  catch (int)
+{
+}
+}
+
+int
+main()
+{
+  fillstack ();
+  g ();
+  return 0;
+}
-- 
2.17.1



Re: [PATCH] assume sprintf formatting of wide characters may fail (PR 86853)

2018-08-20 Thread Jeff Law
On 08/20/2018 01:05 PM, David Edelsohn wrote:
> builtin-sprintf-warn-1.c, builtin-sprintf-warn-2.c, and
> builtin-sprintf-11.c now are failing on AIX.  I expect that at least part
> of the reason is 32 bit AIX uses 16 bit wchar_t
> 
> #ifdef __64BIT__
> typedef unsigned intwchar_t;
> #else
> typedef unsigned short  wchar_t;
> #endif /* __64BIT__ */
> 
> Are the new warnings making assumptions about the width of wchar_t?
> 
> Do we want to skip some of these tests on AIX?Joseph, Martin and myself are 
> discussing how to handle a 2 byte wchar_t.
 Yes, there's a broken assumption in the sprintf code for that case.

jeff


Re: [PATCH] assume sprintf formatting of wide characters may fail (PR 86853)

2018-08-20 Thread David Edelsohn
builtin-sprintf-warn-1.c, builtin-sprintf-warn-2.c, and
builtin-sprintf-11.c now are failing on AIX.  I expect that at least part
of the reason is 32 bit AIX uses 16 bit wchar_t

#ifdef __64BIT__
typedef unsigned intwchar_t;
#else
typedef unsigned short  wchar_t;
#endif /* __64BIT__ */

Are the new warnings making assumptions about the width of wchar_t?

Do we want to skip some of these tests on AIX?

Thanks, David


Re: [PATCH][GCC][mid-end] Fix DSE big-endian subreg crash

2018-08-20 Thread Jeff Law
On 08/15/2018 06:57 AM, Tamar Christina wrote:
> Hi All,
> 
> This patch fixes an ICE that would happen when extract_low_bits
> is called with modes for which you can't extract a valid subreg.
> e.g. taking a 32 bytes subreg from a 48 byte mode.
> 
> The ICE happens because convert_modes which eventually calls
> simplify_gen_subreg does not expect the convertion to fail.
> 
> The assert in gen_lowpart_general would then be hit.  The patch
> changes it to validate the subreg before trying to convert the
> modes.  If the subreg is not possible we return NULL_RTX and bail
> out early.
> 
> I don't have a target independent test for this because it depends
> on the target having a 48byte mode and using it for loads.
> 
> Cross compiled and regtested on
>   aarch64_be-none-elf
> and no issues
> 
> Boostrapped and regtested
>  aarch64-none-linux-gnu
> 
> and found no issues.
> 
> Bootstrapped on 
>  x86_64-pc-linux-gnu
>  arm-none-linux-gnueabihf
> 
> and no issues.
> 
> Ok for trunk?
> 
> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 2018-08-15  Tamar Christina  
> 
>   * expmed.c (extract_low_bits): Reject invalid subregs early.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-08-15  Tamar Christina  
> 
>   * gcc.target/aarch64/large_struct_copy.c: New test.
> 
OK.
jeff


Re: [PATCH] x86: Always update EH return address in word_mode

2018-08-20 Thread Uros Bizjak
On Mon, Aug 20, 2018 at 8:19 PM, H.J. Lu  wrote:
> On x86, return address is always popped in word_mode.  eh_return needs
> to put EH return address in word_mode on stack.
>
> Tested on x86-64 with x32. OK for trunk and release branches?

OK. Perhaps the testcase should go into g++.dg/torture, since it is
sensitive to optimization level?

Thanks,
Uros.

> Thanks.
>
> H.J.
> ---
> gcc/
>
> PR target/87014
> * config/i386/i386.md (eh_return): Always update EH return
> address in word_mode.
>
> gcc/testsuite/
>
> PR target/87014
> * g++.dg/pr87014.C: New file.
> ---
>  gcc/config/i386/i386.md|  5 -
>  gcc/testsuite/g++.dg/pr87014.C | 38 ++
>  2 files changed, 42 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/g++.dg/pr87014.C
>
> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
> index 918241d953a..71faa218ffa 100644
> --- a/gcc/config/i386/i386.md
> +++ b/gcc/config/i386/i386.md
> @@ -13612,7 +13612,10 @@
>   stack address we wish to restore.  */
>tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
>tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
> -  tmp = gen_rtx_MEM (Pmode, tmp);
> +  /* Return address is always in word_mode.  */
> +  tmp = gen_rtx_MEM (word_mode, tmp);
> +  if (GET_MODE (ra) != word_mode)
> +ra = convert_to_mode (word_mode, ra, 1);
>emit_move_insn (tmp, ra);
>
>emit_jump_insn (gen_eh_return_internal ());
> diff --git a/gcc/testsuite/g++.dg/pr87014.C b/gcc/testsuite/g++.dg/pr87014.C
> new file mode 100644
> index 000..060ec948c90
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr87014.C
> @@ -0,0 +1,38 @@
> +// { dg-do run }
> +// { dg-options "-O0" }
> +
> +void
> +fillstack ()
> +{
> +  long long foo[] =
> +{
> +  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
> +};
> +}
> +
> +void
> +f (long long=-1,long long=-1,long long=-1,long long=-1,
> +   long long=-1,long long=-1,long long arg7_on_stack=-1)
> +{
> +  throw 0;
> +}
> +
> +void
> +g()
> +{
> +  try
> +{
> +  f ();
> +}
> +  catch (int)
> +{
> +}
> +}
> +
> +int
> +main()
> +{
> +  fillstack ();
> +  g ();
> +  return 0;
> +}
> --
> 2.17.1
>


Re: [PATCH] Handle TARGET_SPLIT_COMPLEX_ARG in default VA_ARG_EXPR implementation

2018-08-20 Thread Jeff Law
On 08/02/2018 03:17 AM, Chung-Lin Tang wrote:
> 2018-08-02  Chung-Lin Tang  
> 
> * targhooks.c (std_gimplify_va_arg_expr): Properly handle case of when
> 
> TARGET_SPLIT_COMPLEX_ARG is defined.
Thanks.  I've committed this to the trunk.
jeff


Re: [PATCH 3/3] Improve switch code emission for a balanced tree (PR tree-optimization/86847).

2018-08-20 Thread Jeff Law
On 08/07/2018 05:50 AM, marxin wrote:
> This is the most complex patch. It follows original implementation and
> does following improvements that were part of original code:
> 
> a) for a node with both children (that don't have children) and only single 
> case
> values handled: emit series of 3 compares and jump to default
> b) for a node with only one child (that doesn't have a child) and only single
> case values handled: emit 2 compares and jump to default
> c) for a node of a range without a child, emit if (index - low) <= (high - 
> low))
> d) profile emission is precise, taken also from previous implementation
> 
> These changes + VRP should move us back to code quality we had in GCC 8.
> 
> gcc/ChangeLog:
> 
> 2018-08-13  Martin Liska  
> 
> PR tree-optimization/86847
>   * tree-switch-conversion.c (switch_decision_tree::dump_case_nodes):
> Dump also subtree probability.
>   (switch_decision_tree::do_jump_if_equal): New function.
>   (switch_decision_tree::emit_case_nodes): Handle special
> situations in balanced tree that can be emitted much simpler.
> Fix calculation of probabilities that happen in tree expansion.
>   * tree-switch-conversion.h (struct cluster): Add
> is_single_value_p.
>   (struct simple_cluster): Likewise.
>   (struct case_tree_node): Add new function has_child.
>   (do_jump_if_equal): New.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-08-13  Martin Liska  
> 
>   * gcc.dg/tree-ssa/switch-3.c: New test.
>   * gcc.dg/tree-ssa/vrp105.c: Remove.
Presumably the new expansion strategies totally compromise vrp105.  Too
bad, that test has actually caught oversights a few times for me in
recent history.   But I can live with it disappearing.



> diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
> index cd771438214..78914bbe81a 100644
> --- a/gcc/tree-switch-conversion.c
> +++ b/gcc/tree-switch-conversion.c
> @@ -2054,6 +2056,33 @@ switch_decision_tree::emit_cmp_and_jump_insns 
> (basic_block bb, tree op0,
>return false_edge->dest;
>  }
>  
> +/* Generate code to jump to LABEL if OP0 and OP1 are equal in mode MODE.
> +   PROB is the probability of jumping to LABEL_BB.  */
> +
> +basic_block
> +switch_decision_tree::do_jump_if_equal (basic_block bb, tree op0, tree op1,
> + basic_block label_bb,
> + profile_probability prob)
MODE isn't a parameter and probably shouldn't show up in the function
comment.  Please document BB in the function comment.

OK with the comment fix.

jeff



Re: [PATCH, Darwin] Do not run dsymutil automatically, when -save-temps is on the command line.

2018-08-20 Thread Mike Stump
On Aug 18, 2018, at 1:17 PM, Iain Sandoe  wrote:
> 
> The point of running dsymutil automatically from collect2 is that it
> (collect2, lto-wrapper, etc) might be generating or using compiler
> temporary files that will be deleted at the end of the link process.
> 
> dsymutil requires that it can see the objects actually used in the link
> since it actually picks up the debug info from those, rather than the
> linked exe.
> 
> When “-save-temps” is given, the objects should be preserved (if they
> are not, then that’s a bug) and therefore we don’t need to run dsymutil
> automatically.
> 
> The debug experience can be better with GDB + the original objects for
> some permutations of dsymutil / GDB.
> 
> Opinions? 

So, I think of -save-temps as a debugging thing, and as such, kinda don't want 
it to change anything.  I don't think people use this in production to manage 
their builds.

I think it's an over optimization.

[PATCH] x86: Always update EH return address in word_mode

2018-08-20 Thread H.J. Lu
On x86, return address is always popped in word_mode.  eh_return needs
to put EH return address in word_mode on stack.

Tested on x86-64 with x32. OK for trunk and release branches?

Thanks.

H.J.
---
gcc/

PR target/87014
* config/i386/i386.md (eh_return): Always update EH return
address in word_mode.

gcc/testsuite/

PR target/87014
* g++.dg/pr87014.C: New file.
---
 gcc/config/i386/i386.md|  5 -
 gcc/testsuite/g++.dg/pr87014.C | 38 ++
 2 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/pr87014.C

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 918241d953a..71faa218ffa 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13612,7 +13612,10 @@
  stack address we wish to restore.  */
   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
-  tmp = gen_rtx_MEM (Pmode, tmp);
+  /* Return address is always in word_mode.  */
+  tmp = gen_rtx_MEM (word_mode, tmp);
+  if (GET_MODE (ra) != word_mode)
+ra = convert_to_mode (word_mode, ra, 1);
   emit_move_insn (tmp, ra);
 
   emit_jump_insn (gen_eh_return_internal ());
diff --git a/gcc/testsuite/g++.dg/pr87014.C b/gcc/testsuite/g++.dg/pr87014.C
new file mode 100644
index 000..060ec948c90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr87014.C
@@ -0,0 +1,38 @@
+// { dg-do run }
+// { dg-options "-O0" }
+
+void
+fillstack ()
+{
+  long long foo[] =
+{
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+}
+
+void
+f (long long=-1,long long=-1,long long=-1,long long=-1,
+   long long=-1,long long=-1,long long arg7_on_stack=-1)
+{
+  throw 0;
+}
+
+void
+g()
+{
+  try
+{
+  f ();
+}
+  catch (int)
+{
+}
+}
+
+int
+main()
+{
+  fillstack ();
+  g ();
+  return 0;
+}
-- 
2.17.1



Re: [PATCH][Middle-end]patch for fixing PR 86519

2018-08-20 Thread Qing Zhao
Hi, Rainer,

thanks a lot to report the issues with mips and sparc platform.

Yes, looks like even on the assembly level, the string scanning still not 
reliable on different platforms.

I agree with Jeff’s suggestion to apply different search result for different 
platforms.

I will update the testcase with this approach soon.

Qing
> On Aug 20, 2018, at 3:57 AM, Rainer Orth  
> wrote:
> 
> Hi Jeff,
> 
>> On 08/17/2018 09:43 PM, Paul Hua wrote:
>>> Hi Qing:
>>> 
 
 the change has been committed as:
 https://gcc.gnu.org/viewcvs/gcc?view=revision=263563
 
 
 Qing
 
>>> 
>>> The strcmpopt_6.c test still fails on mips64el target.
>>> 
>>> gcc.dg/strcmpopt_6.c: memcmp found 4 times
>>> FAIL: gcc.dg/strcmpopt_6.c scan-assembler-times memcmp 2
>>> 
>>> 
>>> The mips asm output have ".reloc" info.
>>> 
>>> -
>>>ld  $5,%got_page(.LC0)($28)
>>>ld  $25,%call16(memcmp)($28)
>>>li  $6,3# 0x3
>>>sd  $31,8($sp)
>>>.reloc  1f,R_MIPS_JALR,memcmp
>>> 1:  jalr$25
>>>daddiu  $5,$5,%got_ofst(.LC0)
>>> 
>>> 
>>> scan-assembler find "4" times.
>> Ugh.  :(  There's probably other targets that are going to have similar
>> properties.  I'm not really sure how to write a suitable assembler test
>> for this.
>> 
>> Maybe we just need a different search result for MIPS (and potentially
>> other targets).
> 
> we certainly do: I've reported a similar issue on sparc in PR
> testsuite/86519, but powerpc and s390x are equally affected.
> 
>   Rainer
> 
> -- 
> -
> Rainer Orth, Center for Biotechnology, Bielefeld University



[CPP PATCH] node field bits

2018-08-20 Thread Nathan Sidwell
Last bit of cleanup in the preprocessor.  We only need 2 bits to hold 
the node_type enumeration, and 8 bits for the flags.


That leaves several unused bits, which we may as well note.

nathan
--
Nathan Sidwell
2018-08-20  Nathan Sidwell  

	* include/cpplib.h: Fixup some whitespace.
	(cpp_hashnode): Reduce type to 2 bit & flags to 8.

Index: include/cpplib.h
===
--- include/cpplib.h	(revision 263667)
+++ include/cpplib.h	(working copy)
@@ -813,8 +813,10 @@ struct GTY(()) cpp_hashnode {
 	   then index into directive table.
 	   Otherwise, a NODE_OPERATOR.  */
   unsigned char rid_code;		/* Rid code - for front ends.  */
-  ENUM_BITFIELD(node_type) type : 6;	/* CPP node type.  */
-  unsigned int flags : 10;		/* CPP flags.  */
+  ENUM_BITFIELD(node_type) type : 2;	/* CPP node type.  */
+  unsigned int flags : 8;		/* CPP flags.  */
+
+  /* 6 bits spare (plus another 32 on 64-bit hosts).  */
 
   union _cpp_hashnode_value GTY ((desc ("%1.type"))) value;
 };
@@ -940,7 +942,6 @@ extern const cpp_token *cpp_get_token_wi
 inline bool cpp_user_macro_p (const cpp_hashnode *node)
 {
   return node->type == NT_USER_MACRO;
-
 }
 inline bool cpp_builtin_macro_p (const cpp_hashnode *node)
 {
@@ -950,6 +951,7 @@ inline bool cpp_macro_p (const cpp_hashn
 {
   return node->type & NT_MACRO_MASK;
 }
+
 /* Returns true if NODE is a function-like user macro.  */
 inline bool cpp_fun_like_macro_p (cpp_hashnode *node)
 {


[libiberty patch] PEX-unix forking

2018-08-20 Thread Nathan Sidwell
This is the first of a pair of patches I've had on the modules branch 
for a while.  They improve the error behaviour in the case of child 
failure when vfork is the forking mechanism.


This one commonizes the error paths in the parent and child to a pair of 
single blocks that print or return the error respectively.  Currently 
each error case calls pex_child_error, or returns the error in the parent.


The patch records the name of a failing system call, and uses that to 
print or return the error.  It doesn't change functionality but will 
simplify the next patch that does.


booted on x86_64-linux (which uses vfork), ok?

nathan
--
Nathan Sidwell
2018-08-20  Nathan Sidwell  

	* pex-unix.c (pex_child_error): Delete.
	(pex_unix_exec_child): Commonize error paths to single message &
	exit.

Index: pex-unix.c
===
--- pex-unix.c	(revision 263667)
+++ pex-unix.c	(working copy)
@@ -298,8 +298,6 @@ pex_wait (struct pex_obj *obj, pid_t pid
 #endif /* ! defined (HAVE_WAITPID) */
 #endif /* ! defined (HAVE_WAIT4) */
 
-static void pex_child_error (struct pex_obj *, const char *, const char *, int)
- ATTRIBUTE_NORETURN;
 static int pex_unix_open_read (struct pex_obj *, const char *, int);
 static int pex_unix_open_write (struct pex_obj *, const char *, int, int);
 static pid_t pex_unix_exec_child (struct pex_obj *, int, const char *,
@@ -366,28 +364,6 @@ pex_unix_close (struct pex_obj *obj ATTR
   return close (fd);
 }
 
-/* Report an error from a child process.  We don't use stdio routines,
-   because we might be here due to a vfork call.  */
-
-static void
-pex_child_error (struct pex_obj *obj, const char *executable,
-		 const char *errmsg, int err)
-{
-  int retval = 0;
-#define writeerr(s) retval |= (write (STDERR_FILE_NO, s, strlen (s)) < 0)
-  writeerr (obj->pname);
-  writeerr (": error trying to exec '");
-  writeerr (executable);
-  writeerr ("': ");
-  writeerr (errmsg);
-  writeerr (": ");
-  writeerr (xstrerror (err));
-  writeerr ("\n");
-#undef writeerr
-  /* Exit with -2 if the error output failed, too.  */
-  _exit (retval == 0 ? -1 : -2);
-}
-
 /* Execute a child.  */
 
 #if defined(HAVE_SPAWNVE) && defined(HAVE_SPAWNVPE)
@@ -592,21 +568,22 @@ pex_unix_exec_child (struct pex_obj *obj
  int in, int out, int errdes,
 		 int toclose, const char **errmsg, int *err)
 {
-  pid_t pid;
+  pid_t pid = -1;
 
   /* We declare these to be volatile to avoid warnings from gcc about
  them being clobbered by vfork.  */
-  volatile int sleep_interval;
+  volatile int sleep_interval = 1;
   volatile int retries;
 
   /* We vfork and then set environ in the child before calling execvp.
  This clobbers the parent's environ so we need to restore it.
  It would be nice to use one of the exec* functions that takes an
- environment as a parameter, but that may have portability issues.  */
+ environment as a parameter, but that may have portability
+ issues.   */
   char **save_environ = environ;
 
-  sleep_interval = 1;
-  pid = -1;
+  const char *bad_fn = NULL;
+
   for (retries = 0; retries < 4; ++retries)
 {
   pid = vfork ();
@@ -625,57 +602,76 @@ pex_unix_exec_child (struct pex_obj *obj
 
 case 0:
   /* Child process.  */
-  if (in != STDIN_FILE_NO)
+  if (!bad_fn && in != STDIN_FILE_NO)
 	{
 	  if (dup2 (in, STDIN_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
-	  if (close (in) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "dup2";
+	  else if (close (in) < 0)
+	bad_fn = "close";
 	}
-  if (out != STDOUT_FILE_NO)
+  if (!bad_fn && out != STDOUT_FILE_NO)
 	{
 	  if (dup2 (out, STDOUT_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
-	  if (close (out) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "dup2";
+	  else if (close (out) < 0)
+	bad_fn = "close";
 	}
-  if (errdes != STDERR_FILE_NO)
+  if (!bad_fn && errdes != STDERR_FILE_NO)
 	{
 	  if (dup2 (errdes, STDERR_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
-	  if (close (errdes) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "dup2";
+	  else if (close (errdes) < 0)
+	bad_fn = "close";
 	}
-  if (toclose >= 0)
+  if (!bad_fn && toclose >= 0)
 	{
 	  if (close (toclose) < 0)
-	pex_child_error (obj, executable, "close", errno);
+	bad_fn = "close";
 	}
-  if ((flags & PEX_STDERR_TO_STDOUT) != 0)
+  if (!bad_fn && (flags & PEX_STDERR_TO_STDOUT) != 0)
 	{
 	  if (dup2 (STDOUT_FILE_NO, STDERR_FILE_NO) < 0)
-	pex_child_error (obj, executable, "dup2", errno);
+	bad_fn = "dup2";
 	}
-
-  if (env)
+  if (!bad_fn)
 	{
-	  /* NOTE: In a standard vfork implementation this clobbers the
-	 parent's copy of environ "too" (in reality there's only one copy).
-	 This is ok as we restore it below.  */
-	  

Re: [PATCH] Optimize more boolean functions

2018-08-20 Thread Marc Glisse

On Mon, 20 Aug 2018, MCC CS wrote:


this patch optimizes ~(~x | y), (~x | y) & (x | ~y) and
(~x | y) ^ (x | ~y).


Thank you. I didn't mean to force you to add the extra transformations to 
your patch, but now that they are here, that's good :-)



gcc/
PR tree-optimization/87009
* match.pd: Improve boolean optimizations


(maybe the mailer ate the initial TAB)
"." at the end of the description.
Maybe "new" instead of "improve" since you are adding new transformations 
and not modifying existing ones.
Some people list the patterns in parentheses here, but not all, so I guess 
that's ok.



gcc/testsuite/
PR tree-optimization/87009
* gcc.dg/pr87009.c: Add boolean optimization tests


You can simply go with "New file." or "New test.", like most entries in 
this ChangeLog, though the longer version is ok.



Index: gcc/match.pd
===
--- gcc/match.pd (revision 263646)
+++ gcc/match.pd (working copy)
@@ -776,6 +776,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_not (bit_and:cs (bit_not @0) @1))
(bit_ior @0 (bit_not @1)))

+/* ~(~a | b) --> a & ~b */
+(simplify
+ (bit_not (bit_ior:cs (bit_not @0) @1))
+ (bit_and @0 (bit_not @1)))
+
/* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */
#if GIMPLE
(simplify
@@ -981,6 +986,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0)))
(bit_and @0 @1))

+/* (~x | y) & (x | ~y) -> ~(x ^ y) */
+(simplify
+ (bit_and (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
+ (bit_not (bit_xor @0 @1)))
+
+/* (~x | y) ^ (x | ~y) -> x ^ y */
+(simplify
+ (bit_xor (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
+ (bit_xor @0 @1))
+


For what it's worth, I think that's good, though you need to wait for an 
official reviewer.


(I wondered about a single_use check on the second transformation, but I 
hope it isn't needed)



/* ~x & ~y -> ~(x | y)
~x | ~y -> ~(x & y) */
(for op (bit_and bit_ior)
Index: gcc/testsuite/gcc.dg/pr87009.c
===
--- gcc/testsuite/gcc.dg/pr87009.c (nonexistent)
+++ gcc/testsuite/gcc.dg/pr87009.c (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */


If -O is sufficient, that would be better.


+/* { dg-final { scan-tree-dump-times " \\^ " 4 "original" } } */


You may also want to check that there are no unexpected &|~ , to be sure 
that you are getting the expected output.



+
+int f1 (int x, int s)
+{
+ return ~(~(x|s)|x)|~(~(x|s)|s);
+}
+
+int f2 (int x, int s)
+{
+ return ~(~(~x)&~(x&~s));
+}
+
+int f3 (int x, int s)
+{
+ return ~((x|~s)&(~x|s));
+}
+
+int f4 (int x, int s)
+{
+ return (~x|s)&(x|~s);
+}



--
Marc Glisse


Re: [Patch][Aarch64] Implement Aarch64 SIMD ABI and aarch64_vector_pcs attribute

2018-08-20 Thread Steve Ellcey
On Tue, 2018-08-07 at 12:15 -0500, Segher Boessenkool wrote:

> > +/* { dg-final { scan-assembler-not "\[ \t\]stp\tq\[01234567\]" } }
> > */
> That's [0-7] but maybe you find [01234567] more readable here.

Segher,  I fixed all the issues you pointed out except this one.  Since
there are some uses of non consecutive numbers in one of the tests I 
decided to leave [01234567] instead of using [0-7].  Here is the 
latest version of the patch, there are no semantic changes, just
syntactical ones to address the issues that you pointed out.

Steve Ellcey
sell...@cavium.com


2018-08-20  Steve Ellcey  

* config/aarch64/aarch64-protos.h (aarch64_use_simple_return_insn_p):
New prototype.
(aarch64_epilogue_uses): Ditto.
* config/aarch64/aarch64.c (aarch64_attribute_table): New array.
(aarch64_simd_decl_p): New function.
(aarch64_reg_save_mode): New function.
(aarch64_is_simd_call_p): New function.
(aarch64_function_ok_for_sibcall): Check for simd calls.
(aarch64_layout_frame): Check for simd function.
(aarch64_gen_storewb_pair): Handle E_TFmode.
(aarch64_push_regs): Use aarch64_reg_save_mode to get mode.
(aarch64_gen_loadwb_pair): Handle E_TFmode.
(aarch64_pop_regs): Use aarch64_reg_save_mode to get mode.
(aarch64_gen_store_pair): Handle E_TFmode.
(aarch64_gen_load_pair): Ditto.
(aarch64_save_callee_saves): Handle different mode sizes.
(aarch64_restore_callee_saves): Ditto.
(aarch64_components_for_bb): Check for simd function.
(aarch64_epilogue_uses): New function.
(aarch64_process_components): Check for simd function.
(aarch64_expand_prologue): Ditto.
(aarch64_expand_epilogue): Ditto.
(aarch64_expand_call): Ditto.
(TARGET_ATTRIBUTE_TABLE): New define.
* config/aarch64/aarch64.h (EPILOGUE_USES): Redefine.
(FP_SIMD_SAVED_REGNUM_P): New macro.
* config/aarch64/aarch64.md (V23_REGNUM) New constant.
(simple_return): New define_expand.
(load_pair_dw_tftf): New instruction.
(store_pair_dw_tftf): Ditto.
(loadwb_pair_): Ditto.
("storewb_pair_): Ditto.

2018-08-20  Steve Ellcey  

* gcc.target/aarch64/torture/aarch64-torture.exp: New file.
* gcc.target/aarch64/torture/simd-abi-1.c: New test.
* gcc.target/aarch64/torture/simd-abi-2.c: Ditto.
* gcc.target/aarch64/torture/simd-abi-3.c: Ditto.
* gcc.target/aarch64/torture/simd-abi-4.c: Ditto.diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index af5db9c..99c962f 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -423,6 +423,7 @@ bool aarch64_split_dimode_const_store (rtx, rtx);
 bool aarch64_symbolic_address_p (rtx);
 bool aarch64_uimm12_shift (HOST_WIDE_INT);
 bool aarch64_use_return_insn_p (void);
+bool aarch64_use_simple_return_insn_p (void);
 const char *aarch64_mangle_builtin_type (const_tree);
 const char *aarch64_output_casesi (rtx *);
 
@@ -507,6 +508,8 @@ void aarch64_split_simd_move (rtx, rtx);
 /* Check for a legitimate floating point constant for FMOV.  */
 bool aarch64_float_const_representable_p (rtx);
 
+extern int aarch64_epilogue_uses (int);
+
 #if defined (RTX_CODE)
 void aarch64_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode,
    rtx label_ref);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index fa01475..9cffec8 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1027,6 +1027,15 @@ static const struct processor *selected_tune;
 /* The current tuning set.  */
 struct tune_params aarch64_tune_params = generic_tunings;
 
+/* Table of machine attributes.  */
+static const struct attribute_spec aarch64_attribute_table[] =
+{
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+   affects_type_identity, handler, exclude } */
+  { "aarch64_vector_pcs", 0, 0, true,  false, false, false, NULL, NULL },
+  { NULL, 0, 0, false, false, false, false, NULL, NULL }
+};
+
 #define AARCH64_CPU_DEFAULT_FLAGS ((selected_cpu) ? selected_cpu->flags : 0)
 
 /* An ISA extension in the co-processor and main instruction set space.  */
@@ -1405,6 +1414,31 @@ aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode)
   return false;
 }
 
+/* Return true if this is a definition of a vectorized simd function.  */
+
+static bool
+aarch64_simd_decl_p (tree fndecl)
+{
+  if (lookup_attribute ("aarch64_vector_pcs", DECL_ATTRIBUTES (fndecl)) != NULL)
+return true;
+  if (lookup_attribute ("simd", DECL_ATTRIBUTES (fndecl)) == NULL)
+return false;
+  return (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl;
+}
+
+/* Return the mode a register save/restore should use.  DImode for integer
+   registers, DFmode for FP registers in non-SIMD functions (they only save
+   the bottom half of a 128 bit register), or 

Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Bernd Edlinger


On 08/20/18 12:23, Richard Biener wrote:
> On Sun, 19 Aug 2018, Bernd Edlinger wrote:
> 
>> Hi,
>>
>>
>> I rebased my range computation patch to current trunk,
>> and updated it according to what was discussed here.
>>
>> That means get_range_strlen has already a parameter
>> that is used to differentiate between ranges for warnings
>> and ranges for code-gen.
>>
>> That is called "strict", in the 4-parameter overload
>> and "fuzzy" in the internally used 7-parameter overload.
>>
>> So I added an "optimistic" parameter to my
>> get_inner_char_array_unless_typecast helper function.
>> That's it.
>>
>> Therefore at this time, there is only one warning regression
>> in one test case and one xfailed warning test case fixed.
>>
>> So that is par on the warning regression side.
>>
>> The failed test case is gcc/testsuite/gcc.dg/pr83373.c which
>> uses -fassume-zero-terminated-char-arrays, to enable the
>> (unsafe) feedback from string-length information to VRP to
>> suppress the warning.
>>
>> The 5 test cases that were designed to check the optimized
>> tree dump have to use the new -fassume-zero-terminated-char-arrays
>> option, but that is what we agreed upon.
>>
>> The patch is not dependent on any other patches.
>>
>>
>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>> Is it OK for trunk?
> 
> +  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
> 
> I'm not convinced you are testing anything useful here.
> TREE_OPERAND (base, 1) might be a pointer which means it's type
> doesn't have any semantics so you are testing the access type
> against "random".  If you'd restrict this to ADDR_EXPRs and
> look at the objects declared type then you'd still miss
> type-changes from a dynamic type that is different from what
> is declared.
> 

This whole function is only used for warnings or if the test case
asks for unsafe optimization via -ffassume-zero-terminated-char-arrays.

So yes, it is understood, but it has proven to be an oracle with
99.9% likelihood to give the right answer.

> So my conclusion is if you really want to not want to return
> arg for things that look like a type cast then you have to
> unconditionally return NULL_TREE.

Yes. :-)

> 
> +  || TREE_CODE (base) == VIEW_CONVERT_EXPR
> +  /* Or other stuff that would be handled by get_inner_reference.  */
> 
> simply use || handled_component_p (base) for the above and the rest
> to be sure to handle everything that is not stripped above.
> 
> +  || TREE_CODE (base) == BIT_FIELD_REF
> +  || TREE_CODE (base) == REALPART_EXPR
> +  || TREE_CODE (base) == IMAGPART_EXPR)
> +return NULL_TREE;
> 

Yes, good point.

> Btw, you are always returning the passed arg or NULL_TREE so
> formulating this as a predicate function makes uses easier.
> Not sure why it is called "inner" char array?
> 
;

Yes, in a previous version of this patch, this function actually
walked towards the innermost array, and returned that, but I dropped
that part, as it caused too many test cases regress.

So agreed, I think I will convert that to a _p function and think
of a better name.


> There do seem to be independently useful fixes in the patch that
> I'd approve immediately.
> 

Yes, I found some peanuts on my way.

For instance this fix for PR middle-end/86121 survives bootstrap on
it's own, and fixes one xfail.

Is it OK for trunk?

> Btw, I don't think we want sth like
> flag_assume_zero_terminated_char_arrays or even make it default at
> -Ofast.
> 

Yes, I agree.  Is there a consensus about this?

If yes, I go ahead and remove that option again.

BTW: I needed this option in a few test cases, that insist in checking the
optimizer to eliminate stuff, based on the VRP info. (6 +/-1 or so).

But we can as well remove those test cases.


Bernd.
2018-08-20  Bernd Edlinger  

	PR middle-end/86121
	* tree-ssa-strlen.c (adjust_last_stmt): Avoid folding away undefined
	behaviour.

testsuite:
2018-08-20  Bernd Edlinger  

	PR middle-end/86121
	* gcc.dg/Wstringop-overflow-6.c: Remove xfail.

diff -ur gcc/testsuite/gcc.dg/Wstringop-overflow-6.c gcc/testsuite/gcc.dg/Wstringop-overflow-6.c
--- gcc/testsuite/gcc.dg/Wstringop-overflow-6.c	2018-06-12 20:05:13.0 +0200
+++ gcc/testsuite/gcc.dg/Wstringop-overflow-6.c	2018-08-20 14:53:55.605350343 +0200
@@ -25,7 +25,7 @@
 
 void test_strcpy_strcat_2 (void)
 {
-  strcpy (a2, "12"), strcat (a2, "3");   /* { dg-warning "\\\[-Wstringop-overflow=]" "bug 86121" { xfail *-*-* } } */
+  strcpy (a2, "12"), strcat (a2, "3");   /* { dg-warning "\\\[-Wstringop-overflow=]" } */
 

Re: [PATCH v3 01/10] Initial TI PRU GCC port

2018-08-20 Thread Jeff Law
On 08/15/2018 10:49 PM, Dimitar Dimitrov wrote:
> ChangeLog:
> 
> 2018-07-27  Dimitar Dimitrov  
> 
>   * configure: Regenerate.
>   * configure.ac: Add PRU target.
> 
> gcc/ChangeLog:
> 
> 2018-07-27  Dimitar Dimitrov  
> 
>   * common/config/pru/pru-common.c: New file.
>   * config.gcc: Add PRU target.
>   * config/pru/alu-zext.md: New file.
>   * config/pru/constraints.md: New file.
>   * config/pru/predicates.md: New file.
>   * config/pru/pru-opts.h: New file.
>   * config/pru/pru-passes.c: New file.
>   * config/pru/pru-pragma.c: New file.
>   * config/pru/pru-protos.h: New file.
>   * config/pru/pru.c: New file.
>   * config/pru/pru.h: New file.
>   * config/pru/pru.md: New file.
>   * config/pru/pru.opt: New file.
>   * config/pru/t-pru: New file.
>   * doc/extend.texi: Document PRU pragmas.
>   * doc/invoke.texi: Document PRU-specific options.
>   * doc/md.texi: Document PRU asm constraints.

> 
> Signed-off-by: Dimitar Dimitrov 
> 
> diff --git a/gcc/config/pru/alu-zext.md b/gcc/config/pru/alu-zext.md
> new file mode 100644
> index 000..2112b08d3f4
> --- /dev/null
> +++ b/gcc/config/pru/alu-zext.md
[ ... ]
I wonder if the zero-extensions in alu-zext.md are really needed.  Can
we define WORD_REGISTER_OPERATIONS for PRU?  Or do you really want to
expose sub-word operations?  I simply don't know enough about the
hardware to provide guidance here.  But it might allow for some
simplification of the port.  You wouldn't want to define sub-word
patterns such as addqi/addhi anymore either.








> diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c
> new file mode 100644
> index 000..de72d22278e
> --- /dev/null
> +++ b/gcc/config/pru/pru.c
> @@ -0,0 +1,3001 @@

> +/* Emit efficient RTL equivalent of ADD3 with the given const_int for
> +   frame-related registers.
> + op0   - Destination register.
> + op1   - First addendum operand (a register).
> + addendum - Second addendum operand (a constant).
> + kind  - Note kind.  REG_NOTE_MAX if no note must be added.
> + reg_note_rtx - Reg note RTX.  NULL if it should be computed 
> automatically.
> + */
> +static rtx
> +pru_add3_frame_adjust (rtx op0, rtx op1, int addendum,
> +const enum reg_note kind, rtx reg_note_rtx)
> +{
> +  rtx insn;
> +
> +  rtx op0_adjust = gen_rtx_SET (op0, plus_constant (Pmode, op1, addendum));
> +
> +  if (UBYTE_INT (addendum) || UBYTE_INT (-addendum))
> +insn = emit_insn (op0_adjust);
> +  else
> +{
> +  /* Help the compiler to cope with an arbitrary integer constant.
> +  Reload has finished so we can't expect the compiler to
> +  auto-allocate a temporary register.  But we know that call-saved
> +  registers are not live yet, so we utilize them.  */
Note I think this can run afoul of IPA-RA.  THough it looks like you're
exposing this in RTL, so you're probably safe.

> +/* Emit function epilogue.  */
> +void
> +pru_expand_epilogue (bool sibcall_p)
> +{
> +  rtx cfa_adj;
> +  int total_frame_size;
> +  int sp_adjust, save_offset;
> +  int regno_start;
> +
> +  if (!sibcall_p && pru_can_use_return_insn ())
> +{
> +  emit_jump_insn (gen_return ());
> +  return;
> +}
> +
> +  emit_insn (gen_blockage ());
> +
> +  total_frame_size = pru_compute_frame_layout ();
> +  if (frame_pointer_needed)
> +{
> +  /* Recover the stack pointer.  */
> +  cfa_adj = plus_constant (Pmode, stack_pointer_rtx,
> +(total_frame_size
> + - cfun->machine->save_regs_offset));
> +  pru_add3_frame_adjust (stack_pointer_rtx,
> +  hard_frame_pointer_rtx,
> +  -cfun->machine->fp_save_offset,
> +  REG_CFA_DEF_CFA,
> +  cfa_adj);
> +
> +  save_offset = 0;
> +  sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
> +}
> +  else if (!UBYTE_INT (total_frame_size))
> +{
> +  pru_add_to_sp (cfun->machine->save_regs_offset,
> + REG_CFA_ADJUST_CFA);
> +  save_offset = 0;
> +  sp_adjust = total_frame_size - cfun->machine->save_regs_offset;
> +}
> +  else
> +{
> +  save_offset = cfun->machine->save_regs_offset;
> +  sp_adjust = total_frame_size;
> +}
> +
> +  regno_start = 0;
> +  do {
> +  regno_start = xbbo_next_reg_cluster (regno_start, _offset, false);
> +  } while (regno_start >= 0);
> +
> +  if (sp_adjust)
> +  pru_add_to_sp (sp_adjust, REG_CFA_ADJUST_CFA);
> +
> +  if (!sibcall_p)
> +emit_jump_insn (gen_simple_return ());
Note you probably need a blockage before the restore of the stack
pointer to avoid some really nasty problems with the scheduler
reordering things such that the current frame gets deallocated before
register restores happen.  It usually doesn't cause a problem, but if an
interrupt occurs between the 

[PATCH] XFAIL 18_support/new_nothrow.cc on AIX

2018-08-20 Thread David Edelsohn
18_support/new_nothrow.cc relies upon overriding operator new.  This is not
enabled by default in libstdc++ on AIX.  This patch XFAILs the testcase.

Bootstrapped on powerpc-ibm-aix7.2.0.0

Okay?

Thanks, David

* testsuite/18_support/new_nothrow.cc: XFAIL on AIX.

Index: 18_support/new_nothrow.cc
===
--- 18_support/new_nothrow.cc   (revision 263658)
+++ 18_support/new_nothrow.cc   (working copy)
@@ -16,6 +16,7 @@
 // .

 // { dg-do run }
+// { dg-xfail-run-if "AIX operator new" { powerpc-ibm-aix* } }

 #include 
 #include 


[CPP PATCH] node type

2018-08-20 Thread Nathan Sidwell
Finally, this gets to clean up the convoluted way the preprocessor marks 
the type of identifier nodes.  Right now it's a combination of a type 
field and a pair of flags, which gives rise to some convoluted tests and 
remapping for GTY.  This patch rationalizes it by using the type field 
exclusively.


Rather than a single NT_MACRO type, we now have NT_USER_MACRO and 
NT_BUILTIN_MACRO types.  Checking for either of them is a simple bit 
mask, as there's a unique set bit they share.  NT_MACRO_MASK is that bit.


Another change is that NT_ASSERTION is not needed.  Assertions are in a 
disjoint namespace (by prepending '#'), and we can simply use the 
non-nullness of the answers field to know there's an assert (possibly 
checking for NT_VOID if we're looking at an arbitrary node).  We have to 
set the answer field to NULL when clearing a node -- before we could 
leave a dangling pointer.


With NT_MACRO_ARG replacing NODE_MACRO_ARG we have exactly 4 NT_$FOO 
values (which is what we had before), but we free up 2 NODE_ flags, 
which is nice.  The NT_ values directly map to the GTY machinery, so we 
don't need a translation layer anymore.


booted and tested on x86_64-linux.  applying to trunk.

nathan
--
Nathan Sidwell
2018-08-20  Nathan Sidwell  

	* include/cpplib.h (NODE_BUILTIN, NODE_MACRO_ARG): Delete.
	Renumber others.
	(enum node_type): Replace NT_MACRO with NT_USER_MACRO,
	NT_BUILTIN_MACRO, NT_MACRO_ARG.  Delete NT_ASSERTION.
	(NTV_MACRO, NTV_ANSWER, NTV_BUILTIN, NTV_ARGUMENT, NTV_NONE):
	Delete.
	(CPP_HASHNODE_VALUE_IDX): Delete.
	(union _cpp_hashnode_value): GTY tag from enum node_type directly.
	(struct cpp_hashnode): Adjust GTY desc for value field.
	(cpp_user_macro_p, cpp_builtin_macro_p, cpp_macro_p): Adjust.
	* directives.c (undefine_macros): Clear value.anwers, adjust flag
	clearing.
	(_cpp_test_assertion): No need to check NT_ASSERTION.
	(do_assert, do_unassert): Likewise.
	* init.c (cpp_init_special_builtins): Set type not flags.
	* macro.c (struct macro_arg_saved_data): Add type field.
	(cpp_get_token_1): Check type not NT_VOID.
	(_cpp_free_definition): Adjust flag clearing.  Nullify
	value.answers.
	(_cpp_save_parameter, _cpp_unsave_parameters): Save and restore
	type.
	(lex_expansion_token): Check type not flags.
	(_cpp_create_definition): Set type to NT_USER_MACRO.
	(_cpp_notify_macro_use): Adjust type checking.
	* pch.c (write_macdef, count_defs, write_defs, cpp_valid_state)
	(save_macros): Adjust node type/flag handling.
	* traditional.c (_cpp_scan_out_logical_line): Check type not flags.

Index: directives.c
===
--- directives.c	(revision 263666)
+++ directives.c	(working copy)
@@ -695,7 +695,8 @@ undefine_macros (cpp_reader *pfile ATTRI
   /* Body of _cpp_free_definition inlined here for speed.
  Macros and assertions no longer have anything to free.  */
   h->type = NT_VOID;
-  h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+  h->value.answers = NULL;
+  h->flags &= ~(NODE_POISONED|NODE_DISABLED|NODE_USED);
   return 1;
 }
 
@@ -2217,9 +2218,10 @@ parse_answer (cpp_reader *pfile, int typ
 }
 
 /* Parses an assertion directive of type TYPE, returning a pointer to
-   the hash node of the predicate, or 0 on error.  If an answer was
-   supplied, it is placed in EXP_PTR & EXP_COUNT, which is otherwise
-   set to 0.  */
+   the hash node of the predicate, or 0 on error.  The node is
+   guaranteed to be disjoint from the macro namespace, so can only
+   have type 'NT_VOID'.  If an answer was supplied, it is placed in
+   *ANSWER_PTR, which is otherwise set to 0.  */
 static cpp_hashnode *
 parse_assertion (cpp_reader *pfile, int type, cpp_macro **answer_ptr)
 {
@@ -2294,7 +2296,7 @@ _cpp_test_assertion (cpp_reader *pfile,
 
   if (node)
 {
-  if (node->type == NT_ASSERTION)
+  if (node->value.answers)
 	*value = !answer || *find_answer (node, answer);
 }
   else if (pfile->cur_token[-1].type == CPP_EOF)
@@ -2315,7 +2317,7 @@ do_assert (cpp_reader *pfile)
 {
   /* Place the new answer in the answer list.  First check there
  is not a duplicate.  */
-  if (node->type == NT_ASSERTION && *find_answer (node, answer))
+  if (*find_answer (node, answer))
 	{
 	  cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted",
 		 NODE_NAME (node) + 1);
@@ -2327,10 +2329,8 @@ do_assert (cpp_reader *pfile)
 	(pfile, sizeof (cpp_macro) - sizeof (cpp_token)
 	 + sizeof (cpp_token) * answer->count);
 
-  if (node->type == NT_ASSERTION)
-	answer->parm.next = node->value.answers;
-
-  node->type = NT_ASSERTION;
+  /* Chain into the list.  */
+  answer->parm.next = node->value.answers;
   node->value.answers = answer;
 
   check_eol (pfile, false);
@@ -2345,7 +2345,7 @@ do_unassert (cpp_reader *pfile)
   cpp_hashnode *node = parse_assertion (pfile, T_UNASSERT, );
 
   /* It isn't an error to #unassert something that isn't asserted.  */
-  if (node && 

Re: [PATCH] Make GO string literals properly NUL terminated

2018-08-20 Thread Bernd Edlinger
On 08/20/18 15:19, Richard Biener wrote:
> On Mon, 20 Aug 2018, Bernd Edlinger wrote:
> 
>> On 08/20/18 13:01, Richard Biener wrote:
>>> On Wed, Aug 1, 2018 at 3:05 PM Bernd Edlinger  
>>> wrote:



 On 08/01/18 11:29, Richard Biener wrote:
>
> Hmm.  I think it would be nice if TREE_STRING_LENGTH would
> match char[2] and TYPE_SIZE_UNIT even if that is inconvenient
> for your check above.  Because the '\0' doesn't belong to the
> string.  Then build_string internally appends a '\0' outside
> of TREE_STRING_LENGTH.
>

 Hmm. Yes, but the outside-0 byte is just one byte, not a wide
 character.
>>>
>>> That could be fixed though (a wide 0 is just N 0s).  Add a elsz = 1
>>> parameter to build_string and allocate as many extra 0s as needed.
>>>
>>> There are STRING_CSTs which are not string literals,
 for instance attribute tags, Pragmas, asm constrants, etc.
 They use the '\0' outside, and have probably no TREE_TYPE.

>
>> So I would like to be able to assume that the STRING_CST objects
>> are internally always generated properly by the front end.
>
> Yeah, I guess we need to define what "properly" is ;)
>
 Yes.

>> And that the ARRAY_TYPE of the string literal either has the
>> same length than the TREE_STRING_LENGTH or if it is shorter,
>> this is always exactly one (wide) character size less than 
>> TREE_STRING_LENGTH
>
> I think it should be always the same...
>

 One could not differentiate between "\0" without zero-termination
 and "" with zero-termination, theoretically.
>>>
>>> Is that important?  Doesn't the C standard say how to parse string literals?
>>>
 We also have char x[100] = "ab";
 that is TREE_STRING_LENGTH=3, and TYPE_SIZE_UNIT(TREE_TYPE(x)) = 100.
 Of course one could create it with a TREE_STRING_LENGTH = 100,
 but imagine char x[1000] = "ab"
>>>
>>> The question is more about TYPE_SIZE_UNIT (TREE_TYPE ("ab")) which I
>>> hope matches "ab" and not 'x'.  If it matches 'x' then I'd rather have it
>>> unconditionally be [], thus incomplete (because the literals "size" depends
>>> on the context/LHS it is used on).
>>>
>>
>> Sorry, but I must say, it is not at all like that.
>>
>> If I compile x.c:
>> const char x[100] = "ab";
>>
>> and set a breakpoint at output_constant:
>>
>> Breakpoint 1, output_constant (exp=0x76ff9dc8, size=100, align=256,
>>   reverse=false) at ../../gcc-trunk/gcc/varasm.c:4821
>> 4821   if (size == 0 || flag_syntax_only)
>> (gdb) p size
>> $1 = 100
>> (gdb) call debug(exp)
>> "ab"
>> (gdb) p *exp
>> $2 = {base = {code = STRING_CST, side_effects_flag = 0, constant_flag = 1,
>> (gdb) p exp->typed.type->type_common.size_unit
>> $5 = (tree) 0x76ff9d80
>> (gdb) call debug(exp->typed.type->type_common.size_unit)
>> 100
>> (gdb) p exp->string.length
>> $6 = 3
>> (gdb) p exp->string.str[0]
>> $8 = 97 'a'
>> (gdb) p exp->string.str[1]
>> $9 = 98 'b'
>> (gdb) p exp->string.str[2]
>> $10 = 0 '\000'
>> (gdb) p exp->string.str[3]
>> $11 = 0 '\000'
>>
>>
>> This is an important property of string_cst objects, that is used in 
>> c_strlen:
>>
>> It folds c_strlen([4]) directly to 0, because every byte beyond 
>> TREE_STRING_LENGTH
>> is guaranteed to be zero up to the type size.
>>
>> I would not have spent one thought on implementing an optimization like that,
>> but that's how it is right now.
> 
> Huh.  So somebody interpreted STRING_CSTs similar to CONSTRUCTORs aka
> they have zero-padding up to its type size.  I don't see this documented
> anywhere and it would suggest to "optimize" "ab\0\0\0\0" to "ab\0"
> with appropriate TYPE_SIZE.
> 
> This is also a relatively new thing on trunk (coming out of the added
> mem_size parameter of string_constant).  That this looks at the STRING_CST
> type like
> 
>if (TREE_CODE (array) == STRING_CST)
>  {
>*ptr_offset = fold_convert (sizetype, offset);
>if (mem_size)
>  *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
>return array;
> 
> I'd call simply a bug.  As said, interpretation of STRING_CSTs should
> depend on the context.  And for
> 

This use of the TYPE_SIZE_UNIT was pre-existing to r263607
before that (but not in the gcc-8-branch) we had this in c_strlen:

   HOST_WIDE_INT maxelts = strelts;
   tree type = TREE_TYPE (src);
   if (tree size = TYPE_SIZE_UNIT (type))
 if (tree_fits_shwi_p (size))
   {
maxelts = tree_to_uhwi (size);
maxelts = maxelts / eltsize - 1;
   }

which I moved to string_constant and return the result through memsize.

It seems to be working somehow, and I'd bet removing that will immediately
break twenty or thirty of the strlenopt tests.

Obviously the tree string objects allow way too much variations,
and it has to be restricted in some way or another.

In the moment my approach is: look at what most string constants do
and add assertions to ensure that there are no 

[CPP PATCH] Fix warning & other cleanups.

2018-08-20 Thread Nathan Sidwell
I noticed I'd inadvertently allowed a trailing comma to creep in, 
leading to annoying warnings.  I'd also missed a few uses of the 
cpp_macro_p function and friends.  Plus Bernhard had suggested there's a 
name for 255 when it's encoding unsigned char range.


Fixed thusly.

nathan
--
Nathan Sidwell
Index: directives.c
===
--- directives.c	(revision 263658)
+++ directives.c	(working copy)
@@ -665,12 +665,12 @@ do_undef (cpp_reader *pfile)
 
   /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified
 	 identifier is not currently defined as a macro name.  */
-  if (node->type == NT_MACRO)
+  if (cpp_macro_p (node))
 	{
 	  if (node->flags & NODE_WARN)
 	cpp_error (pfile, CPP_DL_WARNING,
 		   "undefining \"%s\"", NODE_NAME (node));
-	  else if ((node->flags & NODE_BUILTIN)
+	  else if (cpp_builtin_macro_p (node)
 		   && CPP_OPTION (pfile, warn_builtin_macro_redefined))
 	cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED,
    pfile->directive_line, 0,
Index: include/cpplib.h
===
--- include/cpplib.h	(revision 263658)
+++ include/cpplib.h	(working copy)
@@ -674,7 +674,7 @@ struct cpp_dir
 enum cpp_macro_kind {
   cmk_macro,	/* An ISO macro (token expansion).  */
   cmk_assert,   /* An assertion.  */
-  cmk_traditional,	/* A traditional macro (text expansion).  */
+  cmk_traditional	/* A traditional macro (text expansion).  */
 };
 
 /* Each macro definition is recorded in a cpp_macro structure.
@@ -972,7 +972,10 @@ inline bool cpp_macro_p (const cpp_hashn
   return node->type == NT_MACRO;
 }
 /* Returns true if NODE is a function-like user macro.  */
-extern bool cpp_fun_like_macro_p (cpp_hashnode *node);
+inline bool cpp_fun_like_macro_p (cpp_hashnode *node)
+{
+  return cpp_user_macro_p (node) && node->value.macro->fun_like;
+}
 
 extern const unsigned char *cpp_macro_definition (cpp_reader *,
 		  cpp_hashnode *);
Index: macro.c
===
--- macro.c	(revision 263658)
+++ macro.c	(working copy)
@@ -3551,7 +3551,7 @@ cpp_define_lazily (cpp_reader *pfile, cp
 {
   cpp_macro *macro = node->value.macro;
 
-  gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < 255);
+  gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < UCHAR_MAX);
 
   macro->lazy = num + 1;
 }
@@ -3632,15 +3632,6 @@ check_trad_stringification (cpp_reader *
 }
 }
 
-/* Returns true of NODE is a function-like macro.  */
-bool
-cpp_fun_like_macro_p (cpp_hashnode *node)
-{
-  return (node->type == NT_MACRO
-	  && (node->flags & (NODE_BUILTIN | NODE_MACRO_ARG)) == 0
-	  && node->value.macro->fun_like);
-}
-
 /* Returns the name, arguments and expansion of a macro, in a format
suitable to be read back in again, and therefore also for DWARF 2
debugging info.  e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION".


Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Bernd Edlinger
On 08/20/18 16:26, Jeff Law wrote:
> On 08/20/2018 04:23 AM, Bernd Edlinger wrote:
>> On 08/20/18 12:12, Richard Biener wrote:
>>> On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:

 On 08/10/2018 10:56 AM, Martin Sebor wrote:
> On 08/08/2018 11:36 PM, Jeff Law wrote:
>> On 08/02/2018 09:42 AM, Martin Sebor wrote:
>>
>>> The warning bits are definitely not okay by me.  The purpose
>>> of the warnings (-W{format,sprintf}-{overflow,truncation} is
>>> to detect buffer overflows.  When a warning doesn't have access
>>> to string length information for dynamically created strings
>>> (like the strlen pass does) it uses array sizes as a proxy.
>>> This is useful both to detect possible buffer overflows and
>>> to prevent false positives for overflows that cannot happen
>>> in correctly written programs.
>> So how much of this falling-back to array sizes as a proxy would become
>> unnecessary if sprintf had access to the strlen pass as an analysis
>> module?
>>
>> As you know we've been kicking that around and from my investigations
>> that doesn't really look hard to do.  Encapsulate the data structures in
>> a class, break up the statement handling into analysis and optimization
>> and we should be good to go.  I'm hoping to start prototyping this week.
>>
>> If we think that has a reasonable chance to eliminate the array-size
>> fallback, then that seems like the most promising path forward.
>
> We discussed this idea this morning so let me respond here and
> reiterate the answer.  Using the strlen data will help detect
> buffer overflow where the array size isn't available but it
> cannot replace the array size heuristic. Here's a simple
> example:
>
> struct S { char a[8]; };
>
> char d[8];
> void f (struct S *s, int i)
> {
>   sprintf (d, "%s-%i",  s[i].a, i);
> }
>
> We don't know the length of s->a but we do know that it can
> be up to 7 bytes long (assuming it's nul-terminated of course)
> so we know the sprintf call can overflow.  Conversely, if
> the size of the destination is increased to 20  the sprintf
> call cannot overflow so the diagnostic can be avoided.
>
> Removing the array size heuristic would force us to either give
> up on diagnosing the first case or issue false positives for
> the second case.  I think the second alternative would make
> the warning too noisy to be useful.
>
> The strlen pass will help detect buffer overflows in cases
> where the array size isn't known (e.g., with dynamically
> allocated buffers) but where the length of the string store
> in the array is known.  It will also help avoid false positives
> in cases where the string stored in an array of known size is
> known to be too short to cause an overflow.  For instance here:
>
> struct S { char a[8]; };
>
> char d[8];
> void f (struct S *s, int i)
> {
>   if (strlen (s->a) < 4 && i >= 0 && i < 100)
> sprintf (d, "%s-%i",  s->a, i);
> }
 ACK.  Thanks for explaining things here too.  I can't speak for others,
 but seeing examples along with the explanation is easier for me to absorb.

 For Bernd and others -- after kicking things around a bit with Martin,
 what we're recommending is that compute_string_length we compute the
 bounds using both GIMPLE and C semantics and return both.
>>>
>>> But you can't do this because GIMPLE did transforms that are not valid in
>>> C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
>>> it as GIMPLE.  What you'd do is return GIMPLE semantics length
>>> and "foobar" semantics length which doesn't match the original source.
>>>
>>
>> If I understood that suggestion right, it means, we
>> live with some false positive or missing warnings due to those 
>> transformations.
>> That means, get_range_strlen with the 2-parameter overload is used
>> for warnings only.  And it returns most of the time a correct range info,
>> that is good enough for warnings.
> Correct.  99.9% of the time using the ranges implied by the array types
> is better for the warning code.  So the idea is to return two ranges.
> One which uses GIMPLE semantics for code generation and optimization
> purposes, the other which uses ranges implied by the array types for
> warning purposes.
> 
> Martin suggested that we always compute and return both rather than
> having a boolean argument to select between the behavior.
> 
> 

Okay, but there is already the "strict" parameter:

/* Determine the minimum and maximum value or string length that ARG
refers to and store each in the first two elements of MINMAXLEN.
For expressions that point to strings of unknown lengths that are
character arrays, use the upper bound of the array as the maximum
length.  For 

Re: r 262451

2018-08-20 Thread Iain Sandoe


> On 20 Aug 2018, at 15:55, Alexander Monakov  wrote:
> On Mon, 20 Aug 2018, Iain Sandoe wrote:
> 
>> I am seeing excess changes when running

I meant regenerating .. not running.. 

>> configure, is it possible the regenerated files were missed from this rev?
>> 
>> https://gcc.gnu.org/ml/gcc-cvs/2018-07/msg00172.html
> 
> Yes, that change did not regenerate configure scripts.  I've also noticed 
> that.
> 
> I considered filing a bug, but the changes in question are so trivial I
> decided it totally not worth the trouble. They only affect pgcc compilers.

Hmm the revision changelog

 * libtool.m4: Sort output of 'find' to enable deterministic builds.
 * ltmain.sh: Likewise.

Agreed the changes are superficially not complex, but libtool changes affect 
most
 (probably all?) of the configure scripts, which means that the next 
regeneration
of each will end up commiting unrelated hunks - or one has to edit them out.

- it would be neater to have a single commit to accommodate any that haven’t
happened as fallout of other changes in the intervening time?

Iain



[PATCH] Optimize more boolean functions

2018-08-20 Thread MCC CS
Hi everyone,

this patch optimizes ~(~x | y), (~x | y) & (x | ~y) and
(~x | y) ^ (x | ~y). Thanks to Marc Glisse
for noticing that the last two weren't optimized.
 
I'll post the test results soon, it took three hours in
addition to timeouts and I had to terminate it.
 
Waiting for your comments.

gcc/
PR tree-optimization/87009
* match.pd: Improve boolean optimizations

gcc/testsuite/
PR tree-optimization/87009
* gcc.dg/pr87009.c: Add boolean optimization tests
Index: gcc/match.pd
===
--- gcc/match.pd (revision 263646)
+++ gcc/match.pd (working copy)
@@ -776,6 +776,11 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_not (bit_and:cs (bit_not @0) @1))
(bit_ior @0 (bit_not @1)))

+/* ~(~a | b) --> a & ~b */
+(simplify
+ (bit_not (bit_ior:cs (bit_not @0) @1))
+ (bit_and @0 (bit_not @1)))
+
/* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */
#if GIMPLE
(simplify
@@ -981,6 +986,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_and:c (bit_ior:c @0 @1) (bit_xor:c @1 (bit_not @0)))
(bit_and @0 @1))

+/* (~x | y) & (x | ~y) -> ~(x ^ y) */
+(simplify
+ (bit_and (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
+ (bit_not (bit_xor @0 @1)))
+
+/* (~x | y) ^ (x | ~y) -> x ^ y */
+(simplify
+ (bit_xor (bit_ior:c (bit_not @0) @1) (bit_ior:c @0 (bit_not @1)))
+ (bit_xor @0 @1))
+
/* ~x & ~y -> ~(x | y)
~x | ~y -> ~(x & y) */
(for op (bit_and bit_ior)
Index: gcc/testsuite/gcc.dg/pr87009.c
===
--- gcc/testsuite/gcc.dg/pr87009.c (nonexistent)
+++ gcc/testsuite/gcc.dg/pr87009.c (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+/* { dg-final { scan-tree-dump-times " \\^ " 4 "original" } } */
+
+int f1 (int x, int s)
+{
+ return ~(~(x|s)|x)|~(~(x|s)|s);
+}
+
+int f2 (int x, int s)
+{
+ return ~(~(~x)&~(x&~s));
+}
+
+int f3 (int x, int s)
+{
+ return ~((x|~s)&(~x|s));
+}
+
+int f4 (int x, int s)
+{
+ return (~x|s)&(x|~s);
+}


Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Bernd Edlinger
On 08/20/18 16:54, Jeff Law wrote:
> On 08/20/2018 08:52 AM, Bernd Edlinger wrote:
>> On 08/20/18 16:16, Jeff Law wrote:
>>> On 08/20/2018 07:28 AM, Richard Biener wrote:
 On Mon, 20 Aug 2018, Bernd Edlinger wrote:

> On 08/20/18 12:41, Richard Biener wrote:
>> On Sun, 19 Aug 2018, Bernd Edlinger wrote:
>>
>>> Hi!
>>>
>>>
>>> This fixes a wrong code issue in expand_expr_real_1 which happens 
>>> because
>>> a negative bitpos is actually able to reach extract_bit_field which
>>> does all computations with poly_uint64, thus the offset 
>>> 0x1ff0.
>>>
>>> To avoid that I propose to use Jakub's r20 patch from the 
>>> expand_assignment
>>> also in the expand_expr_real_1.
>>>
>>> This is a rather unlikely thing to happen, as there are lots of checks 
>>> that are
>>> of course all target dependent between the get_inner_reference and the
>>> actual extract_bit_field call, and all other code paths may or may not 
>>> have a problem
>>> with negative bit offsets.  Most don't have a problem, but the bitpos 
>>> needs to be
>>> folded into offset before it is used, therefore it is necessary to 
>>> handle the negative
>>> bitpos very far away from the extract_bit_field call.  Doing that later 
>>> is IMHO not
>>> possible.
>>>
>>> The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted 
>>> it because
>>> this macro is used in alpha_legitimize_address which is of course what 
>>> one looks
>>> at first if something like that happens.
>>>
>>> I think even with this bogus offset it should not have caused a linker 
>>> error, so there
>>> is probably a second problem in the *movdi code pattern of the 
>>> alpha.md, because it
>>> should be split into instructions that don't cause a link error.
>>>
>>> Once the target is fixed to split the impossible assembler instruction, 
>>> the test case
>>> will probably no longer be able to detect the pattern in the assembly.
>>>
>>> Therefore the test case looks both at the assembler output and the 
>>> expand rtl dump
>>> to spot the bogus offset.  I only check the first 12 digits of the 
>>> bogus constant,
>>> because it is actually dependent on the target configuration:
>>>
>>> I built first a cross-compiler without binutils, and it did used a 
>>> slightly different
>>> offset of 0x2000, (configured with: 
>>> --target=alpha-linux-gnu --enable-languages=c
>>> --disable-libgcc --disable-libssp --disable-libquadmath 
>>> --disable-libgomp --disable-libatomic)
>>> when the binutils are installed at where --prefix points, the offset is 
>>> 0x1ff0.
>>>
>>> Regarding the alpha target, I could not do more than build a cross 
>>> compiler and run
>>> make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".
>>>
>>>
>>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>>> Is it OK for trunk?
>>
>> Hmm, I don't remember why we are inconsistent in get_inner_reference
>> with respect to negative bitpos.  I think we should be consistent
>> here and may not be only by accident?  That is, does
>>
>> diff --git a/gcc/expr.c b/gcc/expr.c
>> index c071be67783..9dc78587136 100644
>> --- a/gcc/expr.c
>> +++ b/gcc/expr.c
>> @@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod
>> *pbitsize,
>>  TYPE_PRECISION (sizetype));
>>   tem <<= LOG2_BITS_PER_UNIT;
>>   tem += bit_offset;
>> -  if (tem.to_shwi (pbitpos))
>> +  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
>>*poffset = offset = NULL_TREE;
>> }
>> 
>> fix the issue?
>>
>
> Yes, at first sight, however, I was involved at PR 58970,
> see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58970
>
> and I proposed a similar patch, which was objected by Jakub:
>
> see comment #25 of PR 58970:
> "Jakub Jelinek 2013-11-05 19:41:12 UTC
>
> (In reply to Bernd Edlinger from comment #24)
>> Created attachment 31169 [details] 
>> https://gcc.gnu.org/bugzilla/attachment.cgi?id=31169
>> Another (better) attempt at fixing this ICE.
>>
>> This avoids any negative bitpos from get_inner_reference.
>> These negative bitpos values are just _very_ dangerous all the
>> way down to expmed.c
>
> I disagree that it is better, you are forgetting get_inner_reference has 
> other > 20 callers outside of expansion and there is no reason why 
> negative bitpos would be a problem in those cases."
>
> So that is what Jakub said at that time, and with the
> suggested change in get_inner_reference,
> this part of the r20 change would be effectively become 

Re: r 262451

2018-08-20 Thread Alexander Monakov



On Mon, 20 Aug 2018, Iain Sandoe wrote:

> I am seeing excess changes when running configure, is it possible the 
> regenerated files were missed from this rev?
> 
> https://gcc.gnu.org/ml/gcc-cvs/2018-07/msg00172.html

Yes, that change did not regenerate configure scripts.  I've also noticed that.

I considered filing a bug, but the changes in question are so trivial I
decided it totally not worth the trouble. They only affect pgcc compilers.

Alexander


Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Jeff Law
On 08/20/2018 08:52 AM, Bernd Edlinger wrote:
> On 08/20/18 16:16, Jeff Law wrote:
>> On 08/20/2018 07:28 AM, Richard Biener wrote:
>>> On Mon, 20 Aug 2018, Bernd Edlinger wrote:
>>>
 On 08/20/18 12:41, Richard Biener wrote:
> On Sun, 19 Aug 2018, Bernd Edlinger wrote:
>
>> Hi!
>>
>>
>> This fixes a wrong code issue in expand_expr_real_1 which happens because
>> a negative bitpos is actually able to reach extract_bit_field which
>> does all computations with poly_uint64, thus the offset 
>> 0x1ff0.
>>
>> To avoid that I propose to use Jakub's r20 patch from the 
>> expand_assignment
>> also in the expand_expr_real_1.
>>
>> This is a rather unlikely thing to happen, as there are lots of checks 
>> that are
>> of course all target dependent between the get_inner_reference and the
>> actual extract_bit_field call, and all other code paths may or may not 
>> have a problem
>> with negative bit offsets.  Most don't have a problem, but the bitpos 
>> needs to be
>> folded into offset before it is used, therefore it is necessary to 
>> handle the negative
>> bitpos very far away from the extract_bit_field call.  Doing that later 
>> is IMHO not
>> possible.
>>
>> The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted 
>> it because
>> this macro is used in alpha_legitimize_address which is of course what 
>> one looks
>> at first if something like that happens.
>>
>> I think even with this bogus offset it should not have caused a linker 
>> error, so there
>> is probably a second problem in the *movdi code pattern of the alpha.md, 
>> because it
>> should be split into instructions that don't cause a link error.
>>
>> Once the target is fixed to split the impossible assembler instruction, 
>> the test case
>> will probably no longer be able to detect the pattern in the assembly.
>>
>> Therefore the test case looks both at the assembler output and the 
>> expand rtl dump
>> to spot the bogus offset.  I only check the first 12 digits of the bogus 
>> constant,
>> because it is actually dependent on the target configuration:
>>
>> I built first a cross-compiler without binutils, and it did used a 
>> slightly different
>> offset of 0x2000, (configured with: --target=alpha-linux-gnu 
>> --enable-languages=c
>> --disable-libgcc --disable-libssp --disable-libquadmath 
>> --disable-libgomp --disable-libatomic)
>> when the binutils are installed at where --prefix points, the offset is 
>> 0x1ff0.
>>
>> Regarding the alpha target, I could not do more than build a cross 
>> compiler and run
>> make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".
>>
>>
>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>> Is it OK for trunk?
>
> Hmm, I don't remember why we are inconsistent in get_inner_reference
> with respect to negative bitpos.  I think we should be consistent
> here and may not be only by accident?  That is, does
>
> diff --git a/gcc/expr.c b/gcc/expr.c
> index c071be67783..9dc78587136 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod
> *pbitsize,
> TYPE_PRECISION (sizetype));
>  tem <<= LOG2_BITS_PER_UNIT;
>  tem += bit_offset;
> -  if (tem.to_shwi (pbitpos))
> +  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
>   *poffset = offset = NULL_TREE;
>}
>
> fix the issue?
>

 Yes, at first sight, however, I was involved at PR 58970,
 see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58970

 and I proposed a similar patch, which was objected by Jakub:

 see comment #25 of PR 58970:
 "Jakub Jelinek 2013-11-05 19:41:12 UTC

 (In reply to Bernd Edlinger from comment #24)
> Created attachment 31169 [details] 
> https://gcc.gnu.org/bugzilla/attachment.cgi?id=31169
> Another (better) attempt at fixing this ICE.
>
> This avoids any negative bitpos from get_inner_reference.
> These negative bitpos values are just _very_ dangerous all the
> way down to expmed.c

 I disagree that it is better, you are forgetting get_inner_reference has 
 other > 20 callers outside of expansion and there is no reason why 
 negative bitpos would be a problem in those cases."

 So that is what Jakub said at that time, and with the
 suggested change in get_inner_reference,
 this part of the r20 change would be effectively become superfluous:

 @@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, bool nontem
  tem = get_inner_reference (to, , , , ,
 

Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Bernd Edlinger
On 08/20/18 16:16, Jeff Law wrote:
> On 08/20/2018 07:28 AM, Richard Biener wrote:
>> On Mon, 20 Aug 2018, Bernd Edlinger wrote:
>>
>>> On 08/20/18 12:41, Richard Biener wrote:
 On Sun, 19 Aug 2018, Bernd Edlinger wrote:

> Hi!
>
>
> This fixes a wrong code issue in expand_expr_real_1 which happens because
> a negative bitpos is actually able to reach extract_bit_field which
> does all computations with poly_uint64, thus the offset 
> 0x1ff0.
>
> To avoid that I propose to use Jakub's r20 patch from the 
> expand_assignment
> also in the expand_expr_real_1.
>
> This is a rather unlikely thing to happen, as there are lots of checks 
> that are
> of course all target dependent between the get_inner_reference and the
> actual extract_bit_field call, and all other code paths may or may not 
> have a problem
> with negative bit offsets.  Most don't have a problem, but the bitpos 
> needs to be
> folded into offset before it is used, therefore it is necessary to handle 
> the negative
> bitpos very far away from the extract_bit_field call.  Doing that later 
> is IMHO not
> possible.
>
> The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted 
> it because
> this macro is used in alpha_legitimize_address which is of course what 
> one looks
> at first if something like that happens.
>
> I think even with this bogus offset it should not have caused a linker 
> error, so there
> is probably a second problem in the *movdi code pattern of the alpha.md, 
> because it
> should be split into instructions that don't cause a link error.
>
> Once the target is fixed to split the impossible assembler instruction, 
> the test case
> will probably no longer be able to detect the pattern in the assembly.
>
> Therefore the test case looks both at the assembler output and the expand 
> rtl dump
> to spot the bogus offset.  I only check the first 12 digits of the bogus 
> constant,
> because it is actually dependent on the target configuration:
>
> I built first a cross-compiler without binutils, and it did used a 
> slightly different
> offset of 0x2000, (configured with: --target=alpha-linux-gnu 
> --enable-languages=c
> --disable-libgcc --disable-libssp --disable-libquadmath --disable-libgomp 
> --disable-libatomic)
> when the binutils are installed at where --prefix points, the offset is 
> 0x1ff0.
>
> Regarding the alpha target, I could not do more than build a cross 
> compiler and run
> make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".
>
>
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?

 Hmm, I don't remember why we are inconsistent in get_inner_reference
 with respect to negative bitpos.  I think we should be consistent
 here and may not be only by accident?  That is, does

 diff --git a/gcc/expr.c b/gcc/expr.c
 index c071be67783..9dc78587136 100644
 --- a/gcc/expr.c
 +++ b/gcc/expr.c
 @@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod
 *pbitsize,
 TYPE_PRECISION (sizetype));
  tem <<= LOG2_BITS_PER_UNIT;
  tem += bit_offset;
 -  if (tem.to_shwi (pbitpos))
 +  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
   *poffset = offset = NULL_TREE;
}

 fix the issue?

>>>
>>> Yes, at first sight, however, I was involved at PR 58970,
>>> see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58970
>>>
>>> and I proposed a similar patch, which was objected by Jakub:
>>>
>>> see comment #25 of PR 58970:
>>> "Jakub Jelinek 2013-11-05 19:41:12 UTC
>>>
>>> (In reply to Bernd Edlinger from comment #24)
 Created attachment 31169 [details] 
 https://gcc.gnu.org/bugzilla/attachment.cgi?id=31169
 Another (better) attempt at fixing this ICE.

 This avoids any negative bitpos from get_inner_reference.
 These negative bitpos values are just _very_ dangerous all the
 way down to expmed.c
>>>
>>> I disagree that it is better, you are forgetting get_inner_reference has 
>>> other > 20 callers outside of expansion and there is no reason why negative 
>>> bitpos would be a problem in those cases."
>>>
>>> So that is what Jakub said at that time, and with the
>>> suggested change in get_inner_reference,
>>> this part of the r20 change would be effectively become superfluous:
>>>
>>> @@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, bool nontem
>>>  tem = get_inner_reference (to, , , , ,
>>>, , true);
>>>
>>> +  /* Make sure bitpos is not negative, it can wreak havoc later.  */
>>> +  if (bitpos < 0)
>>> +   {
>>> + 

r 262451

2018-08-20 Thread Iain Sandoe
I am seeing excess changes when running configure, is it possible the 
regenerated files were missed from this rev?

https://gcc.gnu.org/ml/gcc-cvs/2018-07/msg00172.html

thanks
Iain

Re: [PATCH v3 02/10] Initial TI PRU libgcc port

2018-08-20 Thread Jeff Law
On 08/15/2018 10:49 PM, Dimitar Dimitrov wrote:
> The floating point support has been borrowed from C6X libgcc port
> to help with TI PRU toolchain ABI compatibility.
> 
> libgcc/ChangeLog:
> 
> 2018-07-27  Dimitar Dimitrov  
> 
>   * config.host: Add PRU target.
>   * config/pru/asri.c: New file.
>   * config/pru/eqd.c: New file.
>   * config/pru/eqf.c: New file.
>   * config/pru/ged.c: New file.
>   * config/pru/gef.c: New file.
>   * config/pru/gtd.c: New file.
>   * config/pru/gtf.c: New file.
>   * config/pru/led.c: New file.
>   * config/pru/lef.c: New file.
>   * config/pru/lib2bitcountHI.c: New file.
>   * config/pru/lib2divHI.c: New file.
>   * config/pru/lib2divQI.c: New file.
>   * config/pru/lib2divSI.c: New file.
>   * config/pru/libgcc-eabi.ver: New file.
>   * config/pru/ltd.c: New file.
>   * config/pru/ltf.c: New file.
>   * config/pru/mpyll.S: New file.
>   * config/pru/pru-abi.h: New file.
>   * config/pru/pru-asm.h: New file.
>   * config/pru/pru-divmod.h: New file.
>   * config/pru/sfp-machine.h: New file.
>   * config/pru/t-pru: New file.
This is all fine too once the basic port is approved.

jeff


Re: [PATCH v3 03/10] testsuite: Add PRU tests

2018-08-20 Thread Jeff Law
On 08/15/2018 10:49 PM, Dimitar Dimitrov wrote:
> gcc/testsuite/ChangeLog:
> 
> 2018-07-27  Dimitar Dimitrov  
> 
>   * gcc.target/pru/abi-arg-struct.c: New test.
>   * gcc.target/pru/ashiftrt.c: New test.
>   * gcc.target/pru/builtins-1.c: New test.
>   * gcc.target/pru/builtins-error.c: New test.
>   * gcc.target/pru/clearbit.c: New test.
>   * gcc.target/pru/loop-asm.c: New test.
>   * gcc.target/pru/loop-dowhile.c: New test.
>   * gcc.target/pru/loop-hi-1.c: New test.
>   * gcc.target/pru/loop-hi-2.c: New test.
>   * gcc.target/pru/loop-qi-1.c: New test.
>   * gcc.target/pru/loop-qi-2.c: New test.
>   * gcc.target/pru/loop-short-1.c: New test.
>   * gcc.target/pru/loop-short-2.c: New test.
>   * gcc.target/pru/loop-si-1.c: New test.
>   * gcc.target/pru/loop-si-2.c: New test.
>   * gcc.target/pru/loop-u8_pcrel_overflow.c: New test.
>   * gcc.target/pru/loop-ubyte-1.c: New test.
>   * gcc.target/pru/loop-ubyte-2.c: New test.
>   * gcc.target/pru/lra-framepointer-fragmentation-1.c: New test.
>   * gcc.target/pru/lra-framepointer-fragmentation-2.c: New test.
>   * gcc.target/pru/mabi-ti-1.c: New test.
>   * gcc.target/pru/mabi-ti-2.c: New test.
>   * gcc.target/pru/mabi-ti-3.c: New test.
>   * gcc.target/pru/mabi-ti-4.c: New test.
>   * gcc.target/pru/mabi-ti-5.c: New test.
>   * gcc.target/pru/mabi-ti-6.c: New test.
>   * gcc.target/pru/mabi-ti-7.c: New test.
>   * gcc.target/pru/pr64366.c: New test.
>   * gcc.target/pru/pragma-ctable_entry.c: New test.
>   * gcc.target/pru/pru.exp: New file.
>   * gcc.target/pru/qbbc-1.c: New test.
>   * gcc.target/pru/qbbc-2.c: New test.
>   * gcc.target/pru/qbbc-3.c: New test.
>   * gcc.target/pru/qbbs-1.c: New test.
>   * gcc.target/pru/qbbs-2.c: New test.
>   * gcc.target/pru/setbit.c: New test.
>   * gcc.target/pru/zero_extend-and-hisi.c: New test.
>   * gcc.target/pru/zero_extend-and-qihi.c: New test.
>   * gcc.target/pru/zero_extend-and-qisi.c: New test.
>   * gcc.target/pru/zero_extend-hisi.c: New test.
>   * gcc.target/pru/zero_extend-qihi.c: New test.
>   * gcc.target/pru/zero_extend-qisi.c: New test.
>   * lib/target-supports.exp: Add PRU to feature filters.
Patches 03/10 through 10/10 are all OK once the basic port is approved.

Jeff


Re: [PATCH] PR86844: Fix for store merging

2018-08-20 Thread Jeff Law
On 08/18/2018 03:20 AM, Eric Botcazou wrote:
>> Eric, didn't your patches explicitely handle this case of a non-constant
>> inbetween?
> 
> Only if there is no overlap at all, otherwise you cannot do things simply.
> 
>> Can you have a look / review here?
> 
> Jakub is probably more qualified to give a definitive opinion, as he wrote 
> check_no_overlap and the bug is orthogonal to my patches since it is present 
> in 8.x; in any case, all transformations are supposed to be covered by the 
> testsuite.
FYI. Jakub is on PTO through the end of this week and will probably be
buried when he returns.

Jeff



Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Jeff Law
On 08/20/2018 04:23 AM, Bernd Edlinger wrote:
> On 08/20/18 12:12, Richard Biener wrote:
>> On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:
>>>
>>> On 08/10/2018 10:56 AM, Martin Sebor wrote:
 On 08/08/2018 11:36 PM, Jeff Law wrote:
> On 08/02/2018 09:42 AM, Martin Sebor wrote:
>
>> The warning bits are definitely not okay by me.  The purpose
>> of the warnings (-W{format,sprintf}-{overflow,truncation} is
>> to detect buffer overflows.  When a warning doesn't have access
>> to string length information for dynamically created strings
>> (like the strlen pass does) it uses array sizes as a proxy.
>> This is useful both to detect possible buffer overflows and
>> to prevent false positives for overflows that cannot happen
>> in correctly written programs.
> So how much of this falling-back to array sizes as a proxy would become
> unnecessary if sprintf had access to the strlen pass as an analysis
> module?
>
> As you know we've been kicking that around and from my investigations
> that doesn't really look hard to do.  Encapsulate the data structures in
> a class, break up the statement handling into analysis and optimization
> and we should be good to go.  I'm hoping to start prototyping this week.
>
> If we think that has a reasonable chance to eliminate the array-size
> fallback, then that seems like the most promising path forward.

 We discussed this idea this morning so let me respond here and
 reiterate the answer.  Using the strlen data will help detect
 buffer overflow where the array size isn't available but it
 cannot replace the array size heuristic. Here's a simple
 example:

struct S { char a[8]; };

char d[8];
void f (struct S *s, int i)
{
  sprintf (d, "%s-%i",  s[i].a, i);
}

 We don't know the length of s->a but we do know that it can
 be up to 7 bytes long (assuming it's nul-terminated of course)
 so we know the sprintf call can overflow.  Conversely, if
 the size of the destination is increased to 20  the sprintf
 call cannot overflow so the diagnostic can be avoided.

 Removing the array size heuristic would force us to either give
 up on diagnosing the first case or issue false positives for
 the second case.  I think the second alternative would make
 the warning too noisy to be useful.

 The strlen pass will help detect buffer overflows in cases
 where the array size isn't known (e.g., with dynamically
 allocated buffers) but where the length of the string store
 in the array is known.  It will also help avoid false positives
 in cases where the string stored in an array of known size is
 known to be too short to cause an overflow.  For instance here:

struct S { char a[8]; };

char d[8];
void f (struct S *s, int i)
{
  if (strlen (s->a) < 4 && i >= 0 && i < 100)
sprintf (d, "%s-%i",  s->a, i);
}
>>> ACK.  Thanks for explaining things here too.  I can't speak for others,
>>> but seeing examples along with the explanation is easier for me to absorb.
>>>
>>> For Bernd and others -- after kicking things around a bit with Martin,
>>> what we're recommending is that compute_string_length we compute the
>>> bounds using both GIMPLE and C semantics and return both.
>>
>> But you can't do this because GIMPLE did transforms that are not valid in
>> C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
>> it as GIMPLE.  What you'd do is return GIMPLE semantics length
>> and "foobar" semantics length which doesn't match the original source.
>>
> 
> If I understood that suggestion right, it means, we
> live with some false positive or missing warnings due to those 
> transformations.
> That means, get_range_strlen with the 2-parameter overload is used
> for warnings only.  And it returns most of the time a correct range info,
> that is good enough for warnings.
Correct.  99.9% of the time using the ranges implied by the array types
is better for the warning code.  So the idea is to return two ranges.
One which uses GIMPLE semantics for code generation and optimization
purposes, the other which uses ranges implied by the array types for
warning purposes.

Martin suggested that we always compute and return both rather than
having a boolean argument to select between the behavior.


Jeff


[PATCH] Kill cpp-id-data.h

2018-08-20 Thread Nathan Sidwell
Now that cpp-id-data.h contains a single #include, we can kill it and 
have its includers simply point at the sub include.  That turns out to 
be a single file.


Except of course, the makefile & gty pieces that also need updates, but 
mechanical ones.


booted & tested on x86_64-linux, committing to trunk.

nathan
--
Nathan Sidwell
2018-08-20  Nathan Sidwell  

	libcpp/
	* Makefile.in (TAGS_SOURCES): Remove cpp-id-data.h.
	* include/cpp-id-data.h: Delete.
	* internal.h: Include cpplib.h not cpp-id-data.h.
	gcc/
	* Makefile.in (CPP_ID_DATA_H): Delete.
	(CPP_INTERNAL_H): Don't add it.
	(GTFILES): Replace CPP_ID_DATA_H with CPPLIB_H.
	* gengtype.c (open_base_files): Replace cpp-id-data.h with cpplib.h

Index: gcc/Makefile.in
===
--- gcc/Makefile.in	(revision 263658)
+++ gcc/Makefile.in	(working copy)
@@ -978,8 +978,7 @@ CPPLIB_H = $(srcdir)/../libcpp/include/l
 INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h
 OPTS_H = $(INPUT_H) $(VEC_H) opts.h $(OBSTACK_H)
 SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h $(OBSTACK_H)
-CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
-CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h $(CPP_ID_DATA_H)
+CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h
 TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) $(DUMPFILE_H)
 TREE_PASS_H = tree-pass.h $(TIMEVAR_H) $(DUMPFILE_H)
 TREE_SSA_H = tree-ssa.h tree-ssa-operands.h \
@@ -2522,7 +2521,7 @@ s-match: build/genmatch$(build_exeext) $
 		generic-match.c
 	$(STAMP) s-match
 
-GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
+GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
   $(host_xm_file_list) \
   $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
   $(srcdir)/wide-int.h $(srcdir)/alias.h \
Index: gcc/gengtype.c
===
--- gcc/gengtype.c	(revision 263658)
+++ gcc/gengtype.c	(working copy)
@@ -1721,7 +1721,7 @@ open_base_files (void)
   "tree-vrp.h", "tree-phinodes.h", "ssa-iterators.h", "stringpool.h",
   "tree-ssanames.h", "tree-ssa-loop.h", "tree-ssa-loop-ivopts.h",
   "tree-ssa-loop-manip.h", "tree-ssa-loop-niter.h", "tree-into-ssa.h",
-  "tree-dfa.h", "tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
+  "tree-dfa.h", "tree-ssa.h", "reload.h", "cpplib.h", "tree-chrec.h",
   "except.h", "output.h",  "cfgloop.h", "target.h", "lto-streamer.h",
   "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h",
   "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-offload.h", NULL
Index: libcpp/Makefile.in
===
--- libcpp/Makefile.in	(revision 263658)
+++ libcpp/Makefile.in	(working copy)
@@ -261,9 +261,8 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
 	sed 's:$(srcdir)/::g' po/$(PACKAGE).pot
 	rm po/$(PACKAGE).pot.tmp
 
-TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h ucnid.h \
-include/line-map.h include/symtab.h include/cpp-id-data.h \
-include/cpplib.h include/mkdeps.h system.h
+TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h system.h ucnid.h \
+include/cpplib.h include/line-map.h include/mkdeps.h include/symtab.h
 
 TAGS: $(TAGS_SOURCES)
 	cd $(srcdir) && etags $(TAGS_SOURCES)
Index: libcpp/include/cpp-id-data.h
===
--- libcpp/include/cpp-id-data.h	(revision 263658)
+++ libcpp/include/cpp-id-data.h	(working copy)
@@ -1,19 +0,0 @@
-/* Structures that hang off cpp_identifier, for PCH.
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
-
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3, or (at your option) any
-later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; see the file COPYING3.  If not see
-.  */
-
-#include "cpplib.h"
-
Index: libcpp/internal.h
===
--- libcpp/internal.h	(revision 263658)
+++ libcpp/internal.h	(working copy)
@@ -23,7 +23,7 @@ along with this program; see the file CO
 #define LIBCPP_INTERNAL_H
 
 #include "symtab.h"
-#include "cpp-id-data.h"
+#include "cpplib.h"
 
 #if HAVE_ICONV
 #include 


Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Jeff Law
On 08/20/2018 07:28 AM, Richard Biener wrote:
> On Mon, 20 Aug 2018, Bernd Edlinger wrote:
> 
>> On 08/20/18 12:41, Richard Biener wrote:
>>> On Sun, 19 Aug 2018, Bernd Edlinger wrote:
>>>
 Hi!


 This fixes a wrong code issue in expand_expr_real_1 which happens because
 a negative bitpos is actually able to reach extract_bit_field which
 does all computations with poly_uint64, thus the offset 0x1ff0.

 To avoid that I propose to use Jakub's r20 patch from the 
 expand_assignment
 also in the expand_expr_real_1.

 This is a rather unlikely thing to happen, as there are lots of checks 
 that are
 of course all target dependent between the get_inner_reference and the
 actual extract_bit_field call, and all other code paths may or may not 
 have a problem
 with negative bit offsets.  Most don't have a problem, but the bitpos 
 needs to be
 folded into offset before it is used, therefore it is necessary to handle 
 the negative
 bitpos very far away from the extract_bit_field call.  Doing that later is 
 IMHO not
 possible.

 The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted it 
 because
 this macro is used in alpha_legitimize_address which is of course what one 
 looks
 at first if something like that happens.

 I think even with this bogus offset it should not have caused a linker 
 error, so there
 is probably a second problem in the *movdi code pattern of the alpha.md, 
 because it
 should be split into instructions that don't cause a link error.

 Once the target is fixed to split the impossible assembler instruction, 
 the test case
 will probably no longer be able to detect the pattern in the assembly.

 Therefore the test case looks both at the assembler output and the expand 
 rtl dump
 to spot the bogus offset.  I only check the first 12 digits of the bogus 
 constant,
 because it is actually dependent on the target configuration:

 I built first a cross-compiler without binutils, and it did used a 
 slightly different
 offset of 0x2000, (configured with: --target=alpha-linux-gnu 
 --enable-languages=c
 --disable-libgcc --disable-libssp --disable-libquadmath --disable-libgomp 
 --disable-libatomic)
 when the binutils are installed at where --prefix points, the offset is 
 0x1ff0.

 Regarding the alpha target, I could not do more than build a cross 
 compiler and run
 make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".


 Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
 Is it OK for trunk?
>>>
>>> Hmm, I don't remember why we are inconsistent in get_inner_reference
>>> with respect to negative bitpos.  I think we should be consistent
>>> here and may not be only by accident?  That is, does
>>>
>>> diff --git a/gcc/expr.c b/gcc/expr.c
>>> index c071be67783..9dc78587136 100644
>>> --- a/gcc/expr.c
>>> +++ b/gcc/expr.c
>>> @@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod
>>> *pbitsize,
>>>TYPE_PRECISION (sizetype));
>>> tem <<= LOG2_BITS_PER_UNIT;
>>> tem += bit_offset;
>>> -  if (tem.to_shwi (pbitpos))
>>> +  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
>>>  *poffset = offset = NULL_TREE;
>>>   }
>>>   
>>> fix the issue?
>>>
>>
>> Yes, at first sight, however, I was involved at PR 58970,
>> see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58970
>>
>> and I proposed a similar patch, which was objected by Jakub:
>>
>> see comment #25 of PR 58970:
>> "Jakub Jelinek 2013-11-05 19:41:12 UTC
>>
>> (In reply to Bernd Edlinger from comment #24)
>>> Created attachment 31169 [details] 
>>> https://gcc.gnu.org/bugzilla/attachment.cgi?id=31169
>>> Another (better) attempt at fixing this ICE.
>>>
>>> This avoids any negative bitpos from get_inner_reference.
>>> These negative bitpos values are just _very_ dangerous all the
>>> way down to expmed.c
>>
>> I disagree that it is better, you are forgetting get_inner_reference has 
>> other > 20 callers outside of expansion and there is no reason why negative 
>> bitpos would be a problem in those cases."
>>
>> So that is what Jakub said at that time, and with the
>> suggested change in get_inner_reference,
>> this part of the r20 change would be effectively become superfluous:
>>
>> @@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, bool nontem
>> tem = get_inner_reference (to, , , , ,
>>   , , true);
>>   
>> +  /* Make sure bitpos is not negative, it can wreak havoc later.  */
>> +  if (bitpos < 0)
>> +   {
>> + gcc_assert (offset == NULL_TREE);
>> + offset = size_int (bitpos >> (BITS_PER_UNIT == 8
>> +   ? 3 : exact_log2 

[PATCH v2][C][ADA] use function descriptors instead of trampolines in C

2018-08-20 Thread Uecker, Martin

This is a new version which adds proper changelog entries and
a test case (no actual code changes).

Bootstrapped an regression tested on x86_64.



gcc/
* common.opt (flag_trampolines): Change default.
* calls.c (prepare_call_address): Remove check for
flag_trampolines.  Decision is now made in FEs.
* tree-nested.c (convert_tramp_reference_op): Likewise.
gcc/ada/
* gcc-interface/trans.c (Attribute_to_gnu): Add check for
flag_trampolines.
gcc/c/
* c-objc-common.h: Define
LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS.
* c-typeck.c (function_to_pointer_conversion): If using
descriptors
instead of trampolines, amend function address with
FUNC_ADDR_BY_DESCRIPTOR and calls with
ALL_EXPR_BY_DESCRIPTOR.
gcc/testsuite/
* gcc.dg/trampoline-2.c: New test.



diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ec1fb242c23..e5f3844e8fd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-20  Martin Uecker  
+
+   * common.opt (flag_trampolines): Change default.
+   * calls.c (prepare_call_address): Remove check for
+   flag_trampolines.  Decision is now made in FEs.
+   * tree-nested.c (convert_tramp_reference_op): Likewise.
+
 2018-08-19  Uros Bizjak  
 
    PR target/86994
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 792811fb989..d906909774b 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2018-08-20  Martin Uecker  
+
+   * gcc-interface/trans.c (Attribute_to_gnu): Add check for
+   flag_trampolines.
+
 2018-08-03  Pierre-Marie de Rodat  
 
    Reverts
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-
interface/trans.c
index 0371d00fce1..1b95f7070ac 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1769,7 +1769,8 @@ Attribute_to_gnu (Node_Id gnat_node, tree
*gnu_result_type_p, int attribute)
      if ((attribute == Attr_Access
       || attribute == Attr_Unrestricted_Access)
      && targetm.calls.custom_function_descriptors > 0
-     && Can_Use_Internal_Rep (Etype (gnat_node)))
+     && Can_Use_Internal_Rep (Etype (gnat_node))
+  && (flag_trampolines != 1))
    FUNC_ADDR_BY_DESCRIPTOR (gnu_expr) = 1;
 
      /* Otherwise, we need to check that we are not violating
the
@@ -4341,7 +4342,8 @@ Call_to_gnu (Node_Id gnat_node, tree
*gnu_result_type_p, tree gnu_target,
   /* If the access type doesn't require foreign-compatible
representation,
     be prepared for descriptors.  */
   if (targetm.calls.custom_function_descriptors > 0
-     && Can_Use_Internal_Rep (Etype (Prefix (Name (gnat_node)
+     && Can_Use_Internal_Rep (Etype (Prefix (Name (gnat_node
+  && (flag_trampolines != 1))
    by_descriptor = true;
 }
   else if (Nkind (Name (gnat_node)) == N_Attribute_Reference)
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 7bde11c1f19..028a7284e41 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,10 @@
+2018-08-20  Martin Uecker  
+
+   * c-objc-common.h: Define
LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS.
+   * c-typeck.c (function_to_pointer_conversion): If using
descriptors
+   instead of trampolines, amend function address with
+   FUNC_ADDR_BY_DESCRIPTOR and calls with ALL_EXPR_BY_DESCRIPTOR.
+
 2018-08-15  David Malcolm  
 
    * c-objc-common.c: Include "gcc-rich-location.h".
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index 78e768c2366..ef039560eb9 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -110,4 +110,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
 #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P c_vla_unspec_p
+
+#undef LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS
+#define LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS true
 #endif /* GCC_C_OBJC_COMMON */
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 726ea832ae1..a6a962d1e01 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -1912,7 +1912,13 @@ function_to_pointer_conversion (location_t loc,
tree exp)
   if (TREE_NO_WARNING (orig_exp))
 TREE_NO_WARNING (exp) = 1;
 
-  return build_unary_op (loc, ADDR_EXPR, exp, false);
+  tree r = build_unary_op (loc, ADDR_EXPR, exp, false);
+
+  if ((TREE_CODE(r) == ADDR_EXPR)
+  && (flag_trampolines == 0))
+ FUNC_ADDR_BY_DESCRIPTOR (r) = 1;
+
+  return r;
 }
 
 /* Mark EXP as read, not just set, for set but not used -Wunused
@@ -3135,6 +3141,11 @@ build_function_call_vec (location_t loc,
vec arg_loc,
   else
 result = build_call_array_loc (loc, TREE_TYPE (fntype),
       function, nargs, argarray);
+
+  if ((TREE_CODE (result) == CALL_EXPR)
+  && (flag_trampolines == 0))
+CALL_EXPR_BY_DESCRIPTOR (result) = 1;
+
   /* If -Wnonnull warning has been 

[PATCH] Improve PR78655

2018-08-20 Thread Richard Biener


The following implements parts of the suggested transforms in PR78655
by making code already in VRP actually trigger.  The patch doesn't
handle

void bar (int *x, int a)
{
  if (a != 0)
{
  int *p = x + a;
  if (p == 0)
link_error ();
}
}

because a gets promoted to sizetype and the multiplied by 4 which
has defined overflow and thus gets us zero in the range for the
addend again.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2018-08-20  Richard Biener  

PR tree-optimization/78655
* tree-vrp.c (extract_range_from_binary_expr_1): Make
pointer + offset nonnull if either operand is nonnull work.

* gcc.dg/tree-ssa/evrp11.c: New testcase.

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c 
b/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c
new file mode 100644
index 000..f1373bd8683
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp11.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void link_error ();
+
+void foo (int *x)
+{
+  int *p = x + 1;
+  if (p == 0)
+link_error ();
+}
+
+void bar (char *x, int a)
+{
+  if (a != 0)
+{
+  char *p = x + a;
+  if (p == 0)
+   link_error ();
+}
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "evrp" } }  */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index d553a254878..2ddb0c2c197 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1437,6 +1437,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
   && code != PLUS_EXPR
   && code != MINUS_EXPR
   && code != RSHIFT_EXPR
+  && code != POINTER_PLUS_EXPR
   && (vr0.type == VR_VARYING
  || vr1.type == VR_VARYING
  || vr0.type != vr1.type
@@ -1467,7 +1468,11 @@ extract_range_from_binary_expr_1 (value_range *vr,
{
  /* For pointer types, we are really only interested in asserting
 whether the expression evaluates to non-NULL.  */
- if (range_is_nonnull () || range_is_nonnull ())
+ if (range_is_nonnull ()
+ || range_is_nonnull ()
+ || (vr1.type == VR_RANGE
+ && !symbolic_range_p ()
+ && !range_includes_zero_p (vr1.min, vr1.max)))
set_value_range_to_nonnull (vr, expr_type);
  else if (range_is_null () && range_is_null ())
set_value_range_to_null (vr, expr_type);


Re: [PATCH] PR libstdc++/86963 Implement LWG 2729 constraints on tuple assignment

2018-08-20 Thread Jonathan Wakely

On 17/08/18 19:54 +0100, Jonathan Wakely wrote:

On 17/08/18 19:01 +0100, Jonathan Wakely wrote:

On 17/08/18 18:52 +0100, Jonathan Wakely wrote:

+  // The tag parameter ensures that in nested tuples each __tuple_base
+  // is a different type and can use the empty base-class optimisation.
+  template
+class __tuple_base


Specifically, this would fail if __tuple_base was not a class
template:

static_assert(sizeof(tuple>) == sizeof(int), "");

And also:

struct empty {};
static_assert(sizeof(tuple, tuple>) == 2, "");



In fact, it's just occurred to me that we don't really need the
__tuple_base class template at all. We can make _Tuple_impl
non-assignable (adding _M_assign members for the required
functionality). Then we don't need an extra base class.


Which is what this patch does. I think it's cleaner than needing the
__tuple_base base class.

Tested x86_64-linux and committed to trunk.

commit 1af2f8e775e0f742b530912a3e988316f2c74375
Author: Jonathan Wakely 
Date:   Fri Aug 17 20:37:29 2018 +0100

PR libstdc++/86963 Remove use of __tuple_base in std::tuple

The _Tuple_impl base class can be used to disable copy/move assignment,
without requiring an extra base class.

Exception specifications on std::tuple assignment and swap functions can
be defined directly using is_nothrow_swappable, instead of querying the
base classes.

PR libstdc++/86963
* include/std/tuple (_Tuple_impl::operator=): Define as deleted.
(_Tuple_impl::_M_assign): New functions to perform assignment instead
of assignment operators.
(_Tuple_impl::_M_swap): Remove exception specification.
(_Tuple_impl<_Idx, _Head>): Likewise.
(_TC::_NonNestedTuple, _TC::_NotSameTuple): Use __remove_cvref_t.
(__tuple_base): Remove.
(tuple, tuple<_T1, _T2>): Remove inheritance from __tuple_base.
(tuple::operator=, tuple<_T1, _T2>::operator=): Call _M_assign.
(tuple::swap, tuple<_T1, _T2>::swap): Define exception specification
using __is_nothrow_swappable.
(tuple<_T1, _T2>::tuple(_U1&&, _U2&&)): Use __remove_cvref_t.

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 955b853066f..56b97c25eed 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -219,6 +219,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr _Tuple_impl(const _Tuple_impl&) = default;
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2729. Missing SFINAE on std::pair::operator=
+  _Tuple_impl& operator=(const _Tuple_impl&) = delete;
+
   constexpr
   _Tuple_impl(_Tuple_impl&& __in)
   noexcept(__and_,
@@ -288,49 +292,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 std::forward<_UHead>
 		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
 
-  _Tuple_impl&
-  operator=(const _Tuple_impl& __in)
-  {
-	_M_head(*this) = _M_head(__in);
-	_M_tail(*this) = _M_tail(__in);
-	return *this;
-  }
-
-  _Tuple_impl&
-  operator=(_Tuple_impl&& __in)
-  noexcept(__and_,
-	  is_nothrow_move_assignable<_Inherited>>::value)
-  {
-	_M_head(*this) = std::forward<_Head>(_M_head(__in));
-	_M_tail(*this) = std::move(_M_tail(__in));
-	return *this;
-  }
-
   template
-_Tuple_impl&
-operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
+void
+_M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
 {
 	  _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
-	  _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
-	  return *this;
+	  _M_tail(*this)._M_assign(
+	  _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
 	}
 
   template
-_Tuple_impl&
-operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+void
+_M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
 {
 	  _M_head(*this) = std::forward<_UHead>
 	(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
-	  _M_tail(*this) = std::move
-	(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
-	  return *this;
+	  _M_tail(*this)._M_assign(
+	  std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
 	}
 
 protected:
   void
   _M_swap(_Tuple_impl& __in)
-  noexcept(__is_nothrow_swappable<_Head>::value
-   && noexcept(_M_tail(__in)._M_swap(_M_tail(__in
   {
 	using std::swap;
 	swap(_M_head(*this), _M_head(__in));
@@ -367,6 +350,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr _Tuple_impl(const _Tuple_impl&) = default;
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2729. Missing SFINAE on std::pair::operator=
+  _Tuple_impl& operator=(const _Tuple_impl&) = delete;
+
   constexpr
   _Tuple_impl(_Tuple_impl&& __in)
   noexcept(is_nothrow_move_constructible<_Head>::value)
@@ -420,42 +407,24 @@ 

Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Richard Biener
On Mon, 20 Aug 2018, Bernd Edlinger wrote:

> On 08/20/18 12:41, Richard Biener wrote:
> > On Sun, 19 Aug 2018, Bernd Edlinger wrote:
> > 
> >> Hi!
> >>
> >>
> >> This fixes a wrong code issue in expand_expr_real_1 which happens because
> >> a negative bitpos is actually able to reach extract_bit_field which
> >> does all computations with poly_uint64, thus the offset 0x1ff0.
> >>
> >> To avoid that I propose to use Jakub's r20 patch from the 
> >> expand_assignment
> >> also in the expand_expr_real_1.
> >>
> >> This is a rather unlikely thing to happen, as there are lots of checks 
> >> that are
> >> of course all target dependent between the get_inner_reference and the
> >> actual extract_bit_field call, and all other code paths may or may not 
> >> have a problem
> >> with negative bit offsets.  Most don't have a problem, but the bitpos 
> >> needs to be
> >> folded into offset before it is used, therefore it is necessary to handle 
> >> the negative
> >> bitpos very far away from the extract_bit_field call.  Doing that later is 
> >> IMHO not
> >> possible.
> >>
> >> The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted it 
> >> because
> >> this macro is used in alpha_legitimize_address which is of course what one 
> >> looks
> >> at first if something like that happens.
> >>
> >> I think even with this bogus offset it should not have caused a linker 
> >> error, so there
> >> is probably a second problem in the *movdi code pattern of the alpha.md, 
> >> because it
> >> should be split into instructions that don't cause a link error.
> >>
> >> Once the target is fixed to split the impossible assembler instruction, 
> >> the test case
> >> will probably no longer be able to detect the pattern in the assembly.
> >>
> >> Therefore the test case looks both at the assembler output and the expand 
> >> rtl dump
> >> to spot the bogus offset.  I only check the first 12 digits of the bogus 
> >> constant,
> >> because it is actually dependent on the target configuration:
> >>
> >> I built first a cross-compiler without binutils, and it did used a 
> >> slightly different
> >> offset of 0x2000, (configured with: --target=alpha-linux-gnu 
> >> --enable-languages=c
> >> --disable-libgcc --disable-libssp --disable-libquadmath --disable-libgomp 
> >> --disable-libatomic)
> >> when the binutils are installed at where --prefix points, the offset is 
> >> 0x1ff0.
> >>
> >> Regarding the alpha target, I could not do more than build a cross 
> >> compiler and run
> >> make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".
> >>
> >>
> >> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> >> Is it OK for trunk?
> > 
> > Hmm, I don't remember why we are inconsistent in get_inner_reference
> > with respect to negative bitpos.  I think we should be consistent
> > here and may not be only by accident?  That is, does
> > 
> > diff --git a/gcc/expr.c b/gcc/expr.c
> > index c071be67783..9dc78587136 100644
> > --- a/gcc/expr.c
> > +++ b/gcc/expr.c
> > @@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod
> > *pbitsize,
> >TYPE_PRECISION (sizetype));
> > tem <<= LOG2_BITS_PER_UNIT;
> > tem += bit_offset;
> > -  if (tem.to_shwi (pbitpos))
> > +  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
> >  *poffset = offset = NULL_TREE;
> >   }
> >   
> > fix the issue?
> > 
> 
> Yes, at first sight, however, I was involved at PR 58970,
> see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58970
> 
> and I proposed a similar patch, which was objected by Jakub:
> 
> see comment #25 of PR 58970:
> "Jakub Jelinek 2013-11-05 19:41:12 UTC
> 
> (In reply to Bernd Edlinger from comment #24)
> > Created attachment 31169 [details] 
> > https://gcc.gnu.org/bugzilla/attachment.cgi?id=31169
> > Another (better) attempt at fixing this ICE.
> > 
> > This avoids any negative bitpos from get_inner_reference.
> > These negative bitpos values are just _very_ dangerous all the
> > way down to expmed.c
> 
> I disagree that it is better, you are forgetting get_inner_reference has 
> other > 20 callers outside of expansion and there is no reason why negative 
> bitpos would be a problem in those cases."
> 
> So that is what Jakub said at that time, and with the
> suggested change in get_inner_reference,
> this part of the r20 change would be effectively become superfluous:
> 
> @@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, bool nontem
> tem = get_inner_reference (to, , , , ,
>   , , true);
>   
> +  /* Make sure bitpos is not negative, it can wreak havoc later.  */
> +  if (bitpos < 0)
> +   {
> + gcc_assert (offset == NULL_TREE);
> + offset = size_int (bitpos >> (BITS_PER_UNIT == 8
> +   ? 3 : exact_log2 (BITS_PER_UNIT)));
> + bitpos &= BITS_PER_UNIT - 1;
> +   }
> +
> 

Re: [PATCH] Make GO string literals properly NUL terminated

2018-08-20 Thread Richard Biener
On Mon, 20 Aug 2018, Bernd Edlinger wrote:

> On 08/20/18 13:01, Richard Biener wrote:
> > On Wed, Aug 1, 2018 at 3:05 PM Bernd Edlinger  
> > wrote:
> >>
> >>
> >>
> >> On 08/01/18 11:29, Richard Biener wrote:
> >>>
> >>> Hmm.  I think it would be nice if TREE_STRING_LENGTH would
> >>> match char[2] and TYPE_SIZE_UNIT even if that is inconvenient
> >>> for your check above.  Because the '\0' doesn't belong to the
> >>> string.  Then build_string internally appends a '\0' outside
> >>> of TREE_STRING_LENGTH.
> >>>
> >>
> >> Hmm. Yes, but the outside-0 byte is just one byte, not a wide
> >> character.
> > 
> > That could be fixed though (a wide 0 is just N 0s).  Add a elsz = 1
> > parameter to build_string and allocate as many extra 0s as needed.
> > 
> >There are STRING_CSTs which are not string literals,
> >> for instance attribute tags, Pragmas, asm constrants, etc.
> >> They use the '\0' outside, and have probably no TREE_TYPE.
> >>
> >>>
>  So I would like to be able to assume that the STRING_CST objects
>  are internally always generated properly by the front end.
> >>>
> >>> Yeah, I guess we need to define what "properly" is ;)
> >>>
> >> Yes.
> >>
>  And that the ARRAY_TYPE of the string literal either has the
>  same length than the TREE_STRING_LENGTH or if it is shorter,
>  this is always exactly one (wide) character size less than 
>  TREE_STRING_LENGTH
> >>>
> >>> I think it should be always the same...
> >>>
> >>
> >> One could not differentiate between "\0" without zero-termination
> >> and "" with zero-termination, theoretically.
> > 
> > Is that important?  Doesn't the C standard say how to parse string literals?
> > 
> >> We also have char x[100] = "ab";
> >> that is TREE_STRING_LENGTH=3, and TYPE_SIZE_UNIT(TREE_TYPE(x)) = 100.
> >> Of course one could create it with a TREE_STRING_LENGTH = 100,
> >> but imagine char x[1000] = "ab"
> > 
> > The question is more about TYPE_SIZE_UNIT (TREE_TYPE ("ab")) which I
> > hope matches "ab" and not 'x'.  If it matches 'x' then I'd rather have it
> > unconditionally be [], thus incomplete (because the literals "size" depends
> > on the context/LHS it is used on).
> > 
> 
> Sorry, but I must say, it is not at all like that.
> 
> If I compile x.c:
> const char x[100] = "ab";
> 
> and set a breakpoint at output_constant:
> 
> Breakpoint 1, output_constant (exp=0x76ff9dc8, size=100, align=256,
>  reverse=false) at ../../gcc-trunk/gcc/varasm.c:4821
> 4821if (size == 0 || flag_syntax_only)
> (gdb) p size
> $1 = 100
> (gdb) call debug(exp)
> "ab"
> (gdb) p *exp
> $2 = {base = {code = STRING_CST, side_effects_flag = 0, constant_flag = 1,
> (gdb) p exp->typed.type->type_common.size_unit
> $5 = (tree) 0x76ff9d80
> (gdb) call debug(exp->typed.type->type_common.size_unit)
> 100
> (gdb) p exp->string.length
> $6 = 3
> (gdb) p exp->string.str[0]
> $8 = 97 'a'
> (gdb) p exp->string.str[1]
> $9 = 98 'b'
> (gdb) p exp->string.str[2]
> $10 = 0 '\000'
> (gdb) p exp->string.str[3]
> $11 = 0 '\000'
> 
> 
> This is an important property of string_cst objects, that is used in c_strlen:
> 
> It folds c_strlen([4]) directly to 0, because every byte beyond 
> TREE_STRING_LENGTH
> is guaranteed to be zero up to the type size.
> 
> I would not have spent one thought on implementing an optimization like that,
> but that's how it is right now.

Huh.  So somebody interpreted STRING_CSTs similar to CONSTRUCTORs aka
they have zero-padding up to its type size.  I don't see this documented
anywhere and it would suggest to "optimize" "ab\0\0\0\0" to "ab\0"
with appropriate TYPE_SIZE.

This is also a relatively new thing on trunk (coming out of the added
mem_size parameter of string_constant).  That this looks at the STRING_CST
type like

  if (TREE_CODE (array) == STRING_CST)
{
  *ptr_offset = fold_convert (sizetype, offset);
  if (mem_size)
*mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
  return array;

I'd call simply a bug.  As said, interpretation of STRING_CSTs should
depend on the context.  And for

char a[4] = "abc";
char b[5] = "abc";

we should better be able to share STRING_CSTs [you can see LTO
sharing the nodes if you do b[4] but not when b[5] I suppose].

> All I want to do, is make sure that all string constants have the same look 
> and feel
> in the middle-end, and restrict the variations that are allowed by the current
> implementation.

Sure, I understand that.  But I'd like to simplify things and not add
complications like looking at TYPE_SIZE vs. TREE_STRING_LENGTH to decide
whether sth is 0-terminated.

Richard.

> 
> Bernd.
> 
> 
>  The idea is to use this property of string literals where needed,
>  and check rigorously in varasm.c.
> 
>  Does that make sense?
> >>>
> >>> So if it is not the same then the excess character needs to be
> >>> a (wide) NUL in your model?  ISTR your varasm.c patch didn't verify
> >>> that.
> >>>
> >>
> >> I think it does.
> >>
> >>
> >> Bernd.
> 

Re: [PATCH][debug] Fix handling of vlas in lto

2018-08-20 Thread Richard Biener
On Fri, 17 Aug 2018, Tom de Vries wrote:

> I've rewritten the patch to work generically, not just for DW_AT_upper_bound,
> and to reuse the code already there in add_scalar_info.
> 
> OK for trunk?
> 
> Thanks,
> - Tom
> 
> [debug] Fix handling of vlas in lto
> 
> Atm, when running vla-1.c with -O0 -flto, we have:
> ...
> FAIL: gcc.dg/guality/vla-1.c -O0 -flto -fuse-linker-plugin \
>   -fno-fat-lto-objects line 17 sizeof (a) == 6
> ...
> 
> The vla a[i + 1] in f1 is gimplified into:
> ...
> f1 (int i)
> {
>   char a[0:D.1922] [value-expr: *a.0];
>   char[0:D.1922] * a.0;
> 
>   D.1921 = i + 1;
>   D.1926 = (sizetype) D.1921;
>   a.0 = __builtin_alloca_with_align (D.1926, 8);
> ...
> 
> The early debug info for the upper bound of the type of vla a that we stream
> out is:
> ...
>   DIE0: DW_TAG_subrange_type (0x7f85029a90f0)
> DW_AT_upper_bound: location descriptor:
>   (0x7f85029a9230) DW_OP_GNU_variable_value die -> 0 (0x7f85029a94b0), 0
>   DIE0: DW_TAG_variable (0x7f85029a94b0)
> DW_AT_name: "D.1922"
> DW_AT_type: die -> 0 (0x7f85029a3d70)
> DW_AT_artificial: 1
> ...
> 
> and in ltrans we have for that same upper bound:
> ...
>   DIE0: DW_TAG_subrange_type (0x7f5183b57d70)
> DW_AT_upper_bound: die -> 0 (0x7f5183b576e0)
>   DIE0: DW_TAG_variable (0x7f5183b576e0)
> DW_AT_name: "D.4278"
> DW_AT_abstract_origin: die -> label: vla_1.c.6719312a + 193 
> (0x7f5183b57730)
> ...
> where D.4278 has abstract origin D.1922.
> 
> The D.4278 die has no DW_AT_location, so when evaluting "sizeof (a)" in the
> debugger, we can't find the information to get the value of D.4278, and the
> debugger prints "".
> 
> This patch fixes that by either:
> - adding DW_AT_location to the referenced variable die, or
> - instead of using a ref for the upper bound, using an exprloc.
> 
> When changing gcc.dg/guality/guality.exp to run the usual flto flavours
> "-fno-use-linker-plugin -flto-partition=none" and "-fuse-linker-plugin
> -fno-fat-lto-objects" in combination with O0, Og, O1, O2, O3 and Os, this 
> patch
> fixes all (20) failures in vla-1.c, leaving only:
> ...
> No symbol "i" in current context.
> UNSUPPORTED: gcc.dg/guality/vla-1.c  -O3 -flto -fno-use-linker-plugin \
>   -flto-partition=none line 17 i == 5
> 'a' has unknown type; cast it to its declared type
> UNSUPPORTED: gcc.dg/guality/vla-1.c  -O3 -flto -fno-use-linker-plugin \
>   -flto-partition=none line 17 sizeof (a) == 6
> ...
> 
> Bootstrapped and reg-tested on x86_64.

This looks OK to me.  Note that with a gdb with DW_OP_variable_value 
support we should be able to elide the VLA type in the concrete
instance...

Not sure how we should go forward there - use a configure test or
simply tell people to update gdb?

Thanks,
Richard.

> 2018-08-17  Tom de Vries  
> 
>   * dwarf2out.c (add_scalar_info): Don't add reference to existing die
>   unless the referenced die describes the added property using
>   DW_AT_location or DW_AT_const_value.  Fall back to exprloc case.
>   Otherwise, add a DW_AT_location to the referenced die.
> 
> ---
>  gcc/dwarf2out.c | 32 
>  1 file changed, 20 insertions(+), 12 deletions(-)
> 
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index 9ed473088e7..e1dccb42823 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -20598,7 +20598,7 @@ static void
>  add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
>int forms, struct loc_descr_context *context)
>  {
> -  dw_die_ref context_die, decl_die;
> +  dw_die_ref context_die, decl_die = NULL;
>dw_loc_list_ref list;
>bool strip_conversions = true;
>bool placeholder_seen = false;
> @@ -20675,7 +20675,7 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute 
> attr, tree value,
>  
>if (decl != NULL_TREE)
>   {
> -   dw_die_ref decl_die = lookup_decl_die (decl);
> +   decl_die = lookup_decl_die (decl);
>  
> /* ??? Can this happen, or should the variable have been bound
>first?  Probably it can, since I imagine that we try to create
> @@ -20684,8 +20684,12 @@ add_scalar_info (dw_die_ref die, enum 
> dwarf_attribute attr, tree value,
>later parameter.  */
> if (decl_die != NULL)
>   {
> -   add_AT_die_ref (die, attr, decl_die);
> -   return;
> +   if (get_AT (decl_die, DW_AT_location)
> +   || get_AT (decl_die, DW_AT_const_value))
> + {
> +   add_AT_die_ref (die, attr, decl_die);
> +   return;
> + }
>   }
>   }
>  }
> @@ -20729,15 +20733,19 @@ add_scalar_info (dw_die_ref die, enum 
> dwarf_attribute attr, tree value,
>|| placeholder_seen)
>  return;
>  
> -  if (current_function_decl == 0)
> -context_die = comp_unit_die ();
> -  else
> -context_die = lookup_decl_die (current_function_decl);
> +  if (!decl_die)
> +{
> +  if (current_function_decl == 0)
> 

Re: [RFC][debug] Add -greadable-dwarf

2018-08-20 Thread Richard Biener
On Wed, 15 Aug 2018, Tom de Vries wrote:

> Hi,
> 
> This patch adds option -greadable-dwarf.  In absence of an DW_AT_comment
> attribute,

What's a DW_AT_comment attribute?  I don't see this mentioned in the
patch.

> it sets the DW_AT_name attribute of dies that otherwise do not get
> that attribute, to make it easier to figure out what the die is describing.
> 
> The option exports the names of artificial variables:
> ...
>  DIE0: DW_TAG_variable (0x7fa934dd54b0)
> +  DW_AT_name: "D.1922"
>DW_AT_type: die -> 0 (0x7fa934dd0d70)
>DW_AT_artificial: 1
> 
> ...
> which can be traced back to gimple dumps:
> ...
>   char a[0:D.1922] [value-expr: *a.0];
> ...
> 
> Furthermore, it adds names to external references:
> ...
>  DIE0: DW_TAG_subprogram (0x7fa88b9650f0)
> +DW_AT_name: "main"
>  DW_AT_abstract_origin: die -> label: vla_1.c.6719312a + 29 (0x7fa88b965140)
> ...
> 
> This is an undocumented developer-only option, because using this option may
> change behaviour of dwarf consumers, f.i., gdb shows the artificial variables:
> ...
> (gdb) info locals
> a = 0x7fffda90 "\005"
> D.4278 = 
> ...
> 
> Any comments?

The idea is OK I guess but I'd call it -gforce-named-dies instead
of -greadable-dwarf.  It also goes only half-way since it doesn't
add names to DECL_NAMELESS vars.

There doesn't seem to be a convenient place to 

> Thanks,
> - Tom
> 
> [debug] Add -greadable-dwarf
> 
> 2018-08-15  Tom de Vries  
> 
>   * common.opt (greadable-dwarf): Add option.
>   * dwarf2out.c (add_name_and_src_coords_attributes): Add param. Add name
>   for artifical decls.
>   (add_decl_name): New function.
>   (dwarf2out_register_external_die): Add name to external reference die.
> 
> ---
>  gcc/common.opt  |  5 +
>  gcc/dwarf2out.c | 24 +---
>  2 files changed, 26 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/common.opt b/gcc/common.opt
> index b2f2215ecc6..6e5e0558e49 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2972,6 +2972,11 @@ gstrict-dwarf
>  Common Driver Report Var(dwarf_strict) Init(0)
>  Don't emit DWARF additions beyond selected version.
>  
> +greadable-dwarf
> +Common Driver Undocumented Report Var(flag_readable_dwarf) Init(0)
> +Make generated dwarf more readable, at the cost of space and exposing 
> compiler
> +internals.
> +
>  gtoggle
>  Common Driver Report Var(flag_gtoggle)
>  Toggle debug information generation.
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index 4b63cbd8a1e..8c6b4372874 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -3824,7 +3824,9 @@ static void add_prototyped_attribute (dw_die_ref, tree);
>  static dw_die_ref add_abstract_origin_attribute (dw_die_ref, tree);
>  static void add_pure_or_virtual_attribute (dw_die_ref, tree);
>  static void add_src_coords_attributes (dw_die_ref, tree);
> -static void add_name_and_src_coords_attributes (dw_die_ref, tree, bool = 
> false);
> +static void add_name_and_src_coords_attributes (dw_die_ref, tree, bool = 
> false,
> + bool = false);
> +static void add_decl_name (dw_die_ref, tree);
>  static void add_discr_value (dw_die_ref, dw_discr_value *);
>  static void add_discr_list (dw_die_ref, dw_discr_list_ref);
>  static inline dw_discr_list_ref AT_discr_list (dw_attr_node *);
> @@ -6022,6 +6024,8 @@ dwarf2out_register_external_die (tree decl, const char 
> *sym,
>else
>  equate_decl_number_to_die (decl, die);
>  
> +  if (flag_readable_dwarf)
> +add_decl_name (die, decl);

Please use add_name_and_src_coords_attributes directly.

>/* Add a reference to the DIE providing early debug at $sym + off.  */
>add_AT_external_die_ref (die, DW_AT_abstract_origin, sym, off);
>  }
> @@ -21269,7 +21273,8 @@ add_linkage_name (dw_die_ref die, tree decl)
>  
>  static void
>  add_name_and_src_coords_attributes (dw_die_ref die, tree decl,
> - bool no_linkage_name)
> + bool no_linkage_name,
> + bool no_src_coords_attributes)
>  {
>tree decl_name;
>  
> @@ -21279,12 +21284,19 @@ add_name_and_src_coords_attributes (dw_die_ref die, 
> tree decl,
>const char *name = dwarf2_name (decl, 0);
>if (name)
>   add_name_attribute (die, name);
> -  if (! DECL_ARTIFICIAL (decl))
> +  if (!no_src_coords_attributes && ! DECL_ARTIFICIAL (decl))

inconsistent spacing after !

>   add_src_coords_attributes (die, decl);
>  
>if (!no_linkage_name)
>   add_linkage_name (die, decl);
>  }
> +  else if (flag_readable_dwarf && decl_name == NULL)
> +{
> +  char *buf = XNEWVEC (char, 32);
> +  char decl_letter = TREE_CODE (decl) == CONST_DECL ? 'C' : 'D';
> +  sprintf (buf, "%c.%u", decl_letter, DECL_UID (decl));
> +  add_name_attribute (die, buf);

I think you leak 'buf'.

> +}
>  
>  #ifdef VMS_DEBUGGING_INFO

how does it interact with this VMS_DEBUGGING_INFO path?


[PATCH] #assert becomes macro-like

2018-08-20 Thread Nathan Sidwell
The preprocessor has cpp-asserts, a deprecated extension.  They look 
like macros in that they have a tokenized body, but there's a chain of 
them hanging off an assert node, rather than having any parms.


This patch removes their 'answer' struct, and extends cpp_macro to 
represent them.  the enum macro_kind gains a value, and the parameter 
pointer is now held in a union keyed off the macro kind.


The hashnode value union still contains 'answer' and 'macro' fields, 
even though they have the same underlying type.  Clean up of that union 
will happen later.


The remaining changes are mechanical (the answer struct already used the 
trailing array hack for the tokens, so drops straight into the update 
cpp_macro representation).


booted & tested on x86_64-linux, committing to trunk.

nathan
--
Nathan Sidwell
2018-08-20  Nathan Sidwell  

	libcpp/
	* include/cpp-id-data.h (struct answer): Delete.
	* include/cpplib.h (struct answer): Don't forward-declare.
	(enum cpp_macro_kind): Add cmk_assert.
	(struct cpp_macro): Union parms and next assert chain.
	(union _cpp_hashnode_value): 'answer' field is cpp_macro.
	* directives.c (parse_answer): Convert to use cpp_macro. Return
	true on success. 
	(parse_assertion, find_answer, _cpp_test_assertion, cpp_do_assert)
	(cpp_do_unassert): Convert to use cpp_macro.
	* macro.c (warn_of_redefinition, _cpp_new_macro)
	(check_trad_stringification, cpp_macro_definition): Adjust macro
	parm access.
	* traditional.c (_cpp_replacement_text_len)
	(_cpp_copy_replacement_text, _cpp_create_trad_definition): Likewise.
	gcc/c-family/
	* c-ada-spec.c (macro_length, dump_ada_macros): Adjust macro parm
	access.

Index: gcc/c-family/c-ada-spec.c
===
--- gcc/c-family/c-ada-spec.c	(revision 263656)
+++ gcc/c-family/c-ada-spec.c	(working copy)
@@ -69,7 +69,7 @@ macro_length (const cpp_macro *macro, in
   (*param_len)++;
   for (i = 0; i < macro->paramc; i++)
 	{
-	  cpp_hashnode *param = macro->params[i];
+	  cpp_hashnode *param = macro->parm.params[i];
 
 	  *param_len += NODE_LEN (param);
 
@@ -101,7 +101,7 @@ macro_length (const cpp_macro *macro, in
 
   if (token->type == CPP_MACRO_ARG)
 	*buffer_len +=
-	  NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
+	  NODE_LEN (macro->parm.params[token->val.macro_arg.arg_no - 1]);
   else
 	/* Include enough extra space to handle e.g. special characters.  */
 	*buffer_len += (cpp_token_len (token) + 1) * 8;
@@ -252,7 +252,7 @@ dump_ada_macros (pretty_printer *pp, con
 	  *buf_param++ = '(';
 	  for (i = 0; i < macro->paramc; i++)
 		{
-		  cpp_hashnode *param = macro->params[i];
+		  cpp_hashnode *param = macro->parm.params[i];
 
 		  memcpy (buf_param, NODE_NAME (param), NODE_LEN (param));
 		  buf_param += NODE_LEN (param);
@@ -291,7 +291,7 @@ dump_ada_macros (pretty_printer *pp, con
 		  case CPP_MACRO_ARG:
 		{
 		  cpp_hashnode *param =
-			macro->params[token->val.macro_arg.arg_no - 1];
+			macro->parm.params[token->val.macro_arg.arg_no - 1];
 		  memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
 		  buffer += NODE_LEN (param);
 		}
Index: libcpp/directives.c
===
--- libcpp/directives.c	(revision 263656)
+++ libcpp/directives.c	(working copy)
@@ -124,9 +124,9 @@ static const cpp_token *get_token_no_pad
 static const cpp_token *get__Pragma_string (cpp_reader *);
 static void destringize_and_run (cpp_reader *, const cpp_string *,
  source_location);
-static int parse_answer (cpp_reader *, struct answer **, int, source_location);
-static cpp_hashnode *parse_assertion (cpp_reader *, struct answer **, int);
-static struct answer ** find_answer (cpp_hashnode *, const struct answer *);
+static bool parse_answer (cpp_reader *, int, source_location, cpp_macro **);
+static cpp_hashnode *parse_assertion (cpp_reader *, int, cpp_macro **);
+static cpp_macro **find_answer (cpp_hashnode *, const cpp_macro *);
 static void handle_assertion (cpp_reader *, const char *, int);
 static void do_pragma_push_macro (cpp_reader *);
 static void do_pragma_pop_macro (cpp_reader *);
@@ -2149,17 +2149,13 @@ push_conditional (cpp_reader *pfile, int
storage, i.e. the #assert case.  Returns 0 on success, and sets
ANSWERP to point to the answer.  PRED_LOC is the location of the
predicate.  */
-static int
-parse_answer (cpp_reader *pfile, struct answer **answerp, int type,
-	  source_location pred_loc)
+static bool
+parse_answer (cpp_reader *pfile, int type, source_location pred_loc,
+	  cpp_macro **answer_ptr)
 {
-  const cpp_token *paren;
-  struct answer *answer;
-  unsigned int acount;
-
   /* In a conditional, it is legal to not have an open paren.  We
  should save the following token in this case.  */
-  paren = cpp_get_token (pfile);
+  const cpp_token *paren = cpp_get_token (pfile);
 
   /* If not a paren, see if we're OK.  */
   if (paren->type != 

Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Bernd Edlinger
On 08/20/18 12:41, Richard Biener wrote:
> On Sun, 19 Aug 2018, Bernd Edlinger wrote:
> 
>> Hi!
>>
>>
>> This fixes a wrong code issue in expand_expr_real_1 which happens because
>> a negative bitpos is actually able to reach extract_bit_field which
>> does all computations with poly_uint64, thus the offset 0x1ff0.
>>
>> To avoid that I propose to use Jakub's r20 patch from the 
>> expand_assignment
>> also in the expand_expr_real_1.
>>
>> This is a rather unlikely thing to happen, as there are lots of checks that 
>> are
>> of course all target dependent between the get_inner_reference and the
>> actual extract_bit_field call, and all other code paths may or may not have 
>> a problem
>> with negative bit offsets.  Most don't have a problem, but the bitpos needs 
>> to be
>> folded into offset before it is used, therefore it is necessary to handle 
>> the negative
>> bitpos very far away from the extract_bit_field call.  Doing that later is 
>> IMHO not
>> possible.
>>
>> The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted it 
>> because
>> this macro is used in alpha_legitimize_address which is of course what one 
>> looks
>> at first if something like that happens.
>>
>> I think even with this bogus offset it should not have caused a linker 
>> error, so there
>> is probably a second problem in the *movdi code pattern of the alpha.md, 
>> because it
>> should be split into instructions that don't cause a link error.
>>
>> Once the target is fixed to split the impossible assembler instruction, the 
>> test case
>> will probably no longer be able to detect the pattern in the assembly.
>>
>> Therefore the test case looks both at the assembler output and the expand 
>> rtl dump
>> to spot the bogus offset.  I only check the first 12 digits of the bogus 
>> constant,
>> because it is actually dependent on the target configuration:
>>
>> I built first a cross-compiler without binutils, and it did used a slightly 
>> different
>> offset of 0x2000, (configured with: --target=alpha-linux-gnu 
>> --enable-languages=c
>> --disable-libgcc --disable-libssp --disable-libquadmath --disable-libgomp 
>> --disable-libatomic)
>> when the binutils are installed at where --prefix points, the offset is 
>> 0x1ff0.
>>
>> Regarding the alpha target, I could not do more than build a cross compiler 
>> and run
>> make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".
>>
>>
>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>> Is it OK for trunk?
> 
> Hmm, I don't remember why we are inconsistent in get_inner_reference
> with respect to negative bitpos.  I think we should be consistent
> here and may not be only by accident?  That is, does
> 
> diff --git a/gcc/expr.c b/gcc/expr.c
> index c071be67783..9dc78587136 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod
> *pbitsize,
>TYPE_PRECISION (sizetype));
> tem <<= LOG2_BITS_PER_UNIT;
> tem += bit_offset;
> -  if (tem.to_shwi (pbitpos))
> +  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
>  *poffset = offset = NULL_TREE;
>   }
>   
> fix the issue?
> 

Yes, at first sight, however, I was involved at PR 58970,
see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58970

and I proposed a similar patch, which was objected by Jakub:

see comment #25 of PR 58970:
"Jakub Jelinek 2013-11-05 19:41:12 UTC

(In reply to Bernd Edlinger from comment #24)
> Created attachment 31169 [details] 
> https://gcc.gnu.org/bugzilla/attachment.cgi?id=31169
> Another (better) attempt at fixing this ICE.
> 
> This avoids any negative bitpos from get_inner_reference.
> These negative bitpos values are just _very_ dangerous all the
> way down to expmed.c

I disagree that it is better, you are forgetting get_inner_reference has other 
> 20 callers outside of expansion and there is no reason why negative bitpos 
would be a problem in those cases."

So that is what Jakub said at that time, and with the
suggested change in get_inner_reference,
this part of the r20 change would be effectively become superfluous:

@@ -4721,6 +4721,15 @@ expand_assignment (tree to, tree from, bool nontem
tem = get_inner_reference (to, , , , ,
  , , true);
  
+  /* Make sure bitpos is not negative, it can wreak havoc later.  */
+  if (bitpos < 0)
+   {
+ gcc_assert (offset == NULL_TREE);
+ offset = size_int (bitpos >> (BITS_PER_UNIT == 8
+   ? 3 : exact_log2 (BITS_PER_UNIT)));
+ bitpos &= BITS_PER_UNIT - 1;
+   }
+
if (TREE_CODE (to) == COMPONENT_REF
   && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
 get_bit_range (_start, _end, to, , );

and should be reverted.  I did not really like it then, but I'd respect Jakub's 
advice.


Bernd.



> Richard.
> 


Re: Fix even more merging PIC and PIE options

2018-08-20 Thread Richard Biener
On Fri, 10 Aug 2018, Jan Hubicka wrote:

> Hi,
> this patch should fix merging of PIC and PIE options so we always resort
> to the least common denominator of the object files compiled (i.e. 
> linking together -fpic and -fPIE will result in -fpie binary).
> Note that we also use information about format of output passed by linker
> plugin so we will disable pic/pie when resulting binary is not relocatable.
> However for shared libraries and pie we want to pick right mode that makes
> sense.
> 
> I wrote simple script that tries all possible options of combining two files.
> Mode picked is specified in the output file.
> 
> To support targets that default to pic/pie well, I had to also hack
> lto_write_options to always stream what mode was used in the given file.
> 
> lto-bootstrapped/regtested x86_64-linux, OK?
> 
> Honza
> 
>   PR lto/86517
>   * lto-opts.c (lto_write_options): Always stream PIC/PIE mode.
>   * lto-wrapper.c (merge_and_complain): Fix merging of PIC/PIE
> Index: lto-opts.c
> ===
> --- lto-opts.c(revision 263356)
> +++ lto-opts.c(working copy)
> @@ -78,6 +78,22 @@ lto_write_options (void)
>&& !global_options.x_flag_openacc)
>  append_to_collect_gcc_options (_obstack, _p,
>  "-fno-openacc");
> +  /* Append PIC/PIE mode because its default depends on target and it is
> + subject of merging in lto-wrapper.  */
> +  if ((!global_options_set.x_flag_pic || global_options.x_flag_pic == 0)

why's that checked only for flag_pic?
Shouldn't it be consistent with flag_pie?

Isn't it so that setting either -f[no-]pic or -f[no-]pie fully specifies
the state?  So the == 0 check is superfluous?

The rest of the patch looks OK to me.

Thanks,
Richard.

> +  && !global_options_set.x_flag_pie)
> +{
> +   append_to_collect_gcc_options (_obstack, _p,
> +   global_options.x_flag_pic == 2
> +   ? "-fPIC"
> +   : global_options.x_flag_pic == 1
> +   ? "-fpic"
> +   : global_options.x_flag_pie == 2
> +   ? "-fPIE"
> +   : global_options.x_flag_pie == 1
> +   ? "-fpie"
> +   : "-fno-pie");
> +}
>  
>/* Append options from target hook and store them to offload_lto section.  
> */
>if (lto_stream_offload_p)
> Index: lto-wrapper.c
> ===
> --- lto-wrapper.c (revision 263356)
> +++ lto-wrapper.c (working copy)
> @@ -408,6 +408,11 @@ merge_and_complain (struct cl_decoded_op
>   It is a common mistake to mix few -fPIC compiled objects into otherwise
>   non-PIC code.  We do not want to build everything with PIC then.
>  
> + Similarly we merge PIE options, however in addition we keep
> +  -fPIC + -fPIE = -fPIE
> +  -fpic + -fPIE = -fpie
> +  -fPIC/-fpic + -fpie = -fpie
> +
>   It would be good to warn on mismatches, but it is bit hard to do as
>   we do not know what nothing translates to.  */
>  
> @@ -415,11 +420,38 @@ merge_and_complain (struct cl_decoded_op
>  if ((*decoded_options)[j].opt_index == OPT_fPIC
>  || (*decoded_options)[j].opt_index == OPT_fpic)
>{
> - if (!pic_option
> - || (pic_option->value > 0) != ((*decoded_options)[j].value > 0))
> -   remove_option (decoded_options, j, decoded_options_count);
> - else if (pic_option->opt_index == OPT_fPIC
> -  && (*decoded_options)[j].opt_index == OPT_fpic)
> + /* -fno-pic in one unit implies -fno-pic everywhere.  */
> + if ((*decoded_options)[j].value == 0)
> +   j++;
> + /* If we have no pic option or merge in -fno-pic, we still may turn
> +existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present.  */
> + else if ((pic_option && pic_option->value == 0)
> +  || !pic_option)
> +   {
> + if (pie_option)
> +   {
> + bool big = (*decoded_options)[j].opt_index == OPT_fPIC
> +&& pie_option->opt_index == OPT_fPIE;
> + (*decoded_options)[j].opt_index = big ? OPT_fPIE : OPT_fpie;
> + if (pie_option->value)
> +   (*decoded_options)[j].canonical_option[0] = big ? "-fPIE" : 
> "-fpie";
> + else
> +   (*decoded_options)[j].canonical_option[0] = big ? "-fno-pie" 
> : "-fno-pie";
> + (*decoded_options)[j].value = pie_option->value;
> + j++;
> +   }
> + else if (pic_option)
> +   {
> + (*decoded_options)[j] = *pic_option;
> + j++;
> +   }
> + /* We do not know if target defaults to pic or not, so just remove
> +option if it 

Re: [PATCH][debug] Add debug and earlydebug dumps

2018-08-20 Thread Richard Biener
On Mon, 13 Aug 2018, Tom de Vries wrote:

> Hi,
> 
> With the introduction of early debug, we've added a phase in the compiler 
> which
> produces information which is not visible, unless we run the compiler in the
> debugger and call debug_dwarf from dwarf2out_early_finish or some such.
> 
> This patch adds dumping of "early" and "final" debug info, into .earlydebug
> and .debug dump files, such that we can follow f.i. the upper bound of a vla
> type from early debug:
> ...
>   DW_AT_upper_bound: location descriptor:
> (0x7f0d645b7550) DW_OP_GNU_variable_value , 0
> ...
> to final debug:
> ...
>   DW_AT_upper_bound: location descriptor:
> (0x7f0d645b7550) DW_OP_fbreg 18446744073709551592, 0
> (0x7f0d645b7a00) DW_OP_deref 8, 0
> ...
> to -dA annotated assembly file:
> ...
> .uleb128 0x3# DW_AT_upper_bound
> .byte   0x91# DW_OP_fbreg
> .sleb128 -24
> .byte   0x6 # DW_OP_deref
> ...
> 
> The .debug file shows the same information as the annotated assembly, but in
> the same format as the "early" debug info.
> 
> Bootstrapped and reg-tested on x86_64.
> 
> OK for trunk?

OK.  Can you document the options to trigger those dumps?
I suppose -fdump-tree-earlydebug and -fdump-tree-debug?

Thanks,
Richard.

> Thanks,
> - Tom
> 
> [debug] Add debug and earlydebug dumps
> 
> 2018-08-13  Tom de Vries  
> 
>   * cgraph.h (debuginfo_early_init, debuginfo_init, debuginfo_fini)
>   (debuginfo_start, debuginfo_stop, debuginfo_early_start)
>   (debuginfo_early_stop): Declare.
>   * cgraphunit.c (debuginfo_early_init, debuginfo_init, debuginfo_fini)
>   (debuginfo_start, debuginfo_stop, debuginfo_early_start)
>   (debuginfo_early_stop): New function.
>   (symbol_table::finalize_compilation_unit): Call debuginfo_early_start
>   and debuginfo_early_stop.
>   * dwarf2out.c (print_dw_val, print_loc_descr, print_die): Handle
>   flag_dump_noaddr and flag_dump_unnumbered.
>   (dwarf2out_finish, dwarf2out_early_finish): Dump dwarf.
>   * toplev.c (compile_file): Call debuginfo_start and debuginfo_stop.
>   (general_init): Call debuginfo_early_init.
>   (finalize): Call debuginfo_fini.
>   (do_compile): Call debuginfo_init.
> 
>   * lto.c (lto_main):  Call debuginfo_early_start and
>   debuginfo_early_stop.
> 
>   * gcc.c-torture/unsorted/dump-noaddr.x: Skip earlydebug and debug dumps.
> 
> ---
>  gcc/cgraph.h   |  8 +++
>  gcc/cgraphunit.c   | 66 
> ++
>  gcc/dwarf2out.c| 46 ---
>  gcc/lto/lto.c  |  2 +
>  gcc/testsuite/gcc.c-torture/unsorted/dump-noaddr.x |  7 +++
>  gcc/toplev.c   |  5 ++
>  6 files changed, 126 insertions(+), 8 deletions(-)
> 
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index a8b1b4cb3c3..2b00f0165fa 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -25,6 +25,14 @@ along with GCC; see the file COPYING3.  If not see
>  #include "ipa-ref.h"
>  #include "plugin-api.h"
>  
> +extern void debuginfo_early_init (void);
> +extern void debuginfo_init (void);
> +extern void debuginfo_fini (void);
> +extern void debuginfo_start (void);
> +extern void debuginfo_stop (void);
> +extern void debuginfo_early_start (void);
> +extern void debuginfo_early_stop (void);
> +
>  class ipa_opt_pass_d;
>  typedef ipa_opt_pass_d *ipa_opt_pass;
>  
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 462e247328e..6649942c4fb 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -2636,6 +2636,70 @@ symbol_table::compile (void)
>  }
>  }
>  
> +static int debuginfo_early_dump_nr;
> +static FILE *debuginfo_early_dump_file;
> +static dump_flags_t debuginfo_early_dump_flags;
> +
> +static int debuginfo_dump_nr;
> +static FILE *debuginfo_dump_file;
> +static dump_flags_t debuginfo_dump_flags;
> +
> +void
> +debuginfo_early_init (void)
> +{
> +  gcc::dump_manager *dumps = g->get_dumps ();
> +  debuginfo_early_dump_nr = dumps->dump_register (".earlydebug", 
> "earlydebug",
> +   "earlydebug", DK_tree,
> +   OPTGROUP_NONE,
> +   false);
> +  debuginfo_dump_nr = dumps->dump_register (".debug", "debug",
> +  "debug", DK_tree,
> +  OPTGROUP_NONE,
> +  false);
> +}
> +
> +void
> +debuginfo_init (void)
> +{
> +  gcc::dump_manager *dumps = g->get_dumps ();
> +  debuginfo_dump_file = dump_begin (debuginfo_dump_nr, NULL);
> +  debuginfo_dump_flags = dumps->get_dump_file_info 
> (debuginfo_dump_nr)->pflags;
> +  debuginfo_early_dump_file = dump_begin (debuginfo_early_dump_nr, NULL);
> +  debuginfo_early_dump_flags = 

Re: [PATCH] treat -Wxxx-larger-than=HWI_MAX special (PR 86631)

2018-08-20 Thread Richard Biener
On Thu, Jul 26, 2018 at 10:52 PM Martin Sebor  wrote:
>
> On 07/26/2018 08:58 AM, Martin Sebor wrote:
> > On 07/26/2018 02:38 AM, Richard Biener wrote:
> >> On Wed, Jul 25, 2018 at 5:54 PM Martin Sebor  wrote:
> >>>
> >>> On 07/25/2018 08:57 AM, Jakub Jelinek wrote:
>  On Wed, Jul 25, 2018 at 08:54:13AM -0600, Martin Sebor wrote:
> > I don't mean for the special value to be used except internally
> > for the defaults.  Otherwise, users wanting to override the default
> > will choose a value other than it.  I'm happy to document it in
> > the .opt file for internal users though.
> >
> > -1 has the documented effect of disabling the warnings altogether
> > (-1 is SIZE_MAX) so while I agree that -1 looks better it doesn't
> > work.  (It would need more significant changes.)
> 
>  The variable is signed, so -1 is not SIZE_MAX.  Even if -1 disables
>  it, you
>  could use e.g. -2 or other negative value for the other special case.
> >>>
> >>> The -Wxxx-larger-than=N distinguish three ranges of argument
> >>> values (treated as unsigned):
> >>>
> >>>1.  [0, HOST_WIDE_INT_MAX)
> >>>2.  HOST_WIDE_INT_MAX
> >>>3.  [HOST_WIDE_INT_MAX + 1, Infinity)
> >>
> >> But it doesn't make sense for those to be host dependent.
> >
> > It isn't when the values are handled by each warning.  That's
> > also the point of this patch: to remove this (unintended)
> > dependency.
> >
> >> I think numerical user input should be limited to [0, ptrdiff_max]
> >> and cases (1) and (2) should be simply merged, I see no value
> >> in distinguishing them.  -Wxxx-larger-than should be aliased
> >> to [0, ptrdiff_max], case (3) is achieved by -Wno-xxx-larger-than.
>
> To be clear: this is also close to what this patch does.
>
> The only wrinkle is that we don't know the value of PTRDIFF_MAX
> either at the time the option initial value is set in the .opt
> file or when the option is processed when it's specified either
> on the command line or as an alias in the .opt file (as all
> -Wno-xxx-larger-than options are).

But then why not make that special value accessible and handle
it as PTRDIFF_MAX when that is available (at users of the params)?

That is,

Index: gcc/calls.c
===
--- gcc/calls.c (revision 262951)
+++ gcc/calls.c (working copy)
@@ -1222,9 +1222,12 @@ alloc_max_size (void)
   if (alloc_object_size_limit)
 return alloc_object_size_limit;

-  alloc_object_size_limit
-= build_int_cst (size_type_node, warn_alloc_size_limit);
+  HOST_WIDE_INT limit = warn_alloc_size_limit;
+  if (limit == HOST_WIDE_INT_MAX)
+limit = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));

+  alloc_object_size_limit = build_int_cst (size_type_node, limit);
+
   return alloc_object_size_limit;
 }

use sth like

 if (warn_alloc_size_limit == -1)
   alloc_object_size_limit = fold_convert (size_type_node,
TYPE_MAX_VALUE (ptrdiff_type_node));
 else
   alloc_object_size_limit = size_int (warn_alloc_size_limit);

?  Also removing the need to have > int params values.

It's that HOST_WIDE_INT_MAX use that is problematic IMHO.  Why not use -1?

Richard.

>  Case (2) above is only
> used by the implementation as a placeholder for PTRDIFF_MAX.
> It's not part of the interface -- it's an internal workaround
> for lack of a better word.
>
> (There is an additional wrinkle in the -Walloca-larger-than=
> has two modes both of which are controlled by a single option:
> (a) diagnose only allocations >= PTRDIFF_MAX (default), and
> (b) diagnose allocations > limit plus also unbounded/unknown
> allocations.  I think these modes should be split up and (b)
> controlled by a separate option (say something like
> -Walloca-may-be-unbounded).
>
> >> I think you are over-engineering this and the user-interface is
> >> awful.
> >
> > Thank you.
> >
> > I agree that what you describe would be the ideal solution.
> > As I explained in the description of the patch, I did consider
> > handling PTRDIFF_MAX but the target-dependent value is not
> > available at the time the option argument is processed.  We
> > don't even know yet what the target data model is.
> >
> > This is the best I came up with.  What do you suggest instead?
> >
> > Martin
>


[PATCH] Refactor std::optional SFINAE constraints

2018-08-20 Thread Jonathan Wakely

* include/std/optional (_Optional_payload): Use variable templates
for conditions in default template arguments and exception
specifications.
(optional): Likewise. Adjust indentation.
(optional::__not_self, optional::__not_tag, optional::_Requires): New
SFINAE helpers.
(optional::optional): Use new helpers in constructor constraints.
* include/std/type_traits (__or_v, __and_v): New variable templates.
* testsuite/20_util/optional/cons/value_neg.cc: Change dg-error to
dg-prune-output. Remove unused header.

Tested x86_64-linux, committed to trunk.


commit 18f1aa19fe0560b7fa3a352cc0ae86e638f29673
Author: Jonathan Wakely 
Date:   Mon Aug 20 12:20:10 2018 +0100

Refactor std::optional SFINAE constraints

* include/std/optional (_Optional_payload): Use variable templates
for conditions in default template arguments and exception
specifications.
(optional): Likewise. Adjust indentation.
(optional::__not_self, optional::__not_tag, optional::_Requires): 
New
SFINAE helpers.
(optional::optional): Use new helpers in constructor constraints.
* include/std/type_traits (__or_v, __and_v): New variable templates.
* testsuite/20_util/optional/cons/value_neg.cc: Change dg-error to
dg-prune-output. Remove unused header.

diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index 746ee2fd87e..d0257c07e1f 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -102,11 +102,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // Payload for optionals with non-trivial destructor.
   template ::value,
+ is_trivially_destructible_v<_Tp>,
bool /*_HasTrivialCopyAssignment*/ =
- is_trivially_copy_assignable<_Tp>::value,
+ is_trivially_copy_assignable_v<_Tp>,
bool /*_HasTrivialMoveAssignment*/ =
- is_trivially_move_assignable<_Tp>::value>
+ is_trivially_move_assignable_v<_Tp>>
 struct _Optional_payload
 {
   constexpr _Optional_payload() noexcept : _M_empty() { }
@@ -165,8 +165,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   _Optional_payload&
   operator=(_Optional_payload&& __other)
-  noexcept(__and_,
- is_nothrow_move_assignable<_Tp>>())
+  noexcept(__and_v,
+  is_nothrow_move_assignable<_Tp>>)
   {
if (this->_M_engaged && __other._M_engaged)
  this->_M_get() = std::move(__other._M_get());
@@ -199,7 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 void
 _M_construct(_Args&&... __args)
-noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
+noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
 {
   ::new ((void *) std::__addressof(this->_M_payload))
 _Stored_type(std::forward<_Args>(__args)...);
@@ -377,7 +377,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 void
 _M_construct(_Args&&... __args)
-noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
+noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
 {
   ::new ((void *) std::__addressof(this->_M_payload))
 _Stored_type(std::forward<_Args>(__args)...);
@@ -468,8 +468,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   _Optional_payload&
   operator=(_Optional_payload&& __other)
-  noexcept(__and_,
- is_nothrow_move_assignable<_Tp>>())
+  noexcept(__and_v,
+  is_nothrow_move_assignable<_Tp>>)
   {
if (this->_M_engaged && __other._M_engaged)
  this->_M_get() = std::move(__other._M_get());
@@ -496,7 +496,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 void
 _M_construct(_Args&&... __args)
-noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
+noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
 {
   ::new ((void *) std::__addressof(this->_M_payload))
 _Stored_type(std::forward<_Args>(__args)...);
@@ -598,8 +598,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   _Optional_payload&
   operator=(_Optional_payload&& __other)
-  noexcept(__and_,
- is_nothrow_move_assignable<_Tp>>())
+  noexcept(__and_v,
+  is_nothrow_move_assignable<_Tp>>)
   {
if (this->_M_engaged && __other._M_engaged)
  this->_M_get() = std::move(__other._M_get());
@@ -626,7 +626,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 void
 _M_construct(_Args&&... __args)
-noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
+noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
 {
   ::new ((void *) std::__addressof(this->_M_payload))
 

Re: [PATCH] Make GO string literals properly NUL terminated

2018-08-20 Thread Bernd Edlinger
On 08/20/18 13:01, Richard Biener wrote:
> On Wed, Aug 1, 2018 at 3:05 PM Bernd Edlinger  
> wrote:
>>
>>
>>
>> On 08/01/18 11:29, Richard Biener wrote:
>>>
>>> Hmm.  I think it would be nice if TREE_STRING_LENGTH would
>>> match char[2] and TYPE_SIZE_UNIT even if that is inconvenient
>>> for your check above.  Because the '\0' doesn't belong to the
>>> string.  Then build_string internally appends a '\0' outside
>>> of TREE_STRING_LENGTH.
>>>
>>
>> Hmm. Yes, but the outside-0 byte is just one byte, not a wide
>> character.
> 
> That could be fixed though (a wide 0 is just N 0s).  Add a elsz = 1
> parameter to build_string and allocate as many extra 0s as needed.
> 
>There are STRING_CSTs which are not string literals,
>> for instance attribute tags, Pragmas, asm constrants, etc.
>> They use the '\0' outside, and have probably no TREE_TYPE.
>>
>>>
 So I would like to be able to assume that the STRING_CST objects
 are internally always generated properly by the front end.
>>>
>>> Yeah, I guess we need to define what "properly" is ;)
>>>
>> Yes.
>>
 And that the ARRAY_TYPE of the string literal either has the
 same length than the TREE_STRING_LENGTH or if it is shorter,
 this is always exactly one (wide) character size less than 
 TREE_STRING_LENGTH
>>>
>>> I think it should be always the same...
>>>
>>
>> One could not differentiate between "\0" without zero-termination
>> and "" with zero-termination, theoretically.
> 
> Is that important?  Doesn't the C standard say how to parse string literals?
> 
>> We also have char x[100] = "ab";
>> that is TREE_STRING_LENGTH=3, and TYPE_SIZE_UNIT(TREE_TYPE(x)) = 100.
>> Of course one could create it with a TREE_STRING_LENGTH = 100,
>> but imagine char x[1000] = "ab"
> 
> The question is more about TYPE_SIZE_UNIT (TREE_TYPE ("ab")) which I
> hope matches "ab" and not 'x'.  If it matches 'x' then I'd rather have it
> unconditionally be [], thus incomplete (because the literals "size" depends
> on the context/LHS it is used on).
> 

Sorry, but I must say, it is not at all like that.

If I compile x.c:
const char x[100] = "ab";

and set a breakpoint at output_constant:

Breakpoint 1, output_constant (exp=0x76ff9dc8, size=100, align=256,
 reverse=false) at ../../gcc-trunk/gcc/varasm.c:4821
4821  if (size == 0 || flag_syntax_only)
(gdb) p size
$1 = 100
(gdb) call debug(exp)
"ab"
(gdb) p *exp
$2 = {base = {code = STRING_CST, side_effects_flag = 0, constant_flag = 1,
(gdb) p exp->typed.type->type_common.size_unit
$5 = (tree) 0x76ff9d80
(gdb) call debug(exp->typed.type->type_common.size_unit)
100
(gdb) p exp->string.length
$6 = 3
(gdb) p exp->string.str[0]
$8 = 97 'a'
(gdb) p exp->string.str[1]
$9 = 98 'b'
(gdb) p exp->string.str[2]
$10 = 0 '\000'
(gdb) p exp->string.str[3]
$11 = 0 '\000'


This is an important property of string_cst objects, that is used in c_strlen:

It folds c_strlen([4]) directly to 0, because every byte beyond 
TREE_STRING_LENGTH
is guaranteed to be zero up to the type size.

I would not have spent one thought on implementing an optimization like that,
but that's how it is right now.

All I want to do, is make sure that all string constants have the same look and 
feel
in the middle-end, and restrict the variations that are allowed by the current
implementation.


Bernd.


 The idea is to use this property of string literals where needed,
 and check rigorously in varasm.c.

 Does that make sense?
>>>
>>> So if it is not the same then the excess character needs to be
>>> a (wide) NUL in your model?  ISTR your varasm.c patch didn't verify
>>> that.
>>>
>>
>> I think it does.
>>
>>
>> Bernd.


Re: Remove obsolette hunk in free_lang_data_r

2018-08-20 Thread Richard Biener
On Mon, 20 Aug 2018, Jan Hubicka wrote:

> Hi,
> this hunk should be obsolette now.
> 
> Bootstrapped/regtested x86_64-linux, OK?

OK, can you un-export is_redundant_typedef after this please?

Richard.

> Honza
> 
> Index: tree.c
> ===
> --- tree.c(revision 263586)
> +++ tree.c(working copy)
> @@ -5542,11 +5565,7 @@ find_decls_types_r (tree *tp, int *ws, v
> tem = TYPE_FIELDS (t);
> while (tem)
>   {
> -   if (TREE_CODE (tem) == FIELD_DECL
> -   || (TREE_CODE (tem) == TYPE_DECL
> -   && !DECL_IGNORED_P (tem)
> -   && debug_info_level > DINFO_LEVEL_TERSE
> -   && !is_redundant_typedef (tem)))
> +   if (TREE_CODE (tem) == FIELD_DECL)
>   fld_worklist_push (tem, fld);
> tem = TREE_CHAIN (tem);
>   }
> 
> 

-- 
Richard Biener 
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)


Re: Do not stream types in DECL_CONTEXT

2018-08-20 Thread Richard Biener
On Mon, 20 Aug 2018, Jan Hubicka wrote:

> Hi,
> this patch drops types from decl context in free lang data. This is not 
> possible
> for field decls (because they are chained by TREE_CHAIN), for variably 
> modified
> types (becuase it is used in tree_is_indexable and other places) and for
> virtual functions/tables (because it is used by devirt machinery to loop back
> the type).
> 
> lto Bootstrapped/regtested x86_64-linux, OK?

OK.

Richard.

>   * tree.c (free_lang_data_in_decl): Remove types from DECL_CONTEXT
>   when possible.
> Index: tree.c
> ===
> --- tree.c(revision 263586)
> +++ tree.c(working copy)
> @@ -5380,6 +5380,29 @@ free_lang_data_in_decl (tree decl)
>   nextp = _CHAIN (var);
>  }
>  }
> +  /* We need to keep field decls associated with their trees. Otherwise tree
> + merging may merge some fileds and keep others disjoint wich in turn will
> + not do well with TREE_CHAIN pointers linking them.
> +
> + Also do not drop containing types for virtual methods and tables because
> + these are needed by devirtualization.  */
> +  if (TREE_CODE (decl) != FIELD_DECL
> +  && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
> +  || !DECL_VIRTUAL_P (decl)))
> +{
> +  tree ctx = DECL_CONTEXT (decl);
> +  /* Variably modified types are needed for tree_is_indexable to decide
> +  whether the type needs to go to local or global section.
> +  This code is semi-broken but for now it is easiest to keep contexts
> +  as expected.  */
> +  if (ctx && TYPE_P (ctx)
> +   && !variably_modified_type_p (ctx, NULL_TREE))
> +  {
> +while (ctx && TYPE_P (ctx))
> +  ctx = TYPE_CONTEXT (ctx);
> +DECL_CONTEXT (decl) = ctx;
> +  }
> +}
>  }
>  
>  
> 
> 

-- 
Richard Biener 
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)


Remove obsolette hunk in free_lang_data_r

2018-08-20 Thread Jan Hubicka
Hi,
this hunk should be obsolette now.

Bootstrapped/regtested x86_64-linux, OK?

Honza

Index: tree.c
===
--- tree.c  (revision 263586)
+++ tree.c  (working copy)
@@ -5542,11 +5565,7 @@ find_decls_types_r (tree *tp, int *ws, v
  tem = TYPE_FIELDS (t);
  while (tem)
{
- if (TREE_CODE (tem) == FIELD_DECL
- || (TREE_CODE (tem) == TYPE_DECL
- && !DECL_IGNORED_P (tem)
- && debug_info_level > DINFO_LEVEL_TERSE
- && !is_redundant_typedef (tem)))
+ if (TREE_CODE (tem) == FIELD_DECL)
fld_worklist_push (tem, fld);
  tem = TREE_CHAIN (tem);
}


Do not stream types in DECL_CONTEXT

2018-08-20 Thread Jan Hubicka
Hi,
this patch drops types from decl context in free lang data. This is not possible
for field decls (because they are chained by TREE_CHAIN), for variably modified
types (becuase it is used in tree_is_indexable and other places) and for
virtual functions/tables (because it is used by devirt machinery to loop back
the type).

lto Bootstrapped/regtested x86_64-linux, OK?

* tree.c (free_lang_data_in_decl): Remove types from DECL_CONTEXT
when possible.
Index: tree.c
===
--- tree.c  (revision 263586)
+++ tree.c  (working copy)
@@ -5380,6 +5380,29 @@ free_lang_data_in_decl (tree decl)
nextp = _CHAIN (var);
 }
 }
+  /* We need to keep field decls associated with their trees. Otherwise tree
+ merging may merge some fileds and keep others disjoint wich in turn will
+ not do well with TREE_CHAIN pointers linking them.
+
+ Also do not drop containing types for virtual methods and tables because
+ these are needed by devirtualization.  */
+  if (TREE_CODE (decl) != FIELD_DECL
+  && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
+  || !DECL_VIRTUAL_P (decl)))
+{
+  tree ctx = DECL_CONTEXT (decl);
+  /* Variably modified types are needed for tree_is_indexable to decide
+whether the type needs to go to local or global section.
+This code is semi-broken but for now it is easiest to keep contexts
+as expected.  */
+  if (ctx && TYPE_P (ctx)
+ && !variably_modified_type_p (ctx, NULL_TREE))
+{
+  while (ctx && TYPE_P (ctx))
+ctx = TYPE_CONTEXT (ctx);
+  DECL_CONTEXT (decl) = ctx;
+}
+}
 }
 
 


Re: [PATCH] Make GO string literals properly NUL terminated

2018-08-20 Thread Richard Biener
On Wed, Aug 1, 2018 at 3:05 PM Bernd Edlinger  wrote:
>
>
>
> On 08/01/18 11:29, Richard Biener wrote:
> >
> > Hmm.  I think it would be nice if TREE_STRING_LENGTH would
> > match char[2] and TYPE_SIZE_UNIT even if that is inconvenient
> > for your check above.  Because the '\0' doesn't belong to the
> > string.  Then build_string internally appends a '\0' outside
> > of TREE_STRING_LENGTH.
> >
>
> Hmm. Yes, but the outside-0 byte is just one byte, not a wide
> character.

That could be fixed though (a wide 0 is just N 0s).  Add a elsz = 1
parameter to build_string and allocate as many extra 0s as needed.

  There are STRING_CSTs which are not string literals,
> for instance attribute tags, Pragmas, asm constrants, etc.
> They use the '\0' outside, and have probably no TREE_TYPE.
>
> >
> >> So I would like to be able to assume that the STRING_CST objects
> >> are internally always generated properly by the front end.
> >
> > Yeah, I guess we need to define what "properly" is ;)
> >
> Yes.
>
> >> And that the ARRAY_TYPE of the string literal either has the
> >> same length than the TREE_STRING_LENGTH or if it is shorter,
> >> this is always exactly one (wide) character size less than 
> >> TREE_STRING_LENGTH
> >
> > I think it should be always the same...
> >
>
> One could not differentiate between "\0" without zero-termination
> and "" with zero-termination, theoretically.

Is that important?  Doesn't the C standard say how to parse string literals?

> We also have char x[100] = "ab";
> that is TREE_STRING_LENGTH=3, and TYPE_SIZE_UNIT(TREE_TYPE(x)) = 100.
> Of course one could create it with a TREE_STRING_LENGTH = 100,
> but imagine char x[1000] = "ab"

The question is more about TYPE_SIZE_UNIT (TREE_TYPE ("ab")) which I
hope matches "ab" and not 'x'.  If it matches 'x' then I'd rather have it
unconditionally be [], thus incomplete (because the literals "size" depends
on the context/LHS it is used on).

> >> The idea is to use this property of string literals where needed,
> >> and check rigorously in varasm.c.
> >>
> >> Does that make sense?
> >
> > So if it is not the same then the excess character needs to be
> > a (wide) NUL in your model?  ISTR your varasm.c patch didn't verify
> > that.
> >
>
> I think it does.
>
>
> Bernd.


Re: [PATCH RFC] add generic expansion for MULT_HIGHPART_EXP

2018-08-20 Thread Alexander Monakov
On Mon, 20 Aug 2018, Richard Biener wrote:

> So - how difficult is it to fix BRIG to not use MULT_HIGHPART_EXPR if
> not supported?

Pekka, can you comment? I think you have fallback paths for vector types
only at the moment?

Does BRIG have mult-highpart for 64-bit integers? On 32-bit targets we
won't be able to easily expand them (but on 64-bit targets it is fine).


For scalar types I think we should prefer to implement a generic expansion
rather than have the frontend query the backend. For vector types I am not
sure.

Alexander


Re: [PATCH] Avoid negative bitpos in expand_expr_real_1 (PR 86984)

2018-08-20 Thread Richard Biener
On Sun, 19 Aug 2018, Bernd Edlinger wrote:

> Hi!
> 
> 
> This fixes a wrong code issue in expand_expr_real_1 which happens because
> a negative bitpos is actually able to reach extract_bit_field which
> does all computations with poly_uint64, thus the offset 0x1ff0.
> 
> To avoid that I propose to use Jakub's r20 patch from the 
> expand_assignment
> also in the expand_expr_real_1.
> 
> This is a rather unlikely thing to happen, as there are lots of checks that 
> are
> of course all target dependent between the get_inner_reference and the
> actual extract_bit_field call, and all other code paths may or may not have a 
> problem
> with negative bit offsets.  Most don't have a problem, but the bitpos needs 
> to be
> folded into offset before it is used, therefore it is necessary to handle the 
> negative
> bitpos very far away from the extract_bit_field call.  Doing that later is 
> IMHO not
> possible.
> 
> The fix in CONSTANT_ADDRESS_P is actually unrelated, and I only spotted it 
> because
> this macro is used in alpha_legitimize_address which is of course what one 
> looks
> at first if something like that happens.
> 
> I think even with this bogus offset it should not have caused a linker error, 
> so there
> is probably a second problem in the *movdi code pattern of the alpha.md, 
> because it
> should be split into instructions that don't cause a link error.
> 
> Once the target is fixed to split the impossible assembler instruction, the 
> test case
> will probably no longer be able to detect the pattern in the assembly.
> 
> Therefore the test case looks both at the assembler output and the expand rtl 
> dump
> to spot the bogus offset.  I only check the first 12 digits of the bogus 
> constant,
> because it is actually dependent on the target configuration:
> 
> I built first a cross-compiler without binutils, and it did used a slightly 
> different
> offset of 0x2000, (configured with: --target=alpha-linux-gnu 
> --enable-languages=c
> --disable-libgcc --disable-libssp --disable-libquadmath --disable-libgomp 
> --disable-libatomic)
> when the binutils are installed at where --prefix points, the offset is 
> 0x1ff0.
> 
> Regarding the alpha target, I could not do more than build a cross compiler 
> and run
> make check-gcc-c RUNTESTFLAGS="alpha.exp=pr86984.c".
> 
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?

Hmm, I don't remember why we are inconsistent in get_inner_reference
with respect to negative bitpos.  I think we should be consistent
here and may not be only by accident?  That is, does

diff --git a/gcc/expr.c b/gcc/expr.c
index c071be67783..9dc78587136 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7272,7 +7272,7 @@ get_inner_reference (tree exp, poly_int64_pod 
*pbitsize,
  TYPE_PRECISION (sizetype));
   tem <<= LOG2_BITS_PER_UNIT;
   tem += bit_offset;
-  if (tem.to_shwi (pbitpos))
+  if (tem.to_shwi (pbitpos) && !maybe_lt (*pbitpos, 0))
*poffset = offset = NULL_TREE;
 }
 
fix the issue?

Richard.


[PING 5][PATCH] [v4][aarch64] Avoid tag collisions for loads falkor

2018-08-20 Thread Siddhesh Poyarekar

Ping!

On 07/24/2018 12:37 PM, Siddhesh Poyarekar wrote:

Hi,

This is a rewrite of the tag collision avoidance patch that Kugan had
written as a machine reorg pass back in February.

The falkor hardware prefetching system uses a combination of the
source, destination and offset to decide which prefetcher unit to
train with the load.  This is great when loads in a loop are
sequential but sub-optimal if there are unrelated loads in a loop that
tag to the same prefetcher unit.

This pass attempts to rename the desination register of such colliding
loads using routines available in regrename.c so that their tags do
not collide.  This shows some performance gains with mcf and xalancbmk
(~5% each) and will be tweaked further.  The pass is placed near the
fag end of the pass list so that subsequent passes don't inadvertantly
end up undoing the renames.

A full gcc bootstrap and testsuite ran successfully on aarch64, i.e. it
did not introduce any new regressions.  I also did a make-check with
-mcpu=falkor to ensure that there were no regressions.  The couple of
regressions I found were target-specific and were related to scheduling
and cost differences and are not correctness issues.

Changes from v3:
- Avoid renaming argument/return registers and registers that have a
   specific architectural meaning, i.e. stack pointer, frame pointer,
   etc.  Try renaming their aliases instead.

Changes from v2:
- Ignore SVE instead of asserting that falkor does not support sve

Changes from v1:

- Fixed up issues pointed out by Kyrill
- Avoid renaming R0/V0 since they could be return values
- Fixed minor formatting issues.

2018-07-02  Siddhesh Poyarekar  
Kugan Vivekanandarajah  

* config/aarch64/falkor-tag-collision-avoidance.c: New file.
* config.gcc (extra_objs): Build it.
* config/aarch64/t-aarch64 (falkor-tag-collision-avoidance.o):
Likewise.
* config/aarch64/aarch64-passes.def
(pass_tag_collision_avoidance): New pass.
* config/aarch64/aarch64.c (qdf24xx_tunings): Add
AARCH64_EXTRA_TUNE_RENAME_LOAD_REGS to tuning_flags.
(aarch64_classify_address): Remove static qualifier.
(aarch64_address_info, aarch64_address_type): Move to...
* config/aarch64/aarch64-protos.h: ... here.
(make_pass_tag_collision_avoidance): New function.
* config/aarch64/aarch64-tuning-flags.def (rename_load_regs):
New tuning flag.

CC: james.greenha...@arm.com
CC: kyrylo.tkac...@foss.arm.com
---
  gcc/config.gcc|   2 +-
  gcc/config/aarch64/aarch64-passes.def |   1 +
  gcc/config/aarch64/aarch64-protos.h   |  49 +
  gcc/config/aarch64/aarch64-tuning-flags.def   |   2 +
  gcc/config/aarch64/aarch64.c  |  48 +-
  .../aarch64/falkor-tag-collision-avoidance.c  | 881 ++
  gcc/config/aarch64/t-aarch64  |   9 +
  7 files changed, 946 insertions(+), 46 deletions(-)
  create mode 100644 gcc/config/aarch64/falkor-tag-collision-avoidance.c

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 78e84c2b864..8f5e458e8a6 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -304,7 +304,7 @@ aarch64*-*-*)
extra_headers="arm_fp16.h arm_neon.h arm_acle.h"
c_target_objs="aarch64-c.o"
cxx_target_objs="aarch64-c.o"
-   extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o"
+   extra_objs="aarch64-builtins.o aarch-common.o cortex-a57-fma-steering.o 
falkor-tag-collision-avoidance.o"
target_gtfiles="\$(srcdir)/config/aarch64/aarch64-builtins.c"
target_has_targetm_common=yes
;;
diff --git a/gcc/config/aarch64/aarch64-passes.def 
b/gcc/config/aarch64/aarch64-passes.def
index 87747b420b0..f61a8870aa1 100644
--- a/gcc/config/aarch64/aarch64-passes.def
+++ b/gcc/config/aarch64/aarch64-passes.def
@@ -19,3 +19,4 @@
 .  */
  
  INSERT_PASS_AFTER (pass_regrename, 1, pass_fma_steering);

+INSERT_PASS_AFTER (pass_machine_reorg, 1, pass_tag_collision_avoidance);
diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index af5db9c5953..647ad7a9c37 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -288,6 +288,49 @@ struct tune_params
const struct cpu_prefetch_tune *prefetch;
  };
  
+/* Classifies an address.

+
+   ADDRESS_REG_IMM
+   A simple base register plus immediate offset.
+
+   ADDRESS_REG_WB
+   A base register indexed by immediate offset with writeback.
+
+   ADDRESS_REG_REG
+   A base register indexed by (optionally scaled) register.
+
+   ADDRESS_REG_UXTW
+   A base register indexed by (optionally scaled) zero-extended register.
+
+   ADDRESS_REG_SXTW
+   A base register indexed by (optionally scaled) sign-extended register.
+
+   ADDRESS_LO_SUM
+   A LO_SUM rtx with a base register and "LO12" symbol relocation.
+
+   ADDRESS_SYMBOLIC:
+   A 

Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Richard Biener
On Sun, 19 Aug 2018, Bernd Edlinger wrote:

> Hi,
> 
> 
> I rebased my range computation patch to current trunk,
> and updated it according to what was discussed here.
> 
> That means get_range_strlen has already a parameter
> that is used to differentiate between ranges for warnings
> and ranges for code-gen.
> 
> That is called "strict", in the 4-parameter overload
> and "fuzzy" in the internally used 7-parameter overload.
> 
> So I added an "optimistic" parameter to my
> get_inner_char_array_unless_typecast helper function.
> That's it.
> 
> Therefore at this time, there is only one warning regression
> in one test case and one xfailed warning test case fixed.
> 
> So that is par on the warning regression side.
> 
> The failed test case is gcc/testsuite/gcc.dg/pr83373.c which
> uses -fassume-zero-terminated-char-arrays, to enable the
> (unsafe) feedback from string-length information to VRP to
> suppress the warning.
> 
> The 5 test cases that were designed to check the optimized
> tree dump have to use the new -fassume-zero-terminated-char-arrays
> option, but that is what we agreed upon.
> 
> The patch is not dependent on any other patches.
> 
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?

+  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

I'm not convinced you are testing anything useful here.
TREE_OPERAND (base, 1) might be a pointer which means it's type
doesn't have any semantics so you are testing the access type
against "random".  If you'd restrict this to ADDR_EXPRs and
look at the objects declared type then you'd still miss
type-changes from a dynamic type that is different from what
is declared.

So my conclusion is if you really want to not want to return
arg for things that look like a type cast then you have to
unconditionally return NULL_TREE.

+  || TREE_CODE (base) == VIEW_CONVERT_EXPR
+  /* Or other stuff that would be handled by get_inner_reference.  */

simply use || handled_component_p (base) for the above and the rest
to be sure to handle everything that is not stripped above.

+  || TREE_CODE (base) == BIT_FIELD_REF
+  || TREE_CODE (base) == REALPART_EXPR
+  || TREE_CODE (base) == IMAGPART_EXPR)
+return NULL_TREE;

Btw, you are always returning the passed arg or NULL_TREE so
formulating this as a predicate function makes uses easier.
Not sure why it is called "inner" char array?

There do seem to be independently useful fixes in the patch that
I'd approve immediately.

Btw, I don't think we want sth like 
flag_assume_zero_terminated_char_arrays or even make it default at
-Ofast.

Richard.


Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Bernd Edlinger
On 08/20/18 12:12, Richard Biener wrote:
> On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:
>>
>> On 08/10/2018 10:56 AM, Martin Sebor wrote:
>>> On 08/08/2018 11:36 PM, Jeff Law wrote:
 On 08/02/2018 09:42 AM, Martin Sebor wrote:

> The warning bits are definitely not okay by me.  The purpose
> of the warnings (-W{format,sprintf}-{overflow,truncation} is
> to detect buffer overflows.  When a warning doesn't have access
> to string length information for dynamically created strings
> (like the strlen pass does) it uses array sizes as a proxy.
> This is useful both to detect possible buffer overflows and
> to prevent false positives for overflows that cannot happen
> in correctly written programs.
 So how much of this falling-back to array sizes as a proxy would become
 unnecessary if sprintf had access to the strlen pass as an analysis
 module?

 As you know we've been kicking that around and from my investigations
 that doesn't really look hard to do.  Encapsulate the data structures in
 a class, break up the statement handling into analysis and optimization
 and we should be good to go.  I'm hoping to start prototyping this week.

 If we think that has a reasonable chance to eliminate the array-size
 fallback, then that seems like the most promising path forward.
>>>
>>> We discussed this idea this morning so let me respond here and
>>> reiterate the answer.  Using the strlen data will help detect
>>> buffer overflow where the array size isn't available but it
>>> cannot replace the array size heuristic. Here's a simple
>>> example:
>>>
>>>struct S { char a[8]; };
>>>
>>>char d[8];
>>>void f (struct S *s, int i)
>>>{
>>>  sprintf (d, "%s-%i",  s[i].a, i);
>>>}
>>>
>>> We don't know the length of s->a but we do know that it can
>>> be up to 7 bytes long (assuming it's nul-terminated of course)
>>> so we know the sprintf call can overflow.  Conversely, if
>>> the size of the destination is increased to 20  the sprintf
>>> call cannot overflow so the diagnostic can be avoided.
>>>
>>> Removing the array size heuristic would force us to either give
>>> up on diagnosing the first case or issue false positives for
>>> the second case.  I think the second alternative would make
>>> the warning too noisy to be useful.
>>>
>>> The strlen pass will help detect buffer overflows in cases
>>> where the array size isn't known (e.g., with dynamically
>>> allocated buffers) but where the length of the string store
>>> in the array is known.  It will also help avoid false positives
>>> in cases where the string stored in an array of known size is
>>> known to be too short to cause an overflow.  For instance here:
>>>
>>>struct S { char a[8]; };
>>>
>>>char d[8];
>>>void f (struct S *s, int i)
>>>{
>>>  if (strlen (s->a) < 4 && i >= 0 && i < 100)
>>>sprintf (d, "%s-%i",  s->a, i);
>>>}
>> ACK.  Thanks for explaining things here too.  I can't speak for others,
>> but seeing examples along with the explanation is easier for me to absorb.
>>
>> For Bernd and others -- after kicking things around a bit with Martin,
>> what we're recommending is that compute_string_length we compute the
>> bounds using both GIMPLE and C semantics and return both.
> 
> But you can't do this because GIMPLE did transforms that are not valid in
> C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
> it as GIMPLE.  What you'd do is return GIMPLE semantics length
> and "foobar" semantics length which doesn't match the original source.
> 

If I understood that suggestion right, it means, we
live with some false positive or missing warnings due to those transformations.
That means, get_range_strlen with the 2-parameter overload is used
for warnings only.  And it returns most of the time a correct range info,
that is good enough for warnings.

The 4-parameter overload when called with strict=true, returns only range
info that are based on hard facts, this range info does not use those unsafe
type infos, but it can be safely used as input to the VRP machinery.


Bernd.

>>
>> Anything which influences code generation or optimization must use the
>> GIMPLE semantics.  Warnings may use the C semantics in an effort to
>> improve preciseness.
>>
>> Martin has some other stuff to flush out of his queue, then he'll be
>> focused on the changes to compute_string_length.
>> Jeff


Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Richard Biener
On Wed, Aug 15, 2018 at 6:39 AM Jeff Law  wrote:
>
> On 08/10/2018 10:56 AM, Martin Sebor wrote:
> > On 08/08/2018 11:36 PM, Jeff Law wrote:
> >> On 08/02/2018 09:42 AM, Martin Sebor wrote:
> >>
> >>> The warning bits are definitely not okay by me.  The purpose
> >>> of the warnings (-W{format,sprintf}-{overflow,truncation} is
> >>> to detect buffer overflows.  When a warning doesn't have access
> >>> to string length information for dynamically created strings
> >>> (like the strlen pass does) it uses array sizes as a proxy.
> >>> This is useful both to detect possible buffer overflows and
> >>> to prevent false positives for overflows that cannot happen
> >>> in correctly written programs.
> >> So how much of this falling-back to array sizes as a proxy would become
> >> unnecessary if sprintf had access to the strlen pass as an analysis
> >> module?
> >>
> >> As you know we've been kicking that around and from my investigations
> >> that doesn't really look hard to do.  Encapsulate the data structures in
> >> a class, break up the statement handling into analysis and optimization
> >> and we should be good to go.  I'm hoping to start prototyping this week.
> >>
> >> If we think that has a reasonable chance to eliminate the array-size
> >> fallback, then that seems like the most promising path forward.
> >
> > We discussed this idea this morning so let me respond here and
> > reiterate the answer.  Using the strlen data will help detect
> > buffer overflow where the array size isn't available but it
> > cannot replace the array size heuristic. Here's a simple
> > example:
> >
> >   struct S { char a[8]; };
> >
> >   char d[8];
> >   void f (struct S *s, int i)
> >   {
> > sprintf (d, "%s-%i",  s[i].a, i);
> >   }
> >
> > We don't know the length of s->a but we do know that it can
> > be up to 7 bytes long (assuming it's nul-terminated of course)
> > so we know the sprintf call can overflow.  Conversely, if
> > the size of the destination is increased to 20  the sprintf
> > call cannot overflow so the diagnostic can be avoided.
> >
> > Removing the array size heuristic would force us to either give
> > up on diagnosing the first case or issue false positives for
> > the second case.  I think the second alternative would make
> > the warning too noisy to be useful.
> >
> > The strlen pass will help detect buffer overflows in cases
> > where the array size isn't known (e.g., with dynamically
> > allocated buffers) but where the length of the string store
> > in the array is known.  It will also help avoid false positives
> > in cases where the string stored in an array of known size is
> > known to be too short to cause an overflow.  For instance here:
> >
> >   struct S { char a[8]; };
> >
> >   char d[8];
> >   void f (struct S *s, int i)
> >   {
> > if (strlen (s->a) < 4 && i >= 0 && i < 100)
> >   sprintf (d, "%s-%i",  s->a, i);
> >   }
> ACK.  Thanks for explaining things here too.  I can't speak for others,
> but seeing examples along with the explanation is easier for me to absorb.
>
> For Bernd and others -- after kicking things around a bit with Martin,
> what we're recommending is that compute_string_length we compute the
> bounds using both GIMPLE and C semantics and return both.

But you can't do this because GIMPLE did transforms that are not valid in
C, thus you can't interpret the GIMPLE IL as "C", you can only interpret
it as GIMPLE.  What you'd do is return GIMPLE semantics length
and "foobar" semantics length which doesn't match the original source.

>
> Anything which influences code generation or optimization must use the
> GIMPLE semantics.  Warnings may use the C semantics in an effort to
> improve preciseness.
>
> Martin has some other stuff to flush out of his queue, then he'll be
> focused on the changes to compute_string_length.
> Jeff


Re: [PATCH] Make strlen range computations more conservative

2018-08-20 Thread Richard Biener
On Fri, Aug 3, 2018 at 9:19 AM Jeff Law  wrote:
>
> On 07/25/2018 01:23 AM, Richard Biener wrote:
> > On Tue, 24 Jul 2018, Bernd Edlinger wrote:
> >
> >> On 07/24/18 23:46, Jeff Law wrote:
> >>> On 07/24/2018 01:59 AM, Bernd Edlinger wrote:
>  Hi!
> 
>  This patch makes strlen range computations more conservative.
> 
>  Firstly if there is a visible type cast from type A to B before passing
>  then value to strlen, don't expect the type layout of B to restrict the
>  possible return value range of strlen.
> >>> Why do you think this is the right thing to do?  ie, is there language
> >>> in the standards that makes you think the code as it stands today is
> >>> incorrect from a conformance standpoint?  Is there a significant body of
> >>> code that is affected in an adverse way by the current code?  If so,
> >>> what code?
> >>>
> >>>
> >>
> >> I think if you have an object, of an effective type A say char[100], then
> >> you can cast the address of A to B, say typedef char (*B)[2] for instance
> >> and then to const char *, say for use in strlen.  I may be wrong, but I 
> >> think
> >> that we should at least try not to pick up char[2] from B, but instead
> >> use A for strlen ranges, or leave this range open.  Currently the range
> >> info for strlen is [0..1] in this case, even if we see the type cast
> >> in the generic tree.
> >
> > You raise a valid point - namely that the middle-end allows
> > any object (including storage with a declared type) to change
> > its dynamic type (even of a piece of it).  So unless you can
> > prove that the dynamic type of the thing you are looking at
> > matches your idea of that type you may not derive any string
> > lengths (or ranges) from it.
> >
> > BUT - for the string_constant and c_strlen functions we are,
> > in all cases we return something interesting, able to look
> > at an initializer which then determines that type.  Hopefully.
> > I think the strlen() folding code when it sets SSA ranges
> > now looks at types ...?
> I'm leaning towards a similar conclusion, namely that we can only rely
> on type information for the pointer that actually gets passed to strlen,
> which 99.9% of the time is (char *), potentially with const qualifiers.

It's 100% (char *) because the C standard says arguments are converted
to the argument type.

> It's tempting to look back through the cast to find a cast from a char
> array but I'm more and more concerned that it's not safe unless we can
> walk back to an initializer.
>
> What this might argue is that we need to distinguish between a known
> range and a likely range.  I really dislike doing that again.  We may
> have to see more real world cases where the likely range allows us to
> improve the precision of the sprintf warnings (since that's really the
> goal of improved string length ranges).
>
>
>
> >
> > Consider
> >
> > struct X { int i; char c[4]; int j;};
> > struct Y { char c[16]; };
> >
> > void foo (struct X *p, struct Y *q)
> > {
> >   memcpy (p, q, sizeof (struct Y));
> >   if (strlen ((char *)(struct Y *)p + 4) < 7)
> > abort ();
> > }
> >
> > here the GIMPLE IL looks like
> >
> >   const char * _1;
> >
> >[local count: 1073741825]:
> >   _5 = MEM[(char * {ref-all})q_4(D)];
> >   MEM[(char * {ref-all})p_6(D)] = _5;
> >   _1 = p_6(D) + 4;
> >   _2 = __builtin_strlen (_1);
> >
> > and I guess Martin would argue that since p is of type struct X
> > + 4 gets you to c[4] and thus strlen of that cannot be larger
> > than 3.
> But _1 is of type const char * and that's what's passed to strlen.  The
> type of P and Q are irrelevant ISTM.
>
> Jeff
>
>


  1   2   >