[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [ft-devel] ft_setjmp in Codewarrior
From: |
mpsuzuki |
Subject: |
Re: [ft-devel] ft_setjmp in Codewarrior |
Date: |
Thu, 27 Nov 2008 21:44:22 +0900 |
Dear Garrick,
Thank you for remembering your experience and posting it.
As you wrote, I'm questionable how many die-hard CW for
Mac users are writing new softwares. But I found that
same issue is found in the latest CW for embedded platform
that defines jmp_buf as an array of long pointers.
Unfortunately, yet I'm not in complete understanding of
the function, I'm not sure if the insertion of temporal
variable is inevitable /or not. At present, I'm going to
commit CW-specific fix which does not change anything
for non-CW environment.
Regards,
mpsuzuki
On Wed, 12 Nov 2008 13:16:48 -0800
Garrick Meeker <address@hidden> wrote:
>I'm not sure how many people are still using Codewarrior. I stopped
>using it shortly after I brought up this issue a few years ago.
>
>I recall that the code in ftobjs.c uses a temporary variable for type
>checking, but removing this variable and just casting away volatile
>also works on Codewarrior.
>
>struct a_struct_ {
> jmp_buf jb_memb;
>} volatile* a_struct_ptr;
>
>//volatile jmp_buf* dest = &( a_struct_ptr->jb_memb );
>longjmp(*(jmp_buf*)&(a_struct_ptr->jb_memb), 1);
>
>If you want to keep the temporary variable, couldn't you do something
>like this?
>
>struct a_struct_ {
> jmp_buf jb_memb;
>} volatile* a_struct_ptr;
>
>struct a_struct_* dest = (struct a_struct_*)a_struct_ptr;
>longjmp(dest->jb_memb, 1);
>
>I'm not sure exactly what programming errors the temporary variable is
>supposed to catch.
>
>On Nov 8, 2008, at 7:59 AM, address@hidden wrote:
>
>> Sorry for posting about the issue 2 years ago.
>>
>> Recently I'm working to overhawl the building process of
>> FreeType2 by CodeWarrior, and I found this issue is still
>> left.
>>
>> For first, I think I should note the difference of multiple
>> definition of "jmp_buf" in MacOS. Here I quote MPW header
>>
>> /MPW-GM/Interfaces&Libraries/Interfaces/CIncludes/setjmp.h:
>> ------------------------------------------------------------
>> #if defined (powerc)
>> #if CALL_NOT_IN_CARBON || __MPWINTERNAL__
>> #if defined (__VEC__)
>> typedef vector unsigned long jmp_buf[29]; /*
>> AltiVec: LR,CR,SP,TOC,VRSAVE,R13-R31,FP14-
>> FP31,FPSCR,RESVD,RESVD,VR20-VR31,VS
>> CR */
>> #else /* !__VEC__ */
>> typedef long *jmp_buf[64]; /* PowerPC:
>> LR,CR,SP,TOC,RESVD,R13-R31,FP14-FP31,FPSCR,RESVD,RESVD */
>> #endif /* !__VEC__ */
>> #else
>> #define _JBLEN ( 26 + 36 + 129 + 1 )
>> typedef int jmp_buf[_JBLEN] ;
>> #endif /* CALL_NOT_IN_CARBON || __MPWINTERNAL__ */
>> #elif defined (OLD_JMPBUF)
>> typedef long *jmp_buf[12]; /* old 68K: D2-D7,PC,A2-
>> A4,A6,SP */
>> #else
>> typedef long *jmp_buf[16]; /* new 68K: D2-D7,PC,A2-
>> A4,A6,SP,FLAGS,A5,RESVD,RESVD */
>> #endif
>> ------------------------------------------------------------
>> You can find there are 2 styles: one is a normal array aslike:
>>
>> typedef int jmp_buf[_JBLEN];
>>
>> I think this is popular on recent Unix platforms (on HP-UX 11
>> for IA64, it's an array of 80bit float. On AIX, it's an array
>> of 32bit int for 32bit API, or 64bit long for 64bit API. On
>> IRIX, ditto). I call this as Unix jmp_buf in following (see
>> note *). In fact, Mac OS X's native jmp_buf is Unix jmp_buf.
>>
>> Another definition on MacOS is an array of pointers aslike:
>>
>> typedef long *jmp_buf[12];
>>
>> I call this as MacOS jmp_buf in following. I guess the machine
>> status are stored in jmp_buf[i], not in *(jmp_buf[i]).
>>
>> Thinking about a code like:
>>
>> struct a_struct_ {
>> jmp_buf jb_memb;
>> } volatile* a_struct_ptr;
>>
>> volatile jmp_buf* dest = &( a_struct_ptr->jb_memb );
>>
>> In the case of Unix jmp_buf, "} volatile* a_struct_ptr;"
>> qualifies the memories pointed by a_struct_ptr as volatile.
>> So all jb_memb elements are qualified as volatile too.
>> Also "volatile jmp_buf*" qualifies all dest elements as
>> volatile. They are consistent.
>>
>> In the case of MacOS jmp_buf, "} volatile* a_struct_ptr;"
>> qualifies the memories pointed by a_struct_ptr as volatile,
>> so the jb_memb elements are qualified as volatile, but
>> the memories pointed by the jb_memb elements are not qualified.
>> I guess the machine status is stored in the jb_memb, not
>> in the memories pointed by the jb_memb, so this qualification
>> is good.
>>
>> For "volatile jmp_buf* dest", according to the error message
>> by Metrowerks C compiler:
>>
>> Error : illegal implicit conversion from 'long *volatile (*)[70]'
>> to 'volatile long * (*)[70]'
>>
>> the memories pointed by the *dest elements are qualified as
>> volatile. This would NOT be expected qualification, because
>> the machine status is stored in the *dest elements, not in
>> the memories pointed by the *dest elements.
>>
>> Other compilers (I don't know appropriate method to make GCC
>> to report how the type definition is recognized. By changing
>> the qualifier from volatile to incompatible "const", HP ANSI C
>> compiler reports the error with the type definitions in both
>> sides) seem to qualify the *dest elements as volatile, and
>> leave the memories pointed by the *dest elements as unqualified.
>> So there is no consistency, and the qualification is expected one.
>>
>> Therefore, an insertion of cast (volatile jmp_buf *) to right
>> side for Metrowerks C compiler may not be good idea, because
>> the interpretation of left side would be the root of problem.
>>
>> Recent Metrowerks C compilers can allow implicit cast among
>> different pointer type: a command line option "-relax_pointers",
>> or insertion of pragma "#pragma mpwc_relax on|off|reset" makes
>> the compilation passed. This workaround is not available in
>> all CodeWarriors, but it is available since CodeWarrior v7
>> (2001) at least.
>>
>> # In legacy CodeWarrior, I tested CodeWarrior Gold 10 (1996),
>> # it has no "-relax_pointers" and the meaning of "#pragma mpwc_relax"
>> # is different, but Metrowerks C compilers in CWG10 issue no
>> # errors.
>>
>> If compiler-version-specific workaround must be avoided,
>> "volatile void*" instead of "volatile jmp_buf*" is accepted
>> by recent CodeWarrior.
>>
>> So, now I have 3 workarounds:
>>
>> a) Compile ftobjs.c (or ftbase.c) with "-relax_pointers".
>> b) Insert "#pragma mpwc_relax" with appropriate conditionals
>> (to avoid this pragma to other compilers).
>> c) Use "volatile void*" instead of "volatile jmp_buf*".
>>
>> I guess, a) is not good workaround for CodeWarrior users.
>> Because, CodeWarrior project does not support per-file
>> compile options, so the developers using CW project file
>> would compile most sources with "-relax_pointers", it
>> makes difficult to find other unexpected pointer casting.
>>
>> b) is appropriate-level workaround (the modification is
>> restricted to the problematic part only), but it's
>> questionable to insert legacy-platform-specific workaround
>> in generic source file ftobjs.c.
>>
>> c) is compiler-independent and generic workaround, but
>> its impact (against the optimizer) can be slightly large.
>> At present, I've checked the assembly outputs by a few
>> C compilers, and I didn't find no difference between
>> "volatile jmp_buf*" versus "volatile void*".
>>
>> Which workaround is most appropriate?
>>
>> Regards,
>> mpsuzuki
>>
>>
>> (*)
>> Looking at the definitions of jmp_buf in very legacy GNU
>> libc-1.09.1 (1994), there had ever been some mixed styles.
>>
>> [alpha]
>> typedef struct
>> {
>> long int __9, __10, __11, __12, __13, __14;
>> long int *__pc, *__fp, *__sp;
>> double __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9;
>> } __jmp_buf[1];
>>
>> [m68k]
>> typedef struct
>> {
>> long int __dregs[7];
>> int *__aregs[6];
>> int * __fp;
>> int * __sp;
>> char __fpregs[8 * (96 / 8)];
>> } __jmp_buf[1];
>>
>> But such styles are not found in recent GNU libc. I guess
>> giving explicit semantics to the elements/members of jmp_buf
>> is now avoided.
>>
>>
>>
>>
>>
>> On Sun, 24 Sep 2006 18:45:38 +0200 (CEST)
>> Werner LEMBERG <address@hidden> wrote:
>>
>>>
>>>> This definition also made FT_ValidatorRec's field jump_buffer
>>>> volatile so that a volatile jmp_buf* is passed to (ft_)setjmp and
>>>> (ft_)longjmp. Unfortunately my compiler (GCC 4.1.1) does not emit a
>>>> warning (not even with -Wcast-qual), so this problem eluded
>>>> me. (Strangely G++ 4.1.1 aborts with an error.)
>>>
>>> Yep -- it's really necessary that this is going to be fixed. We've
>>> always supported compilation with both C and C++ compilers.
>>>
>>>
>>> Werner
>
Re: [ft-devel] ft_setjmp in Codewarrior, Garrick Meeker, 2008/11/13
- Re: [ft-devel] ft_setjmp in Codewarrior,
mpsuzuki <=