Bug 29484 - [4.2 Regression] tree-inline.c bug with local static vars
Summary: [4.2 Regression] tree-inline.c bug with local static vars
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 4.2.0
: P2 normal
Target Milestone: 4.3.0
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: link-failure
Depends on:
Blocks:
 
Reported: 2006-10-16 15:59 UTC by Jakub Jelinek
Modified: 2009-03-30 19:40 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.0 4.3.0
Known to fail: 4.0.0 4.0.4 4.1.0 4.2.0 4.2.5
Last reconfirmed: 2007-12-20 14:32:24


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2006-10-16 15:59:59 UTC
static inline __attribute__((always_inline))
void bar (void)
{
  addr:;
  static const unsigned long b __attribute__((__used__)) __attribute__((section("btable")))
    = (unsigned long) &&addr;
  asm ("" : : "m" (b));
}

void foo (void)
{
  bar ();
}

generates at -O and higher a reference to undefined local label (and has one
unused different label).
If the body of bar is instead copied into foo () and the call removed, it works fine.
I think this is related to the http://gcc.gnu.org/ml/gcc-patches/2005-06/msg01850.html
changes, not sure why isn't the local var remapped in:
  /* Add local vars in this inlined callee to caller.  */
  t_step = id->src_cfun->unexpanded_var_list;
  for (; t_step; t_step = TREE_CHAIN (t_step))
    {
      var = TREE_VALUE (t_step);
      if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
        cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
                                               cfun->unexpanded_var_list);
      else
        cfun->unexpanded_var_list = tree_cons (NULL_TREE, remap_decl (var, id),
                                               cfun->unexpanded_var_list);
    }
asm isn't written, but the variable IMHO still needs remapping, at least to
get the LABEL_DECL in the initializer remapped.  In C there shouldn't be a problem with ODR, in C++ not sure what happens if initializer of some inline fn
local var has &&label in its initializer - issue an error?
Comment 1 Andrew Pinski 2006-10-16 16:06:40 UTC
Confirmed.
"generates at -O and higher a reference to undefined local label"
No it generates an undefined local label at all levels of optimization in 4.0.x and above (there was a bug about not supporting used on local static at -O0 which you are running into also).
Comment 2 Jakub Jelinek 2006-10-16 18:42:03 UTC
Actually, even C generates one static var for all the inlined functions (in C
within one object), so I'd say we just should mark functions containing
local static variables with &&label in their initializers as non-inlinable,
because anything else means we can't use the same variable for more than
one inlined copy of the function.
In that light the original testcase would just issue an error, as always_inline
function can't be inlined, but e.g.
void baz (unsigned long *);

static inline
void bar (void)
{
  addr:;
  static unsigned long b = (unsigned long) &&addr;
  baz (&b);
}

void
f1 (void)
{
  bar ();
}

void
f2 (void)
{
  bar ();
}
would be a valid testcase that we don't handle properly.
Comment 3 Gabriel Dos Reis 2007-02-03 20:40:57 UTC
won't fix in GCC-4.0.x.  Adjusting milestone.
Comment 4 Steven Bosscher 2007-12-16 23:18:31 UTC
Open regression with no activity since February 14.  Ping?
Comment 5 Jakub Jelinek 2008-01-03 08:34:58 UTC
Subject: Bug 29484

Author: jakub
Date: Thu Jan  3 08:33:57 2008
New Revision: 131300

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131300
Log:
	PR tree-optimization/29484
	* tree-inline.c (inline_forbidden_p_2): New function.
	(inline_forbidden_p): Disallow inlining if some static var
	has an address of a local LABEL_DECL in its initializer.
	* doc/extend.texi (Labels as Values): Document &&foo behaviour
	vs. inlining.

	* gcc.c-torture/execute/20071220-1.c: New test.
	* gcc.c-torture/execute/20071220-2.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/execute/20071220-1.c
    trunk/gcc/testsuite/gcc.c-torture/execute/20071220-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/doc/extend.texi
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-inline.c

Comment 6 Joseph S. Myers 2008-07-04 21:42:39 UTC
Closing 4.1 branch.
Comment 7 Joseph S. Myers 2009-03-30 19:40:58 UTC
Closing 4.2 branch, fixed in 4.3.