[committed] wwwdocs: contribute: Move validator.w3.org to https

2022-04-09 Thread Gerald Pfeifer
Pushed.

Gerald
---
 htdocs/contribute.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/htdocs/contribute.html b/htdocs/contribute.html
index c0223738..c985b87d 100644
--- a/htdocs/contribute.html
+++ b/htdocs/contribute.html
@@ -145,7 +145,7 @@ eliminate them all.
 Web Site Changes
 
 Changes to the web site must
-http://validator.w3.org/";>validate as HTML 5.  To
+https://validator.w3.org";>validate as HTML 5.  To
 validate your changes, use the "upload file" mode of the
 validator.
 
-- 
2.35.1


[committed] wwwdocs: readings: www.cmass.com is gone, remove

2022-04-09 Thread Gerald Pfeifer
I pushed this for now.

Gaius, if you want to make changes to that section of readings.html,
absolutely be free doing so (and I'll be happy help, too).

Gerald

---
 htdocs/readings.html | 1 -
 1 file changed, 1 deletion(-)

diff --git a/htdocs/readings.html b/htdocs/readings.html
index 12755d7e..8689eab8 100644
--- a/htdocs/readings.html
+++ b/htdocs/readings.html
@@ -569,7 +569,6 @@ names.
 Modula 3 information
 
 
-  http://www.cmass.com";>http://www.cmass.com
   http://www.modula3.org";>http://www.modula3.org
 
 
-- 
2.35.1


Re: [PATCH] LoongArch: Fix bug for tmpdir-g++.dg-struct-layout-1/t033.

2022-04-09 Thread Xi Ruoyao via Gcc-patches
I can confirm this patch fixes t033 failure.  LGTM, except...

> gcc/ChangeLog:
> 
> * config/loongarch/loongarch.cc: Fix bug for
>   tmpdir-g++.dg-struct-layout-1/t033.
  ^^ These two whitespaces should not exist

(I was taught this just several days ago :)

-- 
Xi Ruoyao 
School of Aerospace Science and Technology, Xidian University


Re: [PATCH] libgccjit: Add support for setting the alignment [PR104293]

2022-04-09 Thread Antoni Boucher via Gcc-patches
Here's the updated patch.

On Fri, 2022-04-08 at 15:01 -0400, David Malcolm wrote:
> On Sun, 2022-01-30 at 20:38 -0500, Antoni Boucher via Gcc-patches
> wrote:
> > Hi.
> > This patch adds support for setting the alignment of variables in
> > libgccjit.
> 
> Thanks.  Sorry about the delay in reviewing it.
> 
> > 
> > I was wondering if I should change it so that it takes/returns
> > bytes
> > instead of bits.
> > What do you think?
> 
> I'm not sure, but given that C refers to bytes for this:
>   https://en.cppreference.com/w/c/language/object#Alignment
>   https://en.cppreference.com/w/c/language/_Alignof
> ...I think bytes is the better choice, to maximize similarity with C.

Ok, I updated it to use bytes.

> 
> Does anything support/need a fraction-of-a-byte alignment?  If so,
> then
> bits would be the way to go.
> 
> 
> > diff --git a/gcc/jit/docs/topics/compatibility.rst
> > b/gcc/jit/docs/topics/compatibility.rst
> > index 16cebe31a10..1957399dceb 100644
> > --- a/gcc/jit/docs/topics/compatibility.rst
> > +++ b/gcc/jit/docs/topics/compatibility.rst
> > @@ -302,3 +302,13 @@ thread-local storage model of a variable:
> >  section of a variable:
> >  
> >    * :func:`gcc_jit_lvalue_set_link_section`
> > +
> > +.. _LIBGCCJIT_ABI_24:
> > +
> > +``LIBGCCJIT_ABI_24``
> > +---
> > +``LIBGCCJIT_ABI_24`` covers the addition of functions to get and
> > set the
> > +alignement of a variable:
> > +
> > +  * :func:`gcc_jit_lvalue_set_alignment`
> > +  * :func:`gcc_jit_lvalue_get_alignment`
> > diff --git a/gcc/jit/docs/topics/expressions.rst
> > b/gcc/jit/docs/topics/expressions.rst
> > index 791a20398ca..0f5f5376d8c 100644
> > --- a/gcc/jit/docs/topics/expressions.rst
> > +++ b/gcc/jit/docs/topics/expressions.rst
> > @@ -738,6 +738,45 @@ where the rvalue is computed by reading from
> > the storage area.
> >  
> >    #ifdef LIBGCCJIT_HAVE_gcc_jit_lvalue_set_link_section
> >  
> > +.. function:: void
> > +  gcc_jit_lvalue_set_alignment (gcc_jit_lvalue
> > *lvalue,
> > +    int alignment)
> > +
> > +   Set the alignment of a variable.
> > +   The parameter ``alignment`` is in bits. Analogous to:
> > +
> > +   .. code-block:: c
> > +
> > + int variable __attribute__((aligned (16)));
> > +
> > +   in C, but in bits instead of bytes.
> 
> If we're doing it in bytes, this will need updating, of course.
> 
> Maybe rename the int param from "alignment" to "bytes" to make this
> clearer.
> 
> Probably should be unsigned as well.
> 
> > +
> > +   This entrypoint was added in :ref:`LIBGCCJIT_ABI_24`; you can
> > test for
> > +   its presence using
> > +
> > +   .. code-block:: c
> > +
> > +  #ifdef LIBGCCJIT_HAVE_ALIGNMENT
> > +
> > +.. function:: int
> > +  gcc_jit_lvalue_get_alignment (gcc_jit_lvalue
> > *lvalue)
> > +
> > +   Return the alignment of a variable set by
> > ``gcc_jit_lvalue_set_alignment``, in bits.
> > +   Return 0 if the alignment was not set. Analogous to:
> > +
> > +   .. code-block:: c
> > +
> > + _Alignof (variable)
> > +
> > +   in C, but in bits instead of bytes.
> 
> Likewise this will need updating.
> 
> > +
> > +   This entrypoint was added in :ref:`LIBGCCJIT_ABI_24`; you can
> > test for
> > +   its presence using
> > +
> > +   .. code-block:: c
> > +
> > +  #ifdef LIBGCCJIT_HAVE_ALIGNMENT
> > +
> >  Global variables
> >  
> > 
> 
> [...snip...]
> 
> > diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
> > index 4c352e8c93d..e03f15ec9c8 100644
> > --- a/gcc/jit/libgccjit.cc
> > +++ b/gcc/jit/libgccjit.cc
> > @@ -2649,6 +2649,31 @@ gcc_jit_lvalue_set_link_section
> > (gcc_jit_lvalue *lvalue,
> >    lvalue->set_link_section (section_name);
> >  }
> >  
> > +/* Public entrypoint.  See description in libgccjit.h.
> > +
> > +   After error-checking, the real work is done by the
> > +   gcc::jit::recording::lvalue::get_link_section method in jit-
> > recording.cc.  */
> 
> Comment refers to wrong function.
> 
> > +
> > +int
> > +gcc_jit_lvalue_get_alignment (gcc_jit_lvalue *lvalue)
> > +{
> > +  RETURN_VAL_IF_FAIL (lvalue, 0, NULL, NULL, "NULL lvalue");
> > +  return lvalue->get_alignment ();
> > +}
> 
> Should this return unsigned?
> 
> > +
> > +/* Public entrypoint.  See description in libgccjit.h.
> > +
> > +   After error-checking, the real work is done by the
> > +   gcc::jit::recording::lvalue::set_alignment method in jit-
> > recording.cc.  */
> > +
> > +void
> > +gcc_jit_lvalue_set_alignment (gcc_jit_lvalue *lvalue,
> > + int alignment)
> > +{
> > +  RETURN_IF_FAIL (lvalue, NULL, NULL, "NULL lvalue");
> 
> Should the alignment be unsigned?  What if the user passes in
> negative?
> 
> Does it have to be a power of two?  If so, ideally we should reject
> non-power-of-two here.
> 
> > +  lvalue->set_alignment (alignment);
> > +}
> > +
> 
> [...snip...]
> 
> > diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
> > index f373fd39ac7..df51e4f

Re: [PATCH] libgccjit: Add support for bitcasts [PR104071]

2022-04-09 Thread Antoni Boucher via Gcc-patches
Here's the updated patch.

On Fri, 2022-04-08 at 15:22 -0400, David Malcolm wrote:
> On Fri, 2022-01-21 at 18:41 -0500, Antoni Boucher wrote:
> > Hi.
> > Here's the updated patch.
> > 
> 
> Thanks.  Review below:
> 
> [...snip...]
> 
> > diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
> > index 4c352e8c93d..6bf1e1ceee0 100644
> > --- a/gcc/jit/libgccjit.cc
> > +++ b/gcc/jit/libgccjit.cc
> > @@ -2405,6 +2405,34 @@ gcc_jit_context_new_cast (gcc_jit_context
> > *ctxt,
> >    return static_cast  (ctxt->new_cast (loc,
> > rvalue, type));
> >  }
> >  
> > +/* Public entrypoint.  See description in libgccjit.h.
> > +
> > +   After error-checking, the real work is done by the
> > +   gcc::jit::recording::context::new_bitcast method in jit-
> > recording.c.  */
> > +
> > +gcc_jit_rvalue *
> > +gcc_jit_context_new_bitcast (gcc_jit_context *ctxt,
> > +    gcc_jit_location *loc,
> > +    gcc_jit_rvalue *rvalue,
> > +    gcc_jit_type *type)
> > +{
> > +  RETURN_NULL_IF_FAIL (ctxt, NULL, loc, "NULL context");
> > +  JIT_LOG_FUNC (ctxt->get_logger ());
> > +  /* LOC can be NULL.  */
> > +  RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
> > +  RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
> > +  // TODO: check the sizes.
> > +  /*RETURN_NULL_IF_FAIL_PRINTF3 (
> > +    is_valid_cast (rvalue->get_type (), type),
> > +    ctxt, loc,
> > +    "cannot cast %s from type: %s to type: %s",
> > +    rvalue->get_debug_string (),
> > +    rvalue->get_type ()->get_debug_string (),
> > +    type->get_debug_string ());*/
> 
> I think we agreed that we can't check the sizes at this point, so
> this
> commented-out check would be better replaced with a comment
> explaining
> that we have to defer the check to playback time, when we have the
> trees.
> 
> > +
> > +  return static_cast  (ctxt->new_bitcast (loc,
> > rvalue, type));
> > +}
> > +
> >  /* Public entrypoint.  See description in libgccjit.h.
> >  
> >     After error-checking, the real work is done by the
> 
> [...snip...]
> 
> > diff --git a/gcc/testsuite/jit.dg/test-bitcast.c
> > b/gcc/testsuite/jit.dg/test-bitcast.c
> > new file mode 100644
> > index 000..a092fa117e6
> > --- /dev/null
> > +++ b/gcc/testsuite/jit.dg/test-bitcast.c
> > @@ -0,0 +1,60 @@
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "libgccjit.h"
> > +
> > +#include "harness.h"
> > +
> > +void
> > +create_code (gcc_jit_context *ctxt, void *user_data)
> > +{
> > +  /* Let's try to inject the equivalent of:
> > +int
> > +my_bitcast (double x)
> > +{
> > +   return bitcast(x, int);
> > +}
> > +   */
> > +  gcc_jit_type *int_type =
> > +    gcc_jit_context_get_int_type (ctxt, 4, 1);
> > +  gcc_jit_type *float_type =
> > +    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
> 
> This uses GCC_JIT_TYPE_FLOAT for the param...
> 
> > +
> > +  gcc_jit_param *x =
> > +    gcc_jit_context_new_param (
> > +  ctxt,
> > +  NULL,
> > +  float_type, "x");
> > +  gcc_jit_param *params[1] = {x};
> > +  gcc_jit_function *func =
> > +    gcc_jit_context_new_function (ctxt,
> > + NULL,
> > + GCC_JIT_FUNCTION_EXPORTED,
> > + int_type,
> > + "my_bitcast",
> > + 1, params, 0);
> 
> [..snip...]
> 
> > +
> > +void
> > +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
> > +{
> > +  typedef int (*my_bitcast_fn_type) (double);
> 
> ...but this uses "double".  Presumably these should agree, and have
> the
> same sizeof as the integer type.
> 
> > +  CHECK_NON_NULL (result);
> > +  my_bitcast_fn_type my_bitcast =
> > +    (my_bitcast_fn_type)gcc_jit_result_get_code (result,
> > "my_bitcast");
> > +  CHECK_NON_NULL (my_bitcast);
> > +  int val = my_bitcast (-5.1298714);
> > +  note ("my_bitcast returned: %d", val);
> > +  CHECK_VALUE (val, 35569201);
> 
> Out of curiosity, is there any particular significance for these
> values?  FWIW I rather like:
>   http://evanw.github.io/float-toy/
> for directly manipulating the bits of floating point numbers.

The given float values, when bitcast to an int, gives the given int
value.

> 
> 
> [...snip...]
> 
> > diff --git a/gcc/toplev.cc b/gcc/toplev.cc
> > index 534da1462e8..bc4921974eb 100644
> > --- a/gcc/toplev.cc
> > +++ b/gcc/toplev.cc
> > @@ -2368,6 +2368,7 @@ toplev::finalize (void)
> >    gcse_c_finalize ();
> >    ipa_cp_c_finalize ();
> >    ira_costs_c_finalize ();
> > +  tree_cc_finalize ();
> >  
> >    /* save_decoded_options uses opts_obstack, so these must
> >   be cleaned up together.  */
> > diff --git a/gcc/tree.cc b/gcc/tree.cc
> > index ae159ee20ce..fe9d9083026 100644
> > --- a/gcc/tree.cc
> > +++ b/gcc/tree.cc
> > @@ -6963,6 +6963,15 @@ build_reference_type (tree to_type)
> >    (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64)
> >  static GTY(()) tree nonstandar

Fix nondeterministic and side_effect propagation in ipa-modref

2022-04-09 Thread Jan Hubicka via Gcc-patches
Hi,
this patch adds logic to propagate nondeterministic and side_effects
bits in modref when summary is updated after inlining.

Bootstrapped/regtested x86_64-linux, comitted.

gcc/ChangeLog:

2022-04-09  Jan Hubicka  

* ipa-modref.cc (ipa_merge_modref_summary_after_inlining): Propagate
nondeterministic and side_effects flags.

gcc/testsuite/ChangeLog:

2022-04-09  Jan Hubicka  

* gcc.dg/ipa/pr105160.c: New test.

diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index acfd7d80ff8..556816ab429 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -5281,6 +5281,29 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge 
*edge)
   if (!ignore_stores)
to_info_lto->stores->collapse ();
 }
