freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [ft-devel] ft_setjmp in Codewarrior


From: David Turner
Subject: Re: [ft-devel] ft_setjmp in Codewarrior
Date: Tue, 11 Nov 2008 10:08:34 +0100

I would advise to go with solution b. We don't live in a perfect world and sometimes such hacks
are necessary. I remember that we had to rewrite a routine in ftcalc.c because some Mac compiler
did mis-compile it, for example.

Be sure to leave a comment that explains the reason for the change in the source, so we don't have
to dig in the CVS log to understand it in one year when we all forget about it.

thanks a lot

- David

2008/11/8 <address@hidden>
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


_______________________________________________
Freetype-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/freetype-devel


reply via email to

[Prev in Thread] Current Thread [Next in Thread]