public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix up debuginfo for VLAs in nested functions
@ 2009-04-08 15:21 Jakub Jelinek
  2009-04-24 22:01 ` Ian Lance Taylor
  0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2009-04-08 15:21 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

Hi!

Given e.g.:
module module_test
   real :: a(2,2)
end module module_test

program test_pass
   use module_test, ONLY: a
   interface
      subroutine sub_test(a_sub,c_sub,c_size)
        real,target  :: a_sub(:,:)
        integer      :: c_size
        real         :: c_sub(c_size,c_size/2)
      end subroutine sub_test
   end interface
   a(1,1)=1.
   a(2,1)=2.
   a(1,2)=3.
   a(2,2)=4.
   call sub_test(a,a(:,2),2)
end program test_pass


subroutine sub_test(a_sub,c_sub,c_size)
   real,target  :: a_sub(:,:)
   integer      :: c_size
   real         :: c_sub(c_size,c_size/2)

   real,pointer :: b_sub(:,:)

   b_sub => a_sub
   print*,'a_sub',a_sub(:,:)
   print*,'b_sub',b_sub(:,:)
   print*,'c_sub',c_sub(:,:)
   call contained_sub

contains

   subroutine contained_sub
     print*,'a_sub',a_sub(:,:)
     print*,'b_sub',b_sub(:,:)
     print*,'c_sub',c_sub(:,:)
   end subroutine contained_sub

end subroutine sub_test

compiled with -g -O0, the debugger can't print some VLA vars, both
nonlocal or even local, just referenced from some nested function.
With vanilla gcc, in sub_test it prints:
(gdb) p a_sub
$1 = (( 1, 2) ( 3, 4) )
(gdb) p b_sub
$2 = (( 1, 2) ( 3, 4) )
(gdb) p c_sub
$3 = (PTR TO -> ( real(kind=4) (*,*))) 0x601578
and in contained_sub:
(gdb) p a_sub
Cannot access memory at address 0x8000000042
(gdb) p b_sub
$4 = (( 1, 2) ( 3, 4) )
(gdb) p c_sub
$5 = (PTR TO -> ( real(kind=4) (*,*))) 0x601578

With this patch it prints:
(gdb) p a_sub
$1 = (( 1, 2) ( 3, 4) )
(gdb) p b_sub
$2 = (( 1, 2) ( 3, 4) )
(gdb) p c_sub
$3 = (( 3, 4) )
in sub_test and:
(gdb) p a_sub
Cannot access memory at address 0x8000000042
(gdb) p b_sub
$4 = (( 1, 2) ( 3, 4) )
(gdb) p c_sub
$5 = (( 3, 4) )
in contained_sub (note a_sub symbol hasn't been mentioned in the gimplified
code in contained_sub, only a_sub.0, so we don't generate a debug decl for
it (should be a FE business I'd say and isn't solved by this patch)).

One of the changes needed is to honor DECL_BY_REFERENCE even for VAR_DECLs
(those which tree-nested.c creates as replacement for
PARM_DECLs/RESULT_DECLs).  Unfortunately, ATM DECL_BY_REFERENCE shares the
same bit as TREE_PRIVATE.  I believe the C++ FE (the only setter of
TREE_PRIVATE) only sets this on FUNCTION_DECLs/FIELD_DECLs and
static data members (i.e. TREE_STATIC VAR_DECLs), so this patch extends
DECL_BY_REFERENCE uses from PARM_DECL/RESULT_DECL also to !TREE_STATIC
VAR_DECLs.  Without this parameters passed by invisible reference
referenced from nested routines will show up as pointers in the debug info,
which is undesirable.

The other change is something comments in get_{,non}local_debug_decl
already suggest:
/* ??? We should be remapping types as well, surely.  */

This patch does that remapping, but delays it to the end of the unnesting
pass and remaps just those variables that are actually passed through
the chains.

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

2009-04-08  Jakub Jelinek  <jakub@redhat.com>

	* tree.h (DECL_BY_REFERENCE): Note that it is also valid for
	!TREE_STATIC VAR_DECLs.
	* dwarf2out.c (loc_by_reference, gen_decl_die): Handle
	DECL_BY_REFERENCE on !TREE_STATIC VAR_DECLs.
	(gen_variable_die): Likewise.  Don't look at TREE_PRIVATE if
	DECL_BY_REFERENCE is valid.
	* dbxout.c (DECL_ACCESSIBILITY_CHAR): Don't look at TREE_PRIVATE
	for PARM_DECLs, RESULT_DECLs or !TREE_STATIC VAR_DECLs.
	* tree-nested.c (get_nonlocal_debug_decl, get_local_debug_decl):
	Copy DECL_BY_REFERENCE.
	(struct nesting_copy_body_data): New type.
	(nesting_copy_decl): New function.
	(finalize_nesting_tree_1): Remap types of debug_var_chain variables,
	if they have variable length.

--- gcc/dwarf2out.c.jj	2009-04-07 08:32:56.000000000 +0200
+++ gcc/dwarf2out.c	2009-04-08 11:10:16.000000000 +0200
@@ -11709,7 +11709,9 @@ loc_by_reference (dw_loc_descr_ref loc, 
   if (loc == NULL)
     return NULL;
 
-  if ((TREE_CODE (decl) != PARM_DECL && TREE_CODE (decl) != RESULT_DECL)
+  if ((TREE_CODE (decl) != PARM_DECL
+       && TREE_CODE (decl) != RESULT_DECL
+       && (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)))
       || !DECL_BY_REFERENCE (decl))
     return loc;
 
@@ -14047,12 +14049,19 @@ gen_variable_die (tree decl, tree origin
   else
     {
       tree type = TREE_TYPE (decl);
+      bool private_flag_valid = true;
 
       add_name_and_src_coords_attributes (var_die, decl);
       if ((TREE_CODE (decl) == PARM_DECL
-	   || TREE_CODE (decl) == RESULT_DECL)
+	   || TREE_CODE (decl) == RESULT_DECL
+	   || (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl)))
 	  && DECL_BY_REFERENCE (decl))
-	add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
+	{
+	  add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
+	  /* DECL_BY_REFERENCE uses the same bit as TREE_PRIVATE,
+	     for PARM_DECL, RESULT_DECL or non-static VAR_DECL.  */
+	  private_flag_valid = false;
+	}
       else
 	add_type_attribute (var_die, type, TREE_READONLY (decl),
 			    TREE_THIS_VOLATILE (decl), context_die);
@@ -14065,7 +14074,7 @@ gen_variable_die (tree decl, tree origin
 
       if (TREE_PROTECTED (decl))
 	add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_protected);
-      else if (TREE_PRIVATE (decl))
+      else if (private_flag_valid && TREE_PRIVATE (decl))
 	add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private);
     }
 
@@ -15298,7 +15307,9 @@ gen_decl_die (tree decl, tree origin, dw
 
       /* Output any DIEs that are needed to specify the type of this data
 	 object.  */
-      if (TREE_CODE (decl_or_origin) == RESULT_DECL
+      if ((TREE_CODE (decl_or_origin) == RESULT_DECL
+	   || (TREE_CODE (decl_or_origin) == VAR_DECL
+	       && !TREE_STATIC (decl_or_origin)))
           && DECL_BY_REFERENCE (decl_or_origin))
 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
       else
--- gcc/tree.h.jj	2009-04-06 11:48:32.000000000 +0200
+++ gcc/tree.h	2009-04-07 17:16:28.000000000 +0200
@@ -478,7 +478,7 @@ struct tree_common GTY(())
            CALL_EXPR
 
        DECL_BY_REFERENCE in
-           PARM_DECL, RESULT_DECL
+           PARM_DECL, RESULT_DECL, VAR_DECL (only !TREE_STATIC)
 
        OMP_SECTION_LAST in
            OMP_SECTION
@@ -1291,8 +1291,9 @@ extern void omp_clause_range_check_faile
 #define CALL_EXPR_RETURN_SLOT_OPT(NODE) \
   (CALL_EXPR_CHECK (NODE)->base.private_flag)
 
-/* In a RESULT_DECL or PARM_DECL, means that it is passed by invisible
-   reference (and the TREE_TYPE is a pointer to the true type).  */
+/* In a RESULT_DECL, PARM_DECL or VAR_DECL without TREE_STATIC, means that it is
+   passed by invisible reference (and the TREE_TYPE is a pointer to the true
+   type).  */
 #define DECL_BY_REFERENCE(NODE) (DECL_COMMON_CHECK (NODE)->base.private_flag)
 
 /* In a CALL_EXPR, means that the call is the jump from a thunk to the
--- gcc/tree-nested.c.jj	2009-04-06 11:47:30.000000000 +0200
+++ gcc/tree-nested.c	2009-04-08 09:50:55.000000000 +0200
@@ -827,6 +827,11 @@ get_nonlocal_debug_decl (struct nesting_
   TREE_READONLY (new_decl) = TREE_READONLY (decl);
   TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
   DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
+  if ((TREE_CODE (decl) == PARM_DECL
+       || TREE_CODE (decl) == RESULT_DECL
+       || TREE_CODE (decl) == VAR_DECL)
+      && DECL_BY_REFERENCE (decl))
+    DECL_BY_REFERENCE (new_decl) = 1;
 
   SET_DECL_VALUE_EXPR (new_decl, x);
   DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
@@ -1240,6 +1245,11 @@ get_local_debug_decl (struct nesting_inf
   TREE_READONLY (new_decl) = TREE_READONLY (decl);
   TREE_ADDRESSABLE (new_decl) = TREE_ADDRESSABLE (decl);
   DECL_SEEN_IN_BIND_EXPR_P (new_decl) = 1;
+  if ((TREE_CODE (decl) == PARM_DECL
+       || TREE_CODE (decl) == RESULT_DECL
+       || TREE_CODE (decl) == VAR_DECL)
+      && DECL_BY_REFERENCE (decl))
+    DECL_BY_REFERENCE (new_decl) = 1;
 
   SET_DECL_VALUE_EXPR (new_decl, x);
   DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
@@ -1944,6 +1954,34 @@ convert_all_function_calls (struct nesti
   while (root);
 }
 
+struct nesting_copy_body_data
+{
+  copy_body_data cb;
+  struct nesting_info *root;
+};
+
+/* A helper subroutine for debug_var_chain type remapping.  */
+
+static tree
+nesting_copy_decl (tree decl, copy_body_data *id)
+{
+  struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id;
+  void **slot = pointer_map_contains (nid->root->var_map, decl);
+
+  if (slot)
+    return (tree) *slot;
+
+  if (TREE_CODE (decl) == TYPE_DECL && DECL_ORIGINAL_TYPE (decl))
+    {
+      tree new_decl = copy_decl_no_change (decl, id);
+      DECL_ORIGINAL_TYPE (new_decl)
+	= remap_type (DECL_ORIGINAL_TYPE (decl), id);
+      return new_decl;
+    }
+
+  return copy_decl_no_change (decl, id);
+}
+
 /* Do "everything else" to clean up or complete state collected by the
    various walking passes -- lay out the types and decls, generate code
    to initialize the frame decl, store critical expressions in the
@@ -2076,10 +2114,66 @@ finalize_nesting_tree_1 (struct nesting_
     declare_vars (root->new_local_var_chain,
 		  gimple_seq_first_stmt (gimple_body (root->context)),
 		  false);
+
   if (root->debug_var_chain)
-    declare_vars (root->debug_var_chain,
-		  gimple_seq_first_stmt (gimple_body (root->context)),
-		  true);
+    {
+      tree debug_var;
+
+      for (debug_var = root->debug_var_chain; debug_var;
+	   debug_var = TREE_CHAIN (debug_var))
+	if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
+	  break;
+
+      /* If there are any debug decls with variable length types,
+	 remap those types using other debug_var_chain variables.  */
+      if (debug_var)
+	{
+	  struct nesting_copy_body_data id;
+
+	  memset (&id, 0, sizeof (id));
+	  id.cb.copy_decl = nesting_copy_decl;
+	  id.cb.decl_map = pointer_map_create ();
+	  id.root = root;
+
+	  for (; debug_var; debug_var = TREE_CHAIN (debug_var))
+	    if (variably_modified_type_p (TREE_TYPE (debug_var), NULL))
+	      {
+		tree type = TREE_TYPE (debug_var);
+		tree newt, t = type;
+		struct nesting_info *i;
+
+		for (i = root; i; i = i->outer)
+		  if (variably_modified_type_p (type, i->context))
+		    break;
+
+		if (i == NULL)
+		  continue;
+
+		id.cb.src_fn = i->context;
+		id.cb.dst_fn = i->context;
+		id.cb.src_cfun = DECL_STRUCT_FUNCTION (root->context);
+
+		TREE_TYPE (debug_var) = newt = remap_type (type, &id.cb);
+		while (POINTER_TYPE_P (newt) && !TYPE_NAME (newt))
+		  {
+		    newt = TREE_TYPE (newt);
+		    t = TREE_TYPE (t);
+		  }
+		if (TYPE_NAME (newt)
+		    && TREE_CODE (TYPE_NAME (newt)) == TYPE_DECL
+		    && DECL_ORIGINAL_TYPE (TYPE_NAME (newt))
+		    && newt != t
+		    && TYPE_NAME (newt) == TYPE_NAME (t))
+		  TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
+	      }
+
+	  pointer_map_destroy (id.cb.decl_map);
+	}
+
+      declare_vars (root->debug_var_chain,
+		    gimple_seq_first_stmt (gimple_body (root->context)),
+		    true);
+    }
 
   /* Dump the translated tree function.  */
   dump_function (TDI_nested, root->context);
--- gcc/dbxout.c.jj	2009-04-06 11:47:29.000000000 +0200
+++ gcc/dbxout.c	2009-04-07 17:16:27.000000000 +0200
@@ -1397,7 +1397,9 @@ dbxout_type_index (tree type)
 /* Used in several places: evaluates to '0' for a private decl,
    '1' for a protected decl, '2' for a public decl.  */
 #define DECL_ACCESSIBILITY_CHAR(DECL) \
-(TREE_PRIVATE (DECL) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
+((TREE_CODE (DECL) != PARM_DECL && TREE_CODE (DECL) != RESULT_DECL \
+  && (TREE_CODE (DECL) != VAR_DECL || TREE_STATIC (DECL)) \
+  && TREE_PRIVATE (DECL)) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
 
 /* Subroutine of `dbxout_type'.  Output the type fields of TYPE.
    This must be a separate function because anonymous unions require

	Jakub

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix up debuginfo for VLAs in nested functions
  2009-04-08 15:21 [PATCH] Fix up debuginfo for VLAs in nested functions Jakub Jelinek
