Path: utzoo!news-server.csri.toronto.edu!rutgers!usenet!ogicse!emory!swrinde!zaphod.mps.ohio-state.edu!rpi!uupsi!sunic!news.funet.fi!funic!santra!news From: jkp@cs.HUT.FI (Jyrki Kuoppala) Newsgroups: comp.os.minix Subject: Re: A patch to make gcc 1.39 work with Minix setjmp Message-ID: <1991Mar13.162852.18637@santra.uucp> Date: 13 Mar 91 16:28:52 GMT References: <1991Mar10.223859.380@santra.uucp> <1991Mar12.225635.29426@cbnewsc.att.com> Sender: news@santra.uucp (Cnews - USENET news system) Reply-To: jkp@cs.HUT.FI (Jyrki Kuoppala) Organization: Helsinki University of Technology, Finland Lines: 142 In-Reply-To: ladd@cbnewsc.att.com (david.ladd) >To me, this suggests you either make everything volatile or use >gcc -traditional. What's the big deal? Aaaaarrrgggghhh. I would suggest that people read an article before they reply to it like this. I thought I was very verbose enough about explaining the problem now, learned on an earlier forum that people don't appear to think before they jump into conclusions. Seems that explaining things doesn't help. Ah well. Local variables are not the issue here, and -traditional does not cure the problem I was having. Someone also suggested that I should not blame a compiler when setjmp is faulty. I don't think I did blame a compiler, and to me it seems neither one (gcc or setjmp) is faulty, they just don't act well together. Minix setjmp takes a different approach than setjmp on Unix systems traditionally, and gcc as is doesn't have the functionality to handle this. I assume ACK and other Minix compiler do have the functionality to take care no registers are presumed valid when longjmp returns, so on Minix setjmp should work just fine along the ANSI spec. Haven't checked with ACK or other Minix compilers, though, 'cause I don't have them. But to make this flame perhaps useful for someone, the patch I sent doesn't cure all the problems - it only makes sure the function calling setjmp doesn't clobber the parent function's variables. To make local variables safe (I hear ANSI says that they are guaranteed to remain valid if they are not modified between setjmp and longjmp) you'll need to put local variables in stack in functions calling setjmp on OS's like Minix where setjmp doesn't save registers. There might still be a problem with gcc storing something (like a function address) in call-saved registers and assuming it to be there when setjmp returns. But this problem would appear also on machines where longjump restores registers from stack instead of the jump buffer, and there seems to be code in flow.c to take care of this. Here's a diff for that which should fix local variables handling, although I haven't tested it it should be simple enought so that no bugs have crept in. *** c-decl.c.orig Tue Mar 12 01:22:03 1991 --- c-decl.c Tue Mar 12 01:25:59 1991 *************** *** 4757,4768 **** /* Must mark the RESULT_DECL as being in this function. */ DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; ! /* Obey `register' declarations if `setjmp' is called in this fn. */ ! if (flag_traditional && current_function_calls_setjmp) { setjmp_protect (DECL_INITIAL (fndecl)); setjmp_protect_args (); } --- 4757,4774 ---- /* Must mark the RESULT_DECL as being in this function. */ DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; ! /* Obey `register' declarations if `setjmp' is called in this fn. ! if ( ! #ifndef NON_REG_SAVING_SETJMP ! /* If setjmp doesn't save registers, we'll have to put all local ! variables in the stack whether -traditional or not */ ! flag_traditional && ! #endif ! current_function_calls_setjmp) { setjmp_protect (DECL_INITIAL (fndecl)); setjmp_protect_args (); } *** function.c.orig Tue Mar 12 01:31:54 1991 --- function.c Tue Mar 12 01:34:59 1991 *************** *** 2877,2887 **** for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == REG ! && ! TREE_REGDECL (decl)) put_var_into_stack (decl); for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub)) setjmp_protect (sub); } --- 2877,2893 ---- for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == REG ! #ifndef NON_REG_SAVING_SETJMP ! /* To make variables not clobbered on machines where setjmp ! doesn't save registers, we'll have to put also those declared ! as `register' in the stack. */ ! && ! TREE_REGDECL (decl) ! #endif ! ) put_var_into_stack (decl); for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub)) setjmp_protect (sub); } *************** *** 2895,2905 **** decl; decl = TREE_CHAIN (decl)) if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == REG ! && ! TREE_REGDECL (decl)) put_var_into_stack (decl); } /* Return the context-pointer register corresponding to DECL, or 0 if it does not need one. */ --- 2901,2914 ---- decl; decl = TREE_CHAIN (decl)) if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) && DECL_RTL (decl) != 0 && GET_CODE (DECL_RTL (decl)) == REG ! #ifndef NON_REG_SAVING_SETJMP ! && ! TREE_REGDECL (decl) ! #endif ! ) put_var_into_stack (decl); } /* Return the context-pointer register corresponding to DECL, or 0 if it does not need one. */ //Jyrki