Bug 15721

Summary: [4.0 regression] template instantation omits static data members
Product: gcc Reporter: Michael Elizabeth Chastain <mec.gnu>
Component: c++Assignee: Andrew Pinski <pinskia>
Severity: critical CC: gcc-bugs, zack+srcbugz
Priority: P1 Keywords: patch, wrong-code
Version: 4.0.0   
Target Milestone: 4.0.0   
Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed: 2004-05-29 02:52:33
Bug Depends on:    
Bug Blocks: 15546    
Attachments: Test program
assembly code, last good compiler, 2004-05-19 01:00:00 UTC
Generated code, first bad compiler, 2004-05-19 02:00:00 UTC

Description Michael Elizabeth Chastain 2004-05-29 02:21:28 UTC
Here is the test program:

template <typename T> class gnu_obj_2
    static int my_static;

template <typename T> int gnu_obj_2<T>::my_static = 117;

// instantiate templates explicitly so their static members will exist
template class gnu_obj_2 <int>;
template class gnu_obj_2 <long>;

int main ()
  gnu_obj_2 <int>  test_int;
  gnu_obj_2 <long> test_long;
  return 0;

I compile this program with "gcc -S -gstabs+".  Then I look in the generated
assembly code for the static data members gnu_obj_2<int>::my_static and

(I don't think the -gstabs+ is important but I just happened to start with this
flag and have kept it all the way till now, sigh.  This code originally came
from the gdb test suite, gdb.cp/m-static.cc).

The explicit instantiations of gnu_obj_2<int> and gnu_obj_2<long> are supposed
to instantiate the static data members along with everything else, but they don't.


The last working gcc was 2004-05-19 01:00:00 UTC and the first broken gcc was
2004-05-19 02:00:00 UTC.  The problem is with this patch:

IMA repairs: Don't use DECL_ASSEMBLER_NAME for a key in cgraph(take two)

I'll add three attachments: the test program; the last good assembly code; and
the first bad assembly code.
Comment 1 Michael Elizabeth Chastain 2004-05-29 02:23:33 UTC
Created attachment 6424 [details]
Test program

Compile with: "gcc -S -gstabs+".

Look for gnu_obj_2<int>::my_static and gnu_obj_2<long>::my_static in the
generated code.
Comment 2 Michael Elizabeth Chastain 2004-05-29 02:24:54 UTC
Created attachment 6425 [details]
assembly code, last good compiler, 2004-05-19 01:00:00 UTC

Generated assembly code with "gcc -S -gstabs+ template-static.cc".
This is with the last good compiler.
Comment 3 Michael Elizabeth Chastain 2004-05-29 02:25:45 UTC
Created attachment 6426 [details]
Generated code, first bad compiler, 2004-05-19 02:00:00 UTC

Code generated with "gcc -S -gstabs+ template-static.cc".
This is with the first bad compiler.
Comment 4 Andrew Pinski 2004-05-29 02:52:33 UTC
Confirmed,  I will try to figure out what is going on but if Zack beats me, I would not be made.

mark_decl_referenced is being called for the variable.
Comment 5 Andrew Pinski 2004-05-29 03:04:36 UTC
The problem is that decl is not finalized before being marked as needed.
Comment 6 Andrew Pinski 2004-05-29 03:33:04 UTC
I know that rest_of_decl_compilation is being called for the decl but not assemble_variable for some 
reason.  I have not checked how it was done before Zack's patch.
Comment 7 Andrew Pinski 2004-05-29 20:39:37 UTC
The difference between before and after is that DECL_EXTERNAL (decl) in rest_of_decl_compilation is 
true after but false before which causes it not be outputted.
Comment 8 Andrew Pinski 2004-05-29 22:25:16 UTC
Ignore that last comment, I was wrong, it does not even get to rest_of_decl_compilation for that decl.
Comment 9 Andrew Pinski 2004-05-29 22:29:56 UTC
Okay, wrapup_global_declarations checks TREE_SYMBOL_REFERENCED of DECL_ASSEMBLER_NAME of the 
decl which is where the problem is.
Comment 10 Andrew Pinski 2004-06-02 00:42:04 UTC
This should work (I have tested it on the testcase though), I have not bootstrapped and tested it yet:
Index: toplev.c
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.899
diff -u -p -r1.899 toplev.c
--- toplev.c    30 May 2004 18:32:27 -0000      1.899
+++ toplev.c    2 Jun 2004 00:41:09 -0000
@@ -1455,16 +1455,17 @@ wrapup_global_declarations (tree *vec, i
          if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+              struct cgraph_varpool_node *node;
              bool needed = 1;
+              node = cgraph_varpool_node (decl);
-             if (flag_unit_at_a_time
-                 && cgraph_varpool_node (decl)->finalized)
+             if (node && node->finalized)
                needed = 0;
              else if ((flag_unit_at_a_time && !cgraph_global_info_ready)
                       && (TREE_USED (decl)
                           || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
                /* needed */;
-             else if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+             else if (node && node->needed)
                /* needed */;
              else if (DECL_COMDAT (decl))
                needed = 0;
Comment 11 Andrew Pinski 2004-06-02 20:08:25 UTC
Mine, I posted a patch: <http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00088.html>.
Comment 12 Giovanni Bajo 2004-06-19 10:26:24 UTC
Andrew, this patch was approved by Mark, I assume you just forgot to apply and 
close the bug...
Comment 13 CVS Commits 2004-06-19 16:17:05 UTC
Subject: Bug 15721

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	pinskia@gcc.gnu.org	2004-06-19 16:17:01

Modified files:
	gcc            : ChangeLog toplev.c 

Log message:
	2004-06-19  Andrew Pinski  <apinski@apple.com>
	PR c++/15721
	* toplev.c (wrapup_global_declarations): Do not check
	cgraph_varpool_node's needed field.


Comment 14 Andrew Pinski 2004-06-19 16:18:10 UTC
No I was just testing it again.

Fixed now.
Comment 15 Michael Elizabeth Chastain 2004-06-22 21:52:50 UTC
Subject: Re:  [3.5 regression] template instantation omits static data members

It works for me.
Thanks, Michael C