@ 2009-04-24 22:01 ` Ian Lance Taylor
  2009-04-25 22:11   ` Jakub Jelinek
  0 siblings, 1 reply; 4+ messages in thread
From: Ian Lance Taylor @ 2009-04-24 22:01 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches

Jakub Jelinek <jakub@redhat.com> writes:

> One of the changes needed is to honor DECL_BY_REFERENCE even for VAR_DECLs
> (those which tree-nested.c creates as replacement for
> PARM_DECLs/RESULT_DECLs).  Unfortunately, ATM DECL_BY_REFERENCE shares the
> same bit as TREE_PRIVATE.  I believe the C++ FE (the only setter of
> TREE_PRIVATE) only sets this on FUNCTION_DECLs/FIELD_DECLs and
> static data members (i.e. TREE_STATIC VAR_DECLs), so this patch extends
> DECL_BY_REFERENCE uses from PARM_DECL/RESULT_DECL also to !TREE_STATIC
> VAR_DECLs.  Without this parameters passed by invisible reference
> referenced from nested routines will show up as pointers in the debug info,
> which is undesirable.

This overloading will eventually cause a bug if we don't check for it
when ENABLE_TREE_CHECKING is defined.  Can you, in a separate patch,
modify TREE_PRIVATE and DECL_BY_REFERENCE to verify that they are being
invoked appropriately?  Also modify TREE_PROTECTED to check the same set
of conditions as TREE_PRIVATE.  Then fix any fallout.


