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]

[PATCH] problem with static variables in template functions



hi -

The egcs 1.1 test version appears to mishandle static variables
in template functions on Digital Unix.

Here are the version numbers:

>From egcs_1_1_branch, checked out the afternoon of Aug. 6, 1998.
gcc version egcs-2.91.53 19980806 (gcc2 ss-980609 experimental)
Native configuration is alphaev56-dec-osf4.0b


Here's an example:

--- u.hpp --------------------------------------------------------------
template <class T> 
class T2
{
public:
  static int use_x (int x = 0)
  {
    static int xstatic;
    if (x)
      xstatic = x;
    return xstatic;
  };
};
--- u1.cpp -------------------------------------------------------------
#include "u.hpp"

void u1 ()
{
  T2<int>::use_x (1);
}
--- u2.cpp -------------------------------------------------------------
#include "u.hpp"
#include <iostream.h>

void u1 ();

main ()
{
  u1 ();
  cout << T2<int>::use_x (0) << "\n";
}
------------------------------------------------------------------------


Compile these two modules together with `g++ -o u u1.cpp u2.cpp'.

When run, this prints `0', rather than `1' as i'd expect
(and which i get with other compilers).


If i look at the symbols which are being generated, 

u1.s:   .lcomm xstatic.4,4
u2.s:   .lcomm xstatic.284,4


An instance of T2<int>::use_x(int) is being generated in each
compilation unit, but the xstatic variable each uses is local.

I also tried this test with the same version of the compiler
built on a linux platform.  There, it worked.  The difference
was that on linux, the template function instantiations were
given weak linkage, so that only one copy was actually linked
into the binary.

I tried rebuilding the test on the digital unix platform with -frepo,
but that didn't help --- gcc still generates two copies of the
use_x() function in the binary.  (The use_x() function itself gets
a module-local symbol.)

Here's a patch which seems to fix it.  In tsubst_expt, i call
build_static_name for static variable declarations, to give static
variables a unique external name.  Then in cp_finish_decl,
static variables of template functions are marked public.

I've applied this patch to the 1.1 branch and tested it on digital
unix and i386/linux platforms.  In both cases, this patch causes no
changes in the test results.  I haven't yet tested this on the main
trunk.

thanks,
sss



1998-08-09  scott snyder  <snyder@d0linux01.fnal.gov>

	* pt.c (tsubst_expr): Use build_static_name for static variable
	declarations.
	* decl.c (cp_finish_decl): Turn on TREE_PUBLIC for static
	variables in template functions.


Index: cp/decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.152.2.8
diff -u -u -p -r1.152.2.8 decl.c
--- decl.c	1998/07/29 14:56:23	1.152.2.8
+++ decl.c	1998/08/09 21:06:15
@@ -7236,6 +7236,20 @@ cp_finish_decl (decl, init, asmspec_tree
 	    }
 	}
 
+      /* Static variables in template functions should have a public
+         name, in case we end up instantiating the template in multiple
+         compilation units. */
+      if (TREE_CODE (decl) == VAR_DECL
+	  && TREE_STATIC (decl)
+	  && ! TREE_ASM_WRITTEN (decl)
+	  && current_function_decl
+	  && DECL_CONTEXT (decl) == current_function_decl
+          && DECL_LANG_SPECIFIC (current_function_decl)
+          && DECL_USE_TEMPLATE (current_function_decl))
+      {
+        TREE_PUBLIC (decl) = 1;
+      }
+
       if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
 	make_decl_rtl (decl, NULL_PTR, toplev);
       else if (TREE_CODE (decl) == VAR_DECL
Index: cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.162.2.5
diff -u -u -p -r1.162.2.5 pt.c
--- pt.c	1998/07/27 11:15:25	1.162.2.5
+++ pt.c	1998/08/09 21:06:16
@@ -5516,6 +5516,14 @@ tsubst_expr (t, args, in_decl)
 	  (tsubst (TREE_OPERAND (t, 0), args, in_decl),
 	   tsubst (TREE_OPERAND (t, 1), args, in_decl),
 	   TREE_OPERAND (t, 2) != 0, NULL_TREE, NULL_TREE);
+
+        /* If this is a static variable declaration, give it an external
+           name which is distinguished from other instantiations
+           of this template. */
+        if (TREE_CODE (dcl) == VAR_DECL && TREE_STATIC (dcl))
+          DECL_ASSEMBLER_NAME (dcl) =
+            build_static_name (DECL_CONTEXT (dcl), DECL_NAME (dcl));
+
 	init = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl);
 	cp_finish_decl
 	  (dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0);


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