+  /* Merge side effects and non-determinism.
+ PURE/CONST flags makes functions deterministic and if there is
+ no LOOPING_CONST_OR_PURE they also have no side effects.  */
+  if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE))
+  || (flags & ECF_LOOPING_CONST_OR_PURE))
+{
+  if (to_info)
+   {
+ if (!callee_info || callee_info->side_effects)
+   to_info->side_effects = true;
+ if ((!callee_info || callee_info->nondeterministic)
+ && !ignore_nondeterminism_p (edge->caller->decl, flags))
+   to_info->nondeterministic = true;
+   }
+  if (to_info_lto)
+   {
+ if (!callee_info_lto || callee_info_lto->side_effects)
+   to_info_lto->side_effects = true;
+ if ((!callee_info_lto || callee_info_lto->nondeterministic)
+ && !ignore_nondeterminism_p (edge->caller->decl, flags))
+   to_info_lto->nondeterministic = true;
+   }
+ }
   if (callee_info || callee_info_lto)
 {
   auto_vec  parm_map;
diff --git a/gcc/testsuite/gcc.dg/ipa/pr105160.c 
b/gcc/testsuite/gcc.dg/ipa/pr105160.c
new file mode 100644
index 000..ea80545b102
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr105160.c
@@ -0,0 +1,77 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-ipa-modref" } */
+#define sysreg_read(regname)   \
+({ \
+   unsigned long __sr_val; \
+   asm volatile("");   \
+   \
+   __sr_val;   \
+})
+
+#define sysreg_write(regname, __sw_val)\
+do {   \
+   asm volatile("");   \
+} while (0)
+
+#define isb()  \
+do {   \
+   asm volatile(   \
+   "isb"   \
+   :   \
+   :   \
+   : "memory");\
+} while (0)
+
+static unsigned long sctlr_read(void)
+{
+   return sysreg_read(sctlr_el1);
+}
+
+static void sctlr_write(unsigned long val)
+{
+   sysreg_write(sctlr_el1, val);
+}
+
+static void sctlr_rmw(void)
+{
+   unsigned long val;
+
+   val = sctlr_read();
+   val |= 1UL << 7;
+   sctlr_write(val);
+}
+
+void sctlr_read_multiple(void)
+{
+   sctlr_read();
+   sctlr_read();
+   sctlr_read();
+   sctlr_read();
+}
+
+void sctlr_write_multiple(void)
+{
+   sctlr_write(0);
+   sctlr_write(0);
+   sctlr_write(0);
+   sctlr_write(0);
+   sctlr_write(0);
+}
+
+void sctlr_rmw_multiple(void)
+{
+   sctlr_rmw();
+   sctlr_rmw();
+   sctlr_rmw();
+   sctlr_rmw();
+}
+
+void function(void)
+{
+   sctlr_read_multiple();
+   sctlr_write_multiple();
+   sctlr_rmw_multiple();
+
+   isb();
+}
+/* { dg-final { scan-ipa-dump-not "Function found to be const" "modref"  } } */


Fix ICE with -fno-semantic-interposition added via option attribut

2022-04-09 Thread Jan Hubicka via Gcc-patches
Hi,
This patch solves problem with FE first finalizing function and then adding
-fno-semantic-interposition flag (by parsing optimization attribute).

Bootstrapped/regtested x86_64-linux, comitted.

Honza

gcc/ChangeLog:

2022-04-09  Jan Hubicka  

PR ipa/103376
* cgraphunit.cc (cgraph_node::analyze): update semantic_interposition
flag.

gcc/testsuite/ChangeLog:

2022-04-09  Jan Hubicka  

PR ipa/103376
* gcc.c-torture/compile/pr103376.c: New test.

diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
index 01f4e28204e..bc3dc754481 100644
--- a/gcc/cgraphunit.cc
+++ b/gcc/cgraphunit.cc
@@ -621,6 +621,7 @@ cgraph_node::analyze (void)
   tree decl = this->decl;
   location_t saved_loc = input_location;
   input_location = DECL_SOURCE_LOCATION (decl);
+  semantic_interposition = opt_for_fn (decl, flag_semantic_interposition);
 
   if (thunk)
 {
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr103376.c 
b/gcc/testsuite/gcc.c-torture/compile/pr103376.c
new file mode 100644
index 000..8c14c3ded38
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr103376.c
@@ -0,0 +1,9 @@
+/* { dg-additional-options "-Ofast" } */
+__attribute__ ((optimize ("no-associative-math"))) double
+fn3 (double h, double l)
+{
+  return h + l;
+}
+
+double fn3 (double, double) __attribute__ ((optimize 
("O2,no-associative-math")));
+


Re: [PATCH] c-family: Initialize ridpointers for __int128 etc. [PR105186]

2022-04-09 Thread Marek Polacek via Gcc-patches
On Fri, Apr 08, 2022 at 09:29:52AM +0200, Jakub Jelinek wrote:
> Hi!
> 
> The following testcase ICEs with C++ and is incorrectly rejected with C.
> The reason is that both FEs use ridpointers identifiers for CPP_KEYWORD
> and value or u.value for CPP_NAME e.g. when parsing attributes or OpenMP
> directives etc., like:
>  /* Save away the identifier that indicates which attribute
> this is.  */
>  identifier = (token->type == CPP_KEYWORD)
>/* For keywords, use the canonical spelling, not the
>   parsed identifier.  */
>? ridpointers[(int) token->keyword]
>: id_token->u.value;
> 
>  identifier = canonicalize_attr_name (identifier);
> I've tried to change those to use ridpointers only if non-NULL and otherwise
> use the value/u.value even for CPP_KEYWORDS, but that was a large 10 hunks
> patch.
> 
> The following patch instead just initializes ridpointers for the __intNN
> keywords.  It can't be done earlier before we record_builtin_type as there
> are 2 different spellings and if we initialize those ridpointers early, the
> second record_builtin_type fails miserably.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2022-04-08  Jakub Jelinek  
> 
>   PR c++/105186
>   * c-common.cc (c_common_nodes_and_builtins): After registering __int%d
>   and __int%d__ builtin types, initialize corresponding ridpointers
>   entry.
> 
>   * c-c++-common/pr105186.c: New test.
> 
> --- gcc/c-family/c-common.cc.jj   2022-04-07 17:18:14.378883472 +0200
> +++ gcc/c-family/c-common.cc  2022-04-07 17:21:07.950463695 +0200
> @@ -4278,6 +4278,8 @@ c_common_nodes_and_builtins (void)
>sprintf (name, "__int%d__", int_n_data[i].bitsize);
>record_builtin_type ((enum rid)(RID_FIRST_INT_N + i), name,
>  int_n_trees[i].signed_type);
> +  ridpointers[RID_FIRST_INT_N + i]
> + = DECL_NAME (TYPE_NAME (int_n_trees[i].signed_type));

So this also covers the range for the unsigned variants of these types.

I think the patch is OK, thanks.

>sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
>record_builtin_type (RID_MAX, name, int_n_trees[i].unsigned_type);
> --- gcc/testsuite/c-c++-common/pr105186.c.jj  2022-04-07 17:25:32.084781386 
> +0200
> +++ gcc/testsuite/c-c++-common/pr105186.c 2022-04-07 17:25:13.736037189 
> +0200
> @@ -0,0 +1,5 @@
> +/* PR c++/105186 */
> +/* { dg-do compile } */
> +
> +__attribute__((__int128)) int i; /* { dg-warning "'__int128' attribute 
> directive ignored" } */
> +__attribute__((__int128__)) int j;   /* { dg-warning "'__int128' attribute 
> directive ignored" } */

Marek



[committed] analyzer: fix folding of regions involving unknown ptrs [PR103892]

2022-04-09 Thread David Malcolm via Gcc-patches
PR analyzer/103892 reports a false positive from -Wanalyzer-double-free.

The root cause is the analyzer failing to properly handle "unknown"
symbolic regions, and thus confusing two different expressions.

Specifically, the analyzer eventually hits the complexity limit for
symbolic values, and starts using an "unknown" svalue for a pointer.
The analyzer uses
  symbolic_region(unknown_svalue([of ptr type]))
i.e.
  (*UNKNOWN_PTR)
in a few places to mean "we have an lvalue, but we're not going to
attempt to track what it is anymore".

"Unknown" should probably be renamed to "unknowable"; in theory, any
operation on such an unknown svalue should be also an unknown svalue.

The issue is that in various places where we create child regions, we
were failing to check for the parent region being (*UNKNOWN_PTR), and so
were erroneously creating regions based on (*UNKNOWN_PTR), such as
*(UNKNOWN_PTR + OFFSET).  The state-machine handling was erroneously
allowing e.g. INITIAL_VALUE (*(UNKNOWN_PTR + OFFSET)) to have state,
and thus we could record that such a value had had "free" called on it,
and thus eventually false report a double-free when a different
expression incorrectly "simplified" to the same expression.

This patch fixes things by checking when creating the various kinds of
child region for (*UNKNOWN_PTR) as the parent region, and simply
returning another (*UNKNOWN_PTR) for such child regions (using the
appropriate type).

Doing so fixes the false positive, and also fixes a state explosion on
this testcase, as the states at the program points more rapidly reach
a fixed point where everything is unknown.  I checked for other cases
that no longer needed -Wno-analyzer-too-complex; the only other one
seems to be gcc.dg/analyzer/pr96841.c, but that seems to already have
become redundant at some point before this patch.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-8071-g3d41408c5d2810.

gcc/analyzer/ChangeLog:
PR analyzer/103892
* region-model-manager.cc
(region_model_manager::get_unknown_symbolic_region): New,
extracted from...
(region_model_manager::get_field_region): ...here.
(region_model_manager::get_element_region): Use it here.
(region_model_manager::get_offset_region): Likewise.
(region_model_manager::get_sized_region): Likewise.
(region_model_manager::get_cast_region): Likewise.
(region_model_manager::get_bit_range): Likewise.
* region-model.h
(region_model_manager::get_unknown_symbolic_region): New decl.
* region.cc (symbolic_region::symbolic_region): Handle sval_ptr
having NULL type.
(symbolic_region::dump_to_pp): Handle having NULL type.

gcc/testsuite/ChangeLog:
PR analyzer/103892
* gcc.dg/analyzer/pr103892.c: New test.
* gcc.dg/analyzer/pr96841.c: Drop redundant
-Wno-analyzer-too-complex.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/region-model-manager.cc | 37 ++--
 gcc/analyzer/region-model.h  |  2 +
 gcc/analyzer/region.cc   | 11 +++-
 gcc/testsuite/gcc.dg/analyzer/pr103892.c | 75 
 gcc/testsuite/gcc.dg/analyzer/pr96841.c  |  2 +-
 5 files changed, 117 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr103892.c

diff --git a/gcc/analyzer/region-model-manager.cc 
b/gcc/analyzer/region-model-manager.cc
index 56d60768749..4ec275ecd43 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -1362,6 +1362,19 @@ region_model_manager::get_region_for_global (tree expr)
   return reg;
 }
 
+/* Return the region for an unknown access of type REGION_TYPE,
+   creating it if necessary.
+   This is a symbolic_region, where the pointer is an unknown_svalue
+   of type ®ION_TYPE.  */
+
+const region *
+region_model_manager::get_unknown_symbolic_region (tree region_type)
+{
+  tree ptr_type = region_type ? build_pointer_type (region_type) : NULL_TREE;
+  const svalue *unknown_ptr = get_or_create_unknown_svalue (ptr_type);
+  return get_symbolic_region (unknown_ptr);
+}
+
 /* Return the region that describes accessing field FIELD of PARENT,
creating it if necessary.  */
 
@@ -1372,12 +1385,7 @@ region_model_manager::get_field_region (const region 
*parent, tree field)
 
   /* (*UNKNOWN_PTR).field is (*UNKNOWN_PTR_OF_&FIELD_TYPE).  */
   if (parent->symbolic_for_unknown_ptr_p ())
-{
-  tree ptr_to_field_type = build_pointer_type (TREE_TYPE (field));
-  const svalue *unknown_ptr_to_field
-   = get_or_create_unknown_svalue (ptr_to_field_type);
-  return get_symbolic_region (unknown_ptr_to_field);
-}
+return get_unknown_symbolic_region (TREE_TYPE (field));
 
   field_region::key_t key (parent, field);
   if (field_region *reg = m_field_regions.get (key))
@@ -1397,6 +1405,10 @@ region_model_manager::get_element_region (const region 
*parent,