> 2009-04-08  Jakub Jelinek  <jakub@redhat.com>
>
> 	* tree.h (DECL_BY_REFERENCE): Note that it is also valid for
> 	!TREE_STATIC VAR_DECLs.
> 	* dwarf2out.c (loc_by_reference, gen_decl_die): Handle
> 	DECL_BY_REFERENCE on !TREE_STATIC VAR_DECLs.
> 	(gen_variable_die): Likewise.  Don't look at TREE_PRIVATE if
> 	DECL_BY_REFERENCE is valid.
> 	* dbxout.c (DECL_ACCESSIBILITY_CHAR): Don't look at TREE_PRIVATE
> 	for PARM_DECLs, RESULT_DECLs or !TREE_STATIC VAR_DECLs.
> 	* tree-nested.c (get_nonlocal_debug_decl, get_local_debug_decl):
> 	Copy DECL_BY_REFERENCE.
> 	(struct nesting_copy_body_data): New type.
> 	(nesting_copy_decl): New function.
> 	(finalize_nesting_tree_1): Remap types of debug_var_chain variables,
> 	if they have variable length.

This is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix up debuginfo for VLAs in nested functions
  2009-04-24 22:01 ` Ian Lance Taylor
@ 2009-04-25 22:11   ` Jakub Jelinek
  2009-04-25 22:32     ` Ian Lance Taylor
  0 siblings, 1 reply; 4+ messages in thread
From: Jakub Jelinek @ 2009-04-25 22:11 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Jason Merrill, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1645 bytes --]

On Fri, Apr 24, 2009 at 02:51:38PM -0700, Ian Lance Taylor wrote:
> Jakub Jelinek <jakub@redhat.com> writes:
> 
> > One of the changes needed is to honor DECL_BY_REFERENCE even for VAR_DECLs
> > (those which tree-nested.c creates as replacement for
> > PARM_DECLs/RESULT_DECLs).  Unfortunately, ATM DECL_BY_REFERENCE shares the
> > same bit as TREE_PRIVATE.  I believe the C++ FE (the only setter of
> > TREE_PRIVATE) only sets this on FUNCTION_DECLs/FIELD_DECLs and
> > static data members (i.e. TREE_STATIC VAR_DECLs), so this patch extends
> > DECL_BY_REFERENCE uses from PARM_DECL/RESULT_DECL also to !TREE_STATIC
> > VAR_DECLs.  Without this parameters passed by invisible reference
> > referenced from nested routines will show up as pointers in the debug info,
> > which is undesirable.
> 
> This overloading will eventually cause a bug if we don't check for it
> when ENABLE_TREE_CHECKING is defined.  Can you, in a separate patch,
> modify TREE_PRIVATE and DECL_BY_REFERENCE to verify that they are being
> invoked appropriately?  Also modify TREE_PROTECTED to check the same set
> of conditions as TREE_PRIVATE.  Then fix any fallout.

Attached is a patch to do that, bootstrapped/regtested on x86_64-linux.

But, I see that tree_decl_common hase 49 unused bits (23 in struct tree_base
and 26 in struct tree_decl_common), so perhaps it is not worth all the
overloading trouble and we could instead just allocate a different bit
for DECL_BY_REFERENCE (this is done in the second patch, also
bootstrapped/regtested on x86_64-linux).

Both patches are incremental, on top of the 3 patches you've ACKed.

Ok for trunk?  Which one?

	Jakub

[-- Attachment #2: Y300 --]
[-- Type: text/plain, Size: 8941 bytes --]

2009-04-25  Jakub Jelinek  <jakub@redhat.com>

	* tree.h (DECL_BY_REFERENCE_CHECK, NON_DECL_BY_REFERENCE_CHECK):
	Define.
	(DECL_BY_REFERENCE, TREE_PRIVATE, TREE_PROTECTED): Use it.
	(OMP_CLAUSE_PRIVATE_OUTER_REF): Don't use TREE_PRIVATE macro.
	* print-tree.c (print_node): For PARM_DECL, RESULT_DECL or
	non-static VAR_DECL, print DECL_BY_REFERENCE instead of
	TREE_PRIVATE/TREE_PROTECTED.
	* dbxout.c (DECL_ACCESSIBILITY_CHAR): Don't look at TREE_PRIVATE
	nor TREE_PROTECTED for PARM_DECL, RESULT_DECL or non-static
	VAR_DECL.
	(dbxout_type_fields): Check TREE_CODE before TREE_PRIVATE
	or TREE_PROTECTED.
	* dwarf2out.c (gen_variable_die): Don't look at TREE_PRIVATE
	nor TREE_PROTECTED for PARM_DECL, RESULT_DECL or non-static
	VAR_DECL.
java/
	* class.c (add_field): Set FIELD_STATIC before setting
	FIELD_PROTECTED or FIELD_PRIVATE.

--- gcc/print-tree.c.jj	2008-11-04 21:07:40.000000000 +0100
+++ gcc/print-tree.c	2009-04-25 01:04:43.000000000 +0200
@@ -311,10 +311,19 @@ print_node (FILE *file, const char *pref
     fputs (TYPE_P (node) ? " align-ok" : " nothrow", file);
   if (TREE_PUBLIC (node))
     fputs (" public", file);
-  if (TREE_PRIVATE (node))
-    fputs (" private", file);
-  if (TREE_PROTECTED (node))
-    fputs (" protected", file);
+  if (code == PARM_DECL || code == RESULT_DECL
+      || (code == VAR_DECL && !TREE_STATIC (node)))
+    {
+      if (DECL_BY_REFERENCE (node))
+	fputs (" by_reference", file);
+    }
+  else
+    {
+      if (TREE_PRIVATE (node))
+	fputs (" private", file);
+      if (TREE_PROTECTED (node))
+	fputs (" protected", file);
+    }
   if (TREE_STATIC (node))
     fputs (" static", file);
   if (TREE_DEPRECATED (node))
--- gcc/tree.h.jj	2009-04-25 00:12:59.000000000 +0200
+++ gcc/tree.h	2009-04-25 01:16:44.000000000 +0200
@@ -830,6 +830,26 @@ enum tree_node_structure_enum {
 				 __FILE__, __LINE__, __FUNCTION__);	\
     &__t->exp.operands[__i]; }))
 
+#define DECL_BY_REFERENCE_CHECK(T) __extension__			\
+({  __typeof (T) const __t = (T);					\
+    if (TREE_CODE (__t) != PARM_DECL					\
+	&& TREE_CODE (__t) != RESULT_DECL				\
+	&& (TREE_CODE (__t) != VAR_DECL					\
+	    || TREE_STATIC (__t)))					\
+      tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__,	\
+			     PARM_DECL, RESULT_DECL, VAR_DECL, 0);	\
+    __t; })
+
+#define NON_DECL_BY_REFERENCE_CHECK(T) __extension__			\
+({  __typeof (T) const __t = (T);					\
+    if (TREE_CODE (__t) == PARM_DECL					\
+	|| TREE_CODE (__t) == RESULT_DECL				\
+	|| (TREE_CODE (__t) == VAR_DECL					\
+	    && !TREE_STATIC (__t)))					\
+      tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__,		\
+			 PARM_DECL, RESULT_DECL, VAR_DECL, 0);		\
+    __t; })
+
 /* Nodes are chained together for many purposes.
    Types are chained together to record them for being output to the debugger
    (see the function `chain_type').
