[PATCH] c++, cgraphbuild: Handle DECL_VALUE_EXPRs in record_reference [PR108474]

Jakub Jelinek jakub@redhat.com
Mon Jan 23 15:17:43 GMT 2023


On Mon, Jan 23, 2023 at 12:37:59PM +0000, Richard Biener wrote:
> Guess it should work.  Do we (accidentially?) do anything special
> to static var initializers in nested functions?

I don't think we touch those, we walk the bodies of functions, I don't
think we traverse static var DECL_INITIALs.

>  Can you think of
> any other C/C++ construct that would have DECL_VALUE_EXPR in them?

A lot of them, coroutines, FE NRV, anon union vars, lambdas,
in modules, OpenMP privatized members, structured bindings,
__FUNCTION__ etc., later VLAs, tree-nested, OpenMP lowering.

But anon union vars and structured bindings are the only ones
known for which this is actually needed in static initializers.
I'm afraid no idea about modules case, for OpenMP one needs executable
code, tried the __FUNCTION__ case and while there is DECL_VALUE_EXPR
used, the initializer is already replaced by STRING_CST in the FE somewhere,
VLAs aren't allowed.

BTW, the patch successfully passed bootstrap/regtested on x86_64-linux and
i686-linux.

> > 2023-01-23  Jakub Jelinek  <jakub@redhat.com>
> > 
> > 	PR c++/108474
> > 	* cgraphbuild.cc: Include gimplify.h.
> > 	(record_reference): Replace VAR_DECLs with DECL_HAS_VALUE_EXPR_P with
> > 	their corresponding DECL_VALUE_EXPR expressions after unsharing.
> > 
> > 	* cp-gimplify.cc (cp_fold_r): Revert 2023-01-19 changes.
> > 
> > 	* g++.dg/cpp1z/decomp57.C: New test.
> > 	* g++.dg/cpp1z/decomp58.C: New test.
> > 
> > --- gcc/cgraphbuild.cc.jj	2023-01-02 09:32:34.889104620 +0100
> > +++ gcc/cgraphbuild.cc	2023-01-23 12:10:35.042067571 +0100
> > @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
> >  #include "gimple-walk.h"
> >  #include "ipa-utils.h"
> >  #include "except.h"
> > +#include "gimplify.h"
> >  
> >  /* Context of record_reference.  */
> >  struct record_reference_ctx
> > @@ -79,6 +80,17 @@ record_reference (tree *tp, int *walk_su
> >  
> >        if (VAR_P (decl))
> >  	{
> > +	  /* Replace vars with their DECL_VALUE_EXPR if any.
> > +	     This is normally done during gimplification, but
> > +	     static var initializers are never gimplified.  */
> > +	  if (DECL_HAS_VALUE_EXPR_P (decl))
> > +	    {
> > +	      tree *p;
> > +	      for (p = tp; *p != decl; p = &TREE_OPERAND (*p, 0))
> > +		;
> > +	      *p = unshare_expr (DECL_VALUE_EXPR (decl));
> > +	      return record_reference (tp, walk_subtrees, data);
> > +	    }
> >  	  varpool_node *vnode = varpool_node::get_create (decl);
> >  	  ctx->varpool_node->create_reference (vnode, IPA_REF_ADDR);
> >  	}
> > --- gcc/cp/cp-gimplify.cc.jj	2023-01-23 11:47:49.889875804 +0100
> > +++ gcc/cp/cp-gimplify.cc	2023-01-23 11:49:01.227841759 +0100
> > @@ -1010,16 +1010,6 @@ cp_fold_r (tree *stmt_p, int *walk_subtr
> >  	}
> >        break;
> >  
> > -    case VAR_DECL:
> > -      /* In initializers replace anon union artificial VAR_DECLs
> > -	 with their DECL_VALUE_EXPRs, as nothing will do it later.  */
> > -      if (DECL_ANON_UNION_VAR_P (stmt) && !data->genericize)
> > -	{
> > -	  *stmt_p = stmt = unshare_expr (DECL_VALUE_EXPR (stmt));
> > -	  break;
> > -	}
> > -      break;
> > -
> >      default:
> >        break;
> >      }
> > --- gcc/testsuite/g++.dg/cpp1z/decomp57.C.jj	2023-01-23 11:48:36.367202107 +0100
> > +++ gcc/testsuite/g++.dg/cpp1z/decomp57.C	2023-01-23 11:48:36.367202107 +0100
> > @@ -0,0 +1,27 @@
> > +// PR c++/108474
> > +// { dg-do link { target c++17 } }
> > +
> > +struct T { int i, j; };
> > +T h;
> > +auto [i, j] = h;
> > +int &r = i;
> > +int s = i;
> > +int *t = &i;
> > +
> > +void
> > +foo (int **p, int *q)
> > +{
> > +  static int &u = i;
> > +  static int v = i;
> > +  static int *w = &i;
> > +  int &x = i;
> > +  int y = i;
> > +  int *z = &i;
> > +  *p = &i;
> > +  *q = i;
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +}
> > --- gcc/testsuite/g++.dg/cpp1z/decomp58.C.jj	2023-01-23 11:48:36.367202107 +0100
> > +++ gcc/testsuite/g++.dg/cpp1z/decomp58.C	2023-01-23 11:48:36.367202107 +0100
> > @@ -0,0 +1,39 @@
> > +// PR c++/108474
> > +// { dg-do link { target c++17 } }
> > +
> > +namespace std {
> > +  template <typename T> struct tuple_size;
> > +  template <int, typename> struct tuple_element;
> > +}
> > +
> > +struct A {
> > +  int i;
> > +  template <int I> int& get() { return i; }
> > +};
> > +
> > +template <> struct std::tuple_size <A> { static const int value = 2; };
> > +template <int I> struct std::tuple_element <I, A> { using type = int; };
> > +
> > +struct A a;
> > +auto [i, j] = a;
> > +int &r = i;
> > +int s = i;
> > +int *t = &i;
> > +
> > +void
> > +foo (int **p, int *q)
> > +{
> > +  static int &u = i;
> > +  static int v = i;
> > +  static int *w = &i;
> > +  int &x = i;
> > +  int y = i;
> > +  int *z = &i;
> > +  *p = &i;
> > +  *q = i;
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +}

	Jakub



More information about the Gcc-patches mailing list