diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-11-25 22:18:58 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1997-11-25 22:18:58 +0000 |
commit | 7a5fe8ce23ac50450b804cf0183c773565ae7cef (patch) | |
tree | 220a38a6627619d1386897d42757a140b9de448f /rpc++/gcc-2.2.fix | |
parent | 87b0987cad99cf45cd5d9e03cd1cefbaaec4ef2a (diff) | |
download | ATCD-7a5fe8ce23ac50450b804cf0183c773565ae7cef.tar.gz |
This commit was manufactured by cvs2svn to create branch 'ACE-4_4'.ACE-4_4
Diffstat (limited to 'rpc++/gcc-2.2.fix')
-rw-r--r-- | rpc++/gcc-2.2.fix | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/rpc++/gcc-2.2.fix b/rpc++/gcc-2.2.fix deleted file mode 100644 index f684e5b128b..00000000000 --- a/rpc++/gcc-2.2.fix +++ /dev/null @@ -1,252 +0,0 @@ -To: bug-g++@prep.ai.mit.edu -Subject: gcc-2.2 loops with template-local typedefs (bug&patch) -BCC: mnl,ulf ---text follows this line-- -Hi, - -trying to translate the following fragment on a Sparc running SunOs 4.1.2 -with gcc-2.2 results in gcc infinitly looping. - ---------------------------------------------------------------------------- -// -*- c++ -*- - -class AnyRpcCallback -{ -protected: - -public: - inline virtual ~AnyRpcCallback () {} - inline virtual void Do (void* in, void* out) = 0; -}; - -template<class T> class RpcCallback : public AnyRpcCallback -{ - typedef void (T::*Method)(void*, void*); - typedef void (T::*MethodN)(void*, void**); - typedef void (T::*Method1)(void*, void*); - typedef void (T::*Method2)(void*, void*, void*); - -private: - T* object; - void (T::*method)(void*, void*); - -public: - inline RpcCallback (T* o, void* m) - { object = o; method = m; } - inline void Do (void* in, void* out) - { (object->*method)(in, out); } -}; - -class Test -{ -public: - void m (void*, void*); -}; - -main () -{ - Test o; - AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m); -} ---------------------------------------------------------------------------- - -PLEASE NOTE that you will get another loop due to a bug that I have -reported together with a patch earlier (it's appended to this mail). -So you won't be able to reproduce the bug reported in this mail unless -you have my previous patch applied. I am, however, definitely sure -(and the explanation below will confirm it) that the bug reported in -this mail is *NOT* caused by my patch! - -The problem is, that the "chain" field of the tree-nodes used by gcc -for its internal representation is used for various purposes, and in -the case of this template-local typedef, someone lost track of its usage. - -After parsing, the TYPE_DECL-node created for the typedef is appended -to the scope via "pushlevel". Types in the current scope are linked -using the "chain" field. At the same time, however, all components of -the template are linked together during parsing using the same "chain" -field. Parsing the second typedef, "pushlevel" makes the first typedef -a successor of the second typedef and the subsequent catenation of -components makes the second typedef a successor of the first typedef -thus creating a loop. - -The resulting list of all components is used in routine -"finish_struct". - -I think the most proper approach would be to use TREE_LIST nodes in -the list of components as indirect references to the typedef-nodes. -This is easy to achieve, it is, however, very hard to modify -finish_struct in a way that it handles these indirection properly. -Actually, I gave up when I tried to understand & modify the routine -that removes the duplicate declarations from the list of components. - -There are two easier approaches: (1) Don't include typedefs in the -list of components, (2) use copies of the typedef-node which have an -unused chain field. The first approach assumes that finish_struct -doesn't do anything with typedefs, so it wouldn't be important if they -are missing from the list of components. If this is the case, however, -it can't hurt to use copies of the typedef-nodes (copies of the -originals that are linked in the scope-list), so the second approach -is safer. It can only fail if finish_struct modifies the typedef-nodes -and this modification is significant for the typedef-nodes in the -scope-list (which are, of course, not modified. Only the copies are). - -So I think the patch is pretty safe. It fixes the problem and doesn't -seem to introduce new ones. I'm aware that typedefs that are local to -templates stretch language features to the limits, but it makes my -C++ interface to RPCs real nice (I'll post it one of these days). - -Michael - -*** .orig/cp-parse.y Mon Jun 15 17:08:58 1992 ---- cp-parse.y Mon Jun 15 19:13:15 1992 -*************** -*** 2211,2217 **** - if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t)) - $$ = grok_enum_decls (t, $2); - else -! $$ = $2; - } - end_exception_decls (); - } ---- 2211,2233 ---- - if (TREE_CODE (t) == ENUMERAL_TYPE && TREE_NONLOCAL_FLAG (t)) - $$ = grok_enum_decls (t, $2); - else -! { -! /* if a component is a typedef, it is inserted -! in the list of nodes that make up the valid -! types in the scope. Thus its chain field is -! used and can't be used a second time for linking -! the components of the struct. So, we make a copy -! here. This apparently works. The proper thing -! to do, however, would be to use a TREE_LIST -! node to reference the typedef. I tried to rewrite -! finish_struct accordingly (i.e., ``dereference'' -! components TREE_LIST before use, but I gave up. -! mnl@dtro.e-technik.th-darmstadt.de */ -! if (TREE_CODE ($2) == TYPE_DECL) -! $$ = copy_node ($2); -! else -! $$ = $2; -! } - } - end_exception_decls (); - } - -=========================================================================== -The previous bug: ---------------------------------------------------------------------------- -Return-Path: <mnl> -Date: Wed, 10 Jun 92 19:31:13 +0200 -From: "Michael N. Lipp" <mnl> -To: bug-g++@prep.ai.mit.edu -Subject: gcc-2.2 bug&patch: typedef in template - -Hi, - -gcc-2.2 on a sparc running SunOS 4.1.2 enters an infinite loop when -compiling this: - ------------------------------------------------------------------------------ -// -*- c++ -*- - -class AnyRpcCallback -{ -protected: - -public: - inline virtual ~AnyRpcCallback () {} - inline virtual void Do (void* in, void* out) = 0; -}; - -template<class T> class RpcCallback : public AnyRpcCallback -{ - typedef void (T::*Method)(void*, void*); - -private: - T* object; - void (T::*method)(void*, void*); - -public: - inline RpcCallback (T* o, void* m) - { object = o; method = m; } - inline void Do (void* in, void* out) - { (object->*method)(in, out); } -}; - -class Test -{ -public: - void m (void*, void*); -}; - -main () -{ - Test o; - AnyRpcCallback* cb = new RpcCallback<Test> (&o, &Test::m); -} ------------------------------------------------------------------------------ - -This is quite an improvement over gcc-2.1 which dumped core with this -source. - -I tracked the cause down: grokdeclarator does a pushlevel(0), then -calls start_decl, which in turn calls grokdeclarator again which does -a poplevel_class. This poplevel_class pops the level pushed by -pushlevel(0) and so the poplevel performed by grokdeclarator to match -its pushlevel(0) pops quite a different level! This can easily be -observed by compiling cp-decl.c with -DDEBUG_CP_BINDING_LEVELS. - -Here is a patch that fixes the bug. I don't think it hits the real -cause of this problem, but it works. - -*** .orig/cp-decl.c Wed Jun 10 14:06:26 1992 ---- cp-decl.c Wed Jun 10 15:20:38 1992 -*************** -*** 6874,6882 **** ---- 6874,6889 ---- - tree loc_typedecl; - register int i = sizeof (struct lang_decl_flags) / sizeof (int); - register int *pi; -+ struct binding_level *local_binding_level; - - /* keep `grokdeclarator' from thinking we are in PARM context. */ - pushlevel (0); -+ /* poplevel_class may be called by grokdeclarator which is called in -+ start_decl which is called below. In this case, our pushed level -+ may vanish and poplevel mustn't be called. So remember what we -+ have pushed and pop only if that is matched by -+ current_binding_level later. mnl@dtro.e-technik.th-darmstadt.de */ -+ local_binding_level = current_binding_level; - loc_typedecl = start_decl (declarator, declspecs, initialized, NULL_TREE); - - pi = (int *) permalloc (sizeof (struct lang_decl_flags)); -*************** -*** 6883,6889 **** - while (i > 0) - pi[--i] = 0; - DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; -! poplevel (0, 0, 0); - - #if 0 - if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE) ---- 6890,6897 ---- - while (i > 0) - pi[--i] = 0; - DECL_LANG_SPECIFIC (loc_typedecl) = (struct lang_decl *) pi; -! if (current_binding_level == local_binding_level) -! poplevel (0, 0, 0); - - #if 0 - if (TREE_CODE (TREE_TYPE (loc_typedecl)) == ENUMERAL_TYPE) - -Michael - ------------------,------------------------------,------------------------------ -Michael N. Lipp ! Institut fuer Datentechnik ! Phone: 49-6151-163776 - ! Merckstr. 25 ,----------' Fax: 49-6151-164976 - ! D-6100 Darmstadt ! E-Mail: - ! (Germany) ! mnl@dtro.e-technik.th-darmstadt.de ------------------'-------------------'----------------------------------------- - |