@@ -911,6 +931,8 @@ extern void omp_clause_range_check_faile
 #define TREE_OPERAND_CHECK(T, I)		((T)->exp.operands[I])
 #define TREE_OPERAND_CHECK_CODE(T, CODE, I)	((T)->exp.operands[I])
 #define TREE_RTL_OPERAND_CHECK(T, CODE, I)  (*(rtx *) &((T)->exp.operands[I]))
+#define DECL_BY_REFERENCE_CHECK(T)		(T)
+#define NON_DECL_BY_REFERENCE_CHECK(T)		(T)
 #define OMP_CLAUSE_ELT_CHECK(T, i)	        ((T)->omp_clause.ops[i])
 #define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2)	(T)
 #define OMP_CLAUSE_SUBCODE_CHECK(T, CODE)	(T)
@@ -1297,7 +1319,7 @@ extern void omp_clause_range_check_faile
 /* In a RESULT_DECL, PARM_DECL or VAR_DECL without TREE_STATIC, means that it is
    passed by invisible reference (and the TREE_TYPE is a pointer to the true
    type).  */
-#define DECL_BY_REFERENCE(NODE) (DECL_COMMON_CHECK (NODE)->base.private_flag)
+#define DECL_BY_REFERENCE(NODE) (DECL_BY_REFERENCE_CHECK (NODE)->base.private_flag)
 
 /* In a CALL_EXPR, means that the call is the jump from a thunk to the
    thunked-to function.  */
