This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] adjust setting of TREE_STATIC and DECL_CONTEXT


Hello,

This is a followup to the thread on the definition of TREE_READONLY at
http://gcc.gnu.org/ml/gcc/2008-07/msg00205.html.

The initial issue we were having is wrong code generation at -O1 for
the testcase below on pentium-mingw32msv:

    package TREE_STATIC_Def is
       type Int is record
	  Value : Integer;
       end record;

       procedure check (I : Int; v : integer);

       One : constant Int := (Value => 1);
    end;

    with TREE_STATIC_Def; use TREE_STATIC_Def;
    procedure TREE_STATIC_Use is
       I : Int := One;
    begin
       check (I, 1);
    end;

The anomaly was visible out of the early sra dump:

      integer i$value;
      const struct tree_static_def__int i;

      <bb 2>:
      i$value_1 = 0;         <== err
      i.value ={v} i$value_1;
      tree_static_def__check (i, 1);


"I : Int := One" is first gimplified into

  const struct tree_static_def__int i;
  i = tree_static_def__one;

While the assignment to a const doesn't look good (I'll followup on
that), the bug is actually caused by an unrelated anomaly: a
mis-assignment by the Ada front-end of TREE_STATIC on "One" in this
context, in error because TREE_STATIC implies storage allocation and
One is external here.

We end up triggering this piece of tree-sra:

  sra_walk_gimple_modify_stmt

      /* If this is an assignment from read-only memory, treat this as if
	 we'd been passed the constructor directly.  Invoke INIT.  */
      else if (TREE_CODE (rhs) == VAR_DECL
	       && TREE_STATIC (rhs)
	       && TREE_READONLY (rhs)
	       && targetm.binds_local_p (rhs))
	fns->init (lhs_elt, DECL_INITIAL (rhs), bsi);

and it generates bogus code because we don't have the DECL_INITIAL
attached.

The create_var_decl part of the attached patch fixes this by making
sure we don't set TREE_STATIC on externals in gigi, so far induced by
a strong expectation on the public_flag argument (that it should only
be set for definitions), not always honored by callers.

This uncovered another issue with the way we assign DECL_CONTEXT to
some public external entities, sometimes from the current fn decl on
references, which tripped on

    expand_expr_real_1

      /* Variables inherited from containing functions should have
	 been lowered by this point.  */
      context = decl_function_context (exp);
      gcc_assert (!context
		  || context == current_function_decl
		  || TREE_STATIC (exp)
		  /* ??? C++ creates functions that are not TREE_STATIC.  */
		  || TREE_CODE (exp) == FUNCTION_DECL);


while compiling the second testcase attached.

The gnat_pushdecl piece of this patch addresses that second issue.

Bootstrapped and regtested on x86_64-suse-linux from rev 137630.

	2007-07-17  Olivier Hainque  <hainque@adacore.com>

	ada/
	* utils.c (create_var_decl_1): Relax expectations on the PUBLIC_FLAG
        argument, to apply to references in addition to definitions.  Prevent
        setting TREE_STATIC on externals.
        (gnat_pushdecl): Always clear DECL_CONTEXT on public externals.

	testsuite/
	* gnat.dg/tree_static_def.ad[bs]: Support for ...
	* gnat.dg/tree_static_use.adb: New test.
	* gnat.dg/decl_ctx_def.ads: Support for ...
	* gnat.dg/decl_ctx_use.ad[bs]: New test.


Attachment: tree-static.dif
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]