Bug 10291 - error referencing a static local from a local struct in template code
error referencing a static local from a local struct in template code
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: c++
3.2
: P3 normal
: 4.8.0
Assigned To: Not yet assigned to anyone
: monitored, wrong-code
Depends on:
Blocks: 12944
  Show dependency treegraph
 
Reported: 2003-04-02 01:06 UTC by Martin Sebor
Modified: 2013-03-02 11:19 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-09-23 11:48:06


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2003-04-02 01:06:01 UTC
The well-fomed program below fails to compile with gcc 3.2.

Regards
Martin

Release:
3.2

How-To-Repeat:
$ cat t.cpp; gcc --version; gcc t.cpp
template <class T>
int foo ()
{
    static int i;

    struct S {
        int bar () {
            return i;
        }
    } s;

    return s.bar ();
}

int main ()
{
    foo<int>();
}

gcc (GCC) 3.2
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

t.cpp: In member function `int foo()::S::bar() [with T = int]':
t.cpp:12:   instantiated from `int foo() [with T = int]'
t.cpp:17:   instantiated from here
t.cpp:8: `i' undeclared (first use this function)
t.cpp:8: (Each undeclared identifier is reported only once for each function it 
   appears in.)
Comment 1 Wolfgang Bangerth 2003-04-02 01:27:20 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirmed with 2.95, 3.2, 3.3. With 3.4, it compiles,
    but doesn't link (see below).
    
    This testcase actually has rather interesting questions
    to offer for people who like thinking about the implications
    of two-stage name lookup, such as
    - 'i' being a variable in a template dependent namespace,
      it shouldn't be seen during first phase parsing
    - one would then need to qualify it
    - but how do you qualify function-local objects?
    
    For 3.4: as said, it compiles but doesn't link:
    g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc
    /tmp/cceV3jl1.o: In function `int foo<int>()::S::bar()':
    /tmp/cceV3jl1.o(.text+0x1c): undefined reference to `i'
    collect2: ld returned 1 exit status
    
    Something is not quite right here -- take this small
    modification (introduce another -- global -- variable 'i',
    give initializers to variables, and generate a return value):
    --------------------------
    int i = 0;
    
    template <class T>
    int foo ()
    {
        static int i = 1;
    
        struct S {
            int bar () {
                return i;
            }
        } s;
    
        return s.bar ();
    }
    
    int main ()
    {
        return foo<int>();
    }
    ------------------------------
    
    This links, but surprisingly returns zero! 
       g/x> ./a.out ; echo $?
       0
    Weird...
    W.
Comment 2 Andrew Pinski 2003-06-07 16:47:06 UTC
Still happens on the mainline (20030607).
Comment 3 Andrew Pinski 2003-08-01 20:36:52 UTC
I think the problem is that i is not being mangled.
Comment 4 Andrew Pinski 2004-02-03 07:49:09 UTC
This is no longer rejected but produces wrong code refering to the non-mangled i instead of the 
mangled i.
Comment 5 Andrew Pinski 2004-04-30 01:29:59 UTC
I almost think this is related to DR 191 <http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/
cwg_active.html#191>.
Comment 6 Martin Sebor 2004-04-30 01:46:55 UTC
(In reply to comment #5)
> I almost think this is related to DR 191
<http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#191>.

I don't see it. The original test case seems to be covered by bullet 4:

    if X is a local class (9.8) or is a nested class of a local class,
    before the definition of class X in a block enclosing the definition
    of class X

What makes you think it's related?
Martin
Comment 7 Richard Biener 2007-09-23 11:48:06 UTC
Testcase from comment #1 still returns 0 on trunk.
Comment 8 Jason Merrill 2009-11-04 23:27:48 UTC
The problem is that we use a local_specializations hash table to look up locals when instantiating a template, and i isn't in bar()'s local_specializations, so we fail.  We need to make static locals their own temploid.
Comment 9 Wolfgang Bangerth 2011-10-09 13:55:10 UTC
Still happens with gcc4.5.1.
Comment 10 Paolo Carlini 2013-03-02 11:05:45 UTC
This is fixed for 4.8.0. I'm adding the testcase and closing the PR.
Comment 11 paolo@gcc.gnu.org 2013-03-02 11:17:48 UTC
Author: paolo
Date: Sat Mar  2 11:17:44 2013
New Revision: 196405

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196405
Log:
2013-03-02  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52688
	* g++.dg/template/static33.C: New.
	* g++.dg/template/static34.C: Likewise.

	PR c++/10291
	* g++.dg/template/static35.C: New.

Added:
    trunk/gcc/testsuite/g++.dg/template/static33.C
    trunk/gcc/testsuite/g++.dg/template/static34.C
    trunk/gcc/testsuite/g++.dg/template/static35.C
Modified:
    trunk/gcc/testsuite/ChangeLog
Comment 12 Paolo Carlini 2013-03-02 11:19:06 UTC
Done.