@@ -1315,9 +1337,11 @@ extern void omp_clause_range_check_faile
 #define TYPE_ALIGN_OK(NODE) (TYPE_CHECK (NODE)->base.nothrow_flag)
 
 /* Used in classes in C++.  */
-#define TREE_PRIVATE(NODE) ((NODE)->base.private_flag)
+#define TREE_PRIVATE(NODE) \
+  (NON_DECL_BY_REFERENCE_CHECK (NODE)->base.private_flag)
 /* Used in classes in C++. */
-#define TREE_PROTECTED(NODE) ((NODE)->base.protected_flag)
+#define TREE_PROTECTED(NODE) \
+  (NON_DECL_BY_REFERENCE_CHECK (NODE)->base.protected_flag)
 
 /* Nonzero in a _DECL if the use of the name is defined as a
    deprecated feature by __attribute__((deprecated)).  */
@@ -1744,7 +1768,7 @@ extern void protected_set_expr_location 
 /* True on a PRIVATE clause if ctor needs access to outer region's
    variable.  */
 #define OMP_CLAUSE_PRIVATE_OUTER_REF(NODE) \
-  TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PRIVATE))
+  (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PRIVATE)->base.private_flag)
 
 /* True on a LASTPRIVATE clause if a FIRSTPRIVATE clause for the same
    decl is present in the chain.  */
--- gcc/dbxout.c.jj	2009-04-25 00:12:59.000000000 +0200
+++ gcc/dbxout.c	2009-04-25 01:09:19.000000000 +0200
@@ -1398,9 +1398,9 @@ dbxout_type_index (tree type)
 /* Used in several places: evaluates to '0' for a private decl,
    '1' for a protected decl, '2' for a public decl.  */
 #define DECL_ACCESSIBILITY_CHAR(DECL) \
-((TREE_CODE (DECL) != PARM_DECL && TREE_CODE (DECL) != RESULT_DECL \
-  && (TREE_CODE (DECL) != VAR_DECL || TREE_STATIC (DECL)) \
-  && TREE_PRIVATE (DECL)) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
+((TREE_CODE (DECL) == PARM_DECL || TREE_CODE (DECL) == RESULT_DECL \
+  || (TREE_CODE (DECL) == VAR_DECL && !TREE_STATIC (DECL))) \
+  ? '2' : TREE_PRIVATE (DECL) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
 
 /* Subroutine of `dbxout_type'.  Output the type fields of TYPE.
    This must be a separate function because anonymous unions require
@@ -1444,8 +1444,9 @@ dbxout_type_fields (tree type)
 	  stabstr_C (':');
 
 	  if (use_gnu_debug_info_extensions
-	      && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)
-		  || TREE_CODE (tem) != FIELD_DECL))
+	      && (TREE_CODE (tem) != FIELD_DECL
+		  || TREE_PRIVATE (tem)
+		  || TREE_PROTECTED (tem)))
 	    {
 	      stabstr_C ('/');
 	      stabstr_C (DECL_ACCESSIBILITY_CHAR (tem));
--- gcc/dwarf2out.c.jj	2009-04-25 00:13:06.000000000 +0200
+++ gcc/dwarf2out.c	2009-04-25 08:14:56.000000000 +0200
@@ -14051,16 +14051,15 @@ gen_variable_die (tree decl, tree origin
       bool private_flag_valid = true;
 
       add_name_and_src_coords_attributes (var_die, decl);
-      if ((TREE_CODE (decl) == PARM_DECL
-	   || TREE_CODE (decl) == RESULT_DECL
-	   || (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl)))
-	  && DECL_BY_REFERENCE (decl))
-	{
-	  add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
-	  /* DECL_BY_REFERENCE uses the same bit as TREE_PRIVATE,
-	     for PARM_DECL, RESULT_DECL or non-static VAR_DECL.  */
-	  private_flag_valid = false;
-	}
+      if (TREE_CODE (decl) == PARM_DECL
+	  || TREE_CODE (decl) == RESULT_DECL
+	  || (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl)))
+	/* DECL_BY_REFERENCE uses the same bit as TREE_PRIVATE,
+	   for PARM_DECL, RESULT_DECL or non-static VAR_DECL.  */
+	private_flag_valid = false;
+
+      if (!private_flag_valid && DECL_BY_REFERENCE (decl))
+	add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
       else
 	add_type_attribute (var_die, type, TREE_READONLY (decl),
 			    TREE_THIS_VOLATILE (decl), context_die);
@@ -14071,10 +14070,14 @@ gen_variable_die (tree decl, tree origin
       if (DECL_ARTIFICIAL (decl))
 	add_AT_flag (var_die, DW_AT_artificial, 1);
 
-      if (TREE_PROTECTED (decl))
-	add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_protected);
-      else if (private_flag_valid && TREE_PRIVATE (decl))
-	add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private);
+      if (private_flag_valid)
+	{
+	  if (TREE_PROTECTED (decl))
+	    add_AT_unsigned (var_die, DW_AT_accessibility,
+			     DW_ACCESS_protected);
+	  else if (TREE_PRIVATE (decl))
+	    add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private);
+	}
     }
 
   if (declaration)
--- gcc/java/class.c.jj	2008-10-20 16:59:07.000000000 +0200
+++ gcc/java/class.c	2009-04-25 09:03:47.000000000 +0200
@@ -850,6 +850,8 @@ add_field (tree klass, tree name, tree f
   DECL_CONTEXT (field) = klass;
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);
 
+  if (is_static)
+    FIELD_STATIC (field) = 1;
   if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
   if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
   if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
@@ -864,7 +866,6 @@ add_field (tree klass, tree name, tree f
   if (flags & ACC_SYNTHETIC) FIELD_SYNTHETIC (field) = 1;
   if (is_static)
     {
-      FIELD_STATIC (field) = 1;
       /* Always make field externally visible.  This is required so
 	 that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;

[-- Attachment #3: Y300b --]
[-- Type: text/plain, Size: 6063 bytes --]

2009-04-25  Jakub Jelinek  <jakub@redhat.com>

	* tree.h: Remove DECL_BY_REFERENCE from private_flag comment.
	(struct tree_base): Adjust spacing for 8 bit boundaries.
	(struct tree_decl_common): Add decl_by_reference_flag bit.
	(DECL_BY_REFERENCE): Adjust.
	* print-tree.c (print_node): For VAR_DECL, PARM_DECL or RESULT_DECL,
	print DECL_BY_REFERENCE bit.
	* dbxout.c (DECL_ACCESSIBILITY_CHAR): Revert last change.
	* dwarf2out.c (loc_by_reference, gen_decl_die): Check
	DECL_BY_REFERENCE for all VAR_DECLs, not just non-static ones.
	(gen_variable_die): Likewise.  Check TREE_PRIVATE/TREE_PROTECTED
	unconditionally.

--- gcc/print-tree.c.jj	2008-11-04 21:07:40.000000000 +0100
+++ gcc/print-tree.c	2009-04-25 20:53:37.000000000 +0200
@@ -448,6 +448,10 @@ print_node (FILE *file, const char *pref
 	  fprintf (file, " %s", GET_MODE_NAME (mode));
 	}
 
+      if ((code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
+	  && DECL_BY_REFERENCE (node))
+	fputs (" passed-by-reference", file);
+
       if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)  && DECL_DEFER_OUTPUT (node))
 	fputs (" defer-output", file);
 
--- gcc/tree.h.jj	2009-04-25 20:43:51.000000000 +0200
+++ gcc/tree.h	2009-04-25 22:17:42.000000000 +0200
@@ -362,8 +362,8 @@ struct GTY(()) tree_base {
   unsigned protected_flag : 1;
   unsigned deprecated_flag : 1;
   unsigned saturating_flag : 1;
-  unsigned default_def_flag : 1;
 
+  unsigned default_def_flag : 1;
   unsigned lang_flag_0 : 1;
   unsigned lang_flag_1 : 1;
   unsigned lang_flag_2 : 1;
@@ -371,6 +371,7 @@ struct GTY(()) tree_base {
   unsigned lang_flag_4 : 1;
   unsigned lang_flag_5 : 1;
   unsigned lang_flag_6 : 1;
+
   unsigned visited : 1;
 
   unsigned spare : 23;
@@ -475,9 +476,6 @@ struct GTY(()) tree_common {
        CALL_EXPR_RETURN_SLOT_OPT in
            CALL_EXPR
 
-       DECL_BY_REFERENCE in
-           PARM_DECL, RESULT_DECL, VAR_DECL (only !TREE_STATIC)
-
        OMP_SECTION_LAST in
            OMP_SECTION
 
@@ -1294,10 +1292,12 @@ extern void omp_clause_range_check_faile
 #define CALL_EXPR_RETURN_SLOT_OPT(NODE) \
   (CALL_EXPR_CHECK (NODE)->base.private_flag)
 
-/* In a RESULT_DECL, PARM_DECL or VAR_DECL without TREE_STATIC, means that it is
+/* In a RESULT_DECL, PARM_DECL and VAR_DECL, means that it is
    passed by invisible reference (and the TREE_TYPE is a pointer to the true
    type).  */
-#define DECL_BY_REFERENCE(NODE) (DECL_COMMON_CHECK (NODE)->base.private_flag)
+#define DECL_BY_REFERENCE(NODE) \
+  (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, \
+		RESULT_DECL)->decl_common.decl_by_reference_flag)
 
 /* In a CALL_EXPR, means that the call is the jump from a thunk to the
    thunked-to function.  */
@@ -2662,8 +2662,10 @@ struct GTY(()) tree_decl_common {
   unsigned gimple_reg_flag : 1;
   /* In a DECL with pointer type, set if no TBAA should be done.  */
   unsigned no_tbaa_flag : 1;
+  /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE.  */
+  unsigned decl_by_reference_flag : 1;
   /* Padding so that 'off_align' can be on a 32-bit boundary.  */
-  unsigned decl_common_unused : 2;
+  unsigned decl_common_unused : 1;
 
   /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs.  */
   unsigned int off_align : 8;
--- gcc/dbxout.c.jj	2009-04-25 00:12:59.000000000 +0200
+++ gcc/dbxout.c	2009-04-25 20:47:48.000000000 +0200
@@ -1398,9 +1398,7 @@ dbxout_type_index (tree type)
 /* Used in several places: evaluates to '0' for a private decl,
    '1' for a protected decl, '2' for a public decl.  */
 #define DECL_ACCESSIBILITY_CHAR(DECL) \
-((TREE_CODE (DECL) != PARM_DECL && TREE_CODE (DECL) != RESULT_DECL \
-  && (TREE_CODE (DECL) != VAR_DECL || TREE_STATIC (DECL)) \
-  && TREE_PRIVATE (DECL)) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
+(TREE_PRIVATE (DECL) ? '0' : TREE_PROTECTED (DECL) ? '1' : '2')
 
 /* Subroutine of `dbxout_type'.  Output the type fields of TYPE.
    This must be a separate function because anonymous unions require
--- gcc/dwarf2out.c.jj	2009-04-25 00:13:06.000000000 +0200
+++ gcc/dwarf2out.c	2009-04-25 22:20:52.000000000 +0200
@@ -11715,7 +11715,7 @@ loc_by_reference (dw_loc_descr_ref loc, 
 
   if ((TREE_CODE (decl) != PARM_DECL
        && TREE_CODE (decl) != RESULT_DECL
-       && (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)))
+       && TREE_CODE (decl) != VAR_DECL)
       || !DECL_BY_REFERENCE (decl))
     return loc;
 
@@ -14048,19 +14048,13 @@ gen_variable_die (tree decl, tree origin
   else
     {
       tree type = TREE_TYPE (decl);
-      bool private_flag_valid = true;
 
       add_name_and_src_coords_attributes (var_die, decl);
       if ((TREE_CODE (decl) == PARM_DECL
 	   || TREE_CODE (decl) == RESULT_DECL
-	   || (TREE_CODE (decl) == VAR_DECL && !TREE_STATIC (decl)))
+	   || TREE_CODE (decl) == VAR_DECL)
 	  && DECL_BY_REFERENCE (decl))
-	{
-	  add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
-	  /* DECL_BY_REFERENCE uses the same bit as TREE_PRIVATE,
-	     for PARM_DECL, RESULT_DECL or non-static VAR_DECL.  */
-	  private_flag_valid = false;
-	}
+	add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
       else
 	add_type_attribute (var_die, type, TREE_READONLY (decl),
 			    TREE_THIS_VOLATILE (decl), context_die);
@@ -14073,7 +14067,7 @@ gen_variable_die (tree decl, tree origin
 
       if (TREE_PROTECTED (decl))
 	add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_protected);
-      else if (private_flag_valid && TREE_PRIVATE (decl))
+      else if (TREE_PRIVATE (decl))
 	add_AT_unsigned (var_die, DW_AT_accessibility, DW_ACCESS_private);
     }
 
@@ -15307,8 +15301,7 @@ gen_decl_die (tree decl, tree origin, dw
       /* Output any DIEs that are needed to specify the type of this data
 	 object.  */
       if ((TREE_CODE (decl_or_origin) == RESULT_DECL
-	   || (TREE_CODE (decl_or_origin) == VAR_DECL
-	       && !TREE_STATIC (decl_or_origin)))
+	   || TREE_CODE (decl_or_origin) == VAR_DECL)
           && DECL_BY_REFERENCE (decl_or_origin))
 	gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
       else

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] Fix up debuginfo for VLAs in nested functions
  2009-04-25 22:11   ` Jakub Jelinek
@ 2009-04-25 22:32     ` Ian Lance Taylor
  0 siblings, 0 replies; 4+ messages in thread
From: Ian Lance Taylor @ 2009-04-25 22:32 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jason Merrill, gcc-patches

Jakub Jelinek <jakub@redhat.com> writes:

> Attached is a patch to do that, bootstrapped/regtested on x86_64-linux.
>
> But, I see that tree_decl_common hase 49 unused bits (23 in struct tree_base
> and 26 in struct tree_decl_common), so perhaps it is not worth all the
> overloading trouble and we could instead just allocate a different bit
> for DECL_BY_REFERENCE (this is done in the second patch, also
> bootstrapped/regtested on x86_64-linux).
>
> Both patches are incremental, on top of the 3 patches you've ACKed.


> 2009-04-25  Jakub Jelinek  <jakub@redhat.com>
>
> 	* tree.h: Remove DECL_BY_REFERENCE from private_flag comment.
> 	(struct tree_base): Adjust spacing for 8 bit boundaries.
> 	(struct tree_decl_common): Add decl_by_reference_flag bit.
> 	(DECL_BY_REFERENCE): Adjust.
> 	* print-tree.c (print_node): For VAR_DECL, PARM_DECL or RESULT_DECL,
> 	print DECL_BY_REFERENCE bit.
> 	* dbxout.c (DECL_ACCESSIBILITY_CHAR): Revert last change.
> 	* dwarf2out.c (loc_by_reference, gen_decl_die): Check
> 	DECL_BY_REFERENCE for all VAR_DECLs, not just non-static ones.
> 	(gen_variable_die): Likewise.  Check TREE_PRIVATE/TREE_PROTECTED
> 	unconditionally.

This patch, the one which allocates a different bit, is OK, unless
somebody objects in the next couple of days.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-04-25 22:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-08 15:21 [PATCH] Fix up debuginfo for VLAs in nested functions Jakub Jelinek
2009-04-24 22:01 ` Ian Lance Taylor
2009-04-25 22:11   ` Jakub Jelinek
2009-04-25 22:32     ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).