diff options
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/20091006-2_0.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/20091006-2_1.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/20091006-2_2.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/20091013-1_0.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/20091013-1_1.c | 111 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/20091013-1_2.c | 220 |
7 files changed, 368 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e53af9..95cddc4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2009-10-13 Richard Guenther <rguenther@suse.de> + + PR lto/41668 + * gcc.dg/lto/20091006-2_0.c: New testcase. + * gcc.dg/lto/20091006-2_1.c: Likewise. + * gcc.dg/lto/20091006-2_2.c: Likewise. + * gcc.dg/lto/20091013-1_0.c: Likewise. + * gcc.dg/lto/20091013-1_1.c: Likewise. + * gcc.dg/lto/20091013-1_2.c: Likewise. + 2009-10-13 Martin Jambor <mjambor@suse.cz> * gcc.c-torture/compile/pr41661.c: New test. diff --git a/gcc/testsuite/gcc.dg/lto/20091006-2_0.c b/gcc/testsuite/gcc.dg/lto/20091006-2_0.c new file mode 100644 index 0000000..f818992 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091006-2_0.c @@ -0,0 +1,4 @@ +/* { dg-lto-do link } */ + +extern int a[10]; +int main() { return 0; } diff --git a/gcc/testsuite/gcc.dg/lto/20091006-2_1.c b/gcc/testsuite/gcc.dg/lto/20091006-2_1.c new file mode 100644 index 0000000..5818393 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091006-2_1.c @@ -0,0 +1 @@ +int a[16]; diff --git a/gcc/testsuite/gcc.dg/lto/20091006-2_2.c b/gcc/testsuite/gcc.dg/lto/20091006-2_2.c new file mode 100644 index 0000000..a610b2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091006-2_2.c @@ -0,0 +1 @@ +extern int a[14]; diff --git a/gcc/testsuite/gcc.dg/lto/20091013-1_0.c b/gcc/testsuite/gcc.dg/lto/20091013-1_0.c new file mode 100644 index 0000000..e1a7dc8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091013-1_0.c @@ -0,0 +1,21 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options {{-fPIC -shared -flto} {-fPIC -shared -O2 -flto}} } */ + +void * HeapAlloc(void*,unsigned int,unsigned long); + +typedef struct tagGdiFont GdiFont; + +typedef struct tagDC { + int xunused; + GdiFont *gdiFont; + unsigned int font_code_page; +} DC; + +DC *alloc_dc_ptr( void *funcs, unsigned short magic ) +{ + DC *dc; + if (!(dc = HeapAlloc( 0, 0, sizeof(*dc) ))) return ((void *)0); + dc->gdiFont = 0; + return dc; +} + diff --git a/gcc/testsuite/gcc.dg/lto/20091013-1_1.c b/gcc/testsuite/gcc.dg/lto/20091013-1_1.c new file mode 100644 index 0000000..68294fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091013-1_1.c @@ -0,0 +1,111 @@ +typedef struct HDC__ { int unused; } *HDC; +typedef struct HFONT__ { int unused; } *HFONT; + +typedef struct +{ + unsigned int ciACP; +} CHARSETINFO, *PCHARSETINFO, *LPCHARSETINFO; + +typedef struct tagTEXTMETRICW +{ + int tmCharSet; +} TEXTMETRICW, *LPTEXTMETRICW, *PTEXTMETRICW; + +struct gdi_obj_funcs +{ + void* (*pSelectObject)( void* handle, void* hdc ); +}; + +typedef struct tagGdiFont GdiFont; + +typedef struct tagDC +{ + int xunused; + GdiFont *gdiFont; + unsigned int font_code_page; +} DC; + +extern GdiFont* WineEngCreateFontInstance(DC*, HFONT); +extern unsigned int WineEngGetTextCharsetInfo(GdiFont *font, void* fs, unsigned int flags); +extern int WineEngGetTextMetrics(GdiFont*, LPTEXTMETRICW); +extern void* alloc_gdi_handle( void *obj, unsigned short type, const struct gdi_obj_funcs *funcs ); + +enum __wine_debug_class +{ + __WINE_DBCL_FIXME, + __WINE_DBCL_ERR, + __WINE_DBCL_WARN, + __WINE_DBCL_TRACE, + + __WINE_DBCL_INIT = 7 +}; + +struct __wine_debug_channel +{ + unsigned char flags; + char name[15]; +}; + +extern int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *ch, const char *func, + const char *format, ... ) __attribute__((format (printf,4,5))); + +static struct __wine_debug_channel __wine_dbch_font = { ~0, "font" }; +static struct __wine_debug_channel * const __wine_dbch___default = &__wine_dbch_font; + +static void* FONT_SelectObject( void* handle, void* hdc ); + +static const struct gdi_obj_funcs font_funcs = +{ + FONT_SelectObject, +}; + +HFONT CreateFontIndirectW( const void *plf ) +{ + return alloc_gdi_handle( 0, 6, &font_funcs ); +} + +static void update_font_code_page( DC *dc ) +{ + CHARSETINFO csi; + int charset = (unsigned char)1; + + if (dc->gdiFont) + charset = WineEngGetTextCharsetInfo( dc->gdiFont, ((void *)0), 0 ); + + if (TranslateCharsetInfo( ((void *)(unsigned long)((unsigned long)charset)), &csi, 1) ) + dc->font_code_page = csi.ciACP; + else { + switch(charset) { + case (unsigned char)1: + dc->font_code_page = GetACP(); + break; + + case (unsigned char)246: + dc->font_code_page = 0; + break; + + default: + do { if((((__wine_dbch___default))->flags & (1 << __WINE_DBCL_FIXME))) { struct __wine_debug_channel * const __dbch = (__wine_dbch___default); const enum __wine_debug_class __dbcl = __WINE_DBCL_FIXME; wine_dbg_log( __dbcl, __dbch, __FUNCTION__, "Can't find codepage for charset %d\n", charset); } } while(0); + dc->font_code_page = 0; + break; + } + } + + do { if((((__wine_dbch___default))->flags & (1 << __WINE_DBCL_TRACE))) { struct __wine_debug_channel * const __dbch = (__wine_dbch___default); const enum __wine_debug_class __dbcl = __WINE_DBCL_TRACE; wine_dbg_log( __dbcl, __dbch, __FUNCTION__, "charset %d => cp %d\n", charset, dc->font_code_page); } } while(0); +} + +static void* FONT_SelectObject( void* handle, void* hdc ) +{ + DC *dc; + + dc->gdiFont = WineEngCreateFontInstance( dc, handle ); + update_font_code_page( dc ); + return 0; +} + +int GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics ) +{ + DC * dc; + return WineEngGetTextMetrics(dc->gdiFont, metrics); +} + diff --git a/gcc/testsuite/gcc.dg/lto/20091013-1_2.c b/gcc/testsuite/gcc.dg/lto/20091013-1_2.c new file mode 100644 index 0000000..55f8ca1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/20091013-1_2.c @@ -0,0 +1,220 @@ +typedef struct HDC__ { int unused; } *HDC; +typedef struct HFONT__ { int unused; } *HFONT; + +void* HeapAlloc(void*,unsigned int,unsigned long); + +typedef struct tagLOGFONTW +{ + int lfPitchAndFamily; + unsigned short lfFaceName[32]; +} LOGFONTW, *PLOGFONTW, *LPLOGFONTW; + +typedef struct tagGdiFont GdiFont; +typedef struct tagDC DC; + +extern unsigned int WineEngGetFontData(GdiFont*, unsigned int, unsigned int, void*, unsigned int); + +struct list +{ + struct list *next; + struct list *prev; +}; + +typedef struct FT_FaceRec_ +{ + signed long face_flags; +} FT_FaceRec, *FT_Face; + +typedef struct { } GM; + +typedef struct { } FMAT2; + +typedef struct { + unsigned int hash; + LOGFONTW lf; + int can_use_bitmap; +} FONT_DESC; + + + +typedef struct tagHFONTLIST { + struct list entry; + HFONT hfont; +} HFONTLIST; + +typedef struct { + struct list entry; + void *face; + GdiFont *font; +} CHILD_FONT; + + +struct tagGdiFont { + struct list entry; + GM **gm; + struct list hfontlist; + struct list child_fonts; + + FT_Face ft_face; + FONT_DESC font_desc; + long ppem; +}; + + + +static struct list gdi_font_list = { &(gdi_font_list), &(gdi_font_list) }; + + + + +static int get_glyph_index_linked(GdiFont *font, unsigned int c, GdiFont **linked_font, unsigned int *glyph); +static long load_VDMX(GdiFont*, long); + +extern int f1(void*,int); + +static FT_Face OpenFontFace(GdiFont *font, void *face, long width, long height) +{ + FT_Face ft_face; + + font->ppem = load_VDMX(font, height); + if(font->ppem == 0) + font->ppem = f1(ft_face, height); + return ft_face; +} + + +static GdiFont *alloc_font(void) +{ + GdiFont *ret = HeapAlloc(0, 0x00000008, sizeof(*ret)); + ret->gm = HeapAlloc(0, 0x00000008, sizeof(GM*)); + return ret; +} + + +static long load_VDMX(GdiFont *font,long height) +{ + unsigned short hdr[3]; + + WineEngGetFontData(font, 0x42424242, 0, hdr, 6); + return 0; +} + +static int fontcmp(const GdiFont *font, FONT_DESC *fd) +{ + if(font->font_desc.hash != fd->hash) return 1; + if(memcmp(&font->font_desc.lf, &fd->lf, __builtin_offsetof (LOGFONTW, lfFaceName))) return 1; + if(!font->font_desc.can_use_bitmap != !fd->can_use_bitmap) return 1; + return strcmpiW(font->font_desc.lf.lfFaceName, fd->lf.lfFaceName); +} + +static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pmat, int can_use_bitmap) +{ + GdiFont *ret; + FONT_DESC fd; + HFONTLIST *hflist; + struct list *font_elem_ptr, *hfontlist_elem_ptr; + + fd.lf = *plf; + fd.can_use_bitmap = can_use_bitmap; + + + for ((font_elem_ptr) = (&gdi_font_list)->next; (font_elem_ptr) != (&gdi_font_list); (font_elem_ptr) = (font_elem_ptr)->next) { + ret = ((struct tagGdiFont *)((char *)(font_elem_ptr) - (unsigned long)(&((struct tagGdiFont *)0)->entry))); + if(!fontcmp(ret, &fd)) { + if(!can_use_bitmap && !( ret->ft_face->face_flags & ( 1L << 0 ) )) continue; + for ((hfontlist_elem_ptr) = (&ret->hfontlist)->next; (hfontlist_elem_ptr) != (&ret->hfontlist); (hfontlist_elem_ptr) = (hfontlist_elem_ptr)->next) { + hflist = ((struct tagHFONTLIST *)((char *)(hfontlist_elem_ptr) - (unsigned long)(&((struct tagHFONTLIST *)0)->entry))); + if(hflist->hfont == hfont) + return ret; + } + hflist = HeapAlloc(0, 0, sizeof(*hflist)); + hflist->hfont = hfont; + return ret; + } + } + + while(font_elem_ptr) { + ret = ((struct tagGdiFont *)((char *)(font_elem_ptr) - (unsigned long)(&((struct tagGdiFont *)0)->entry))); + if(!fontcmp(ret, &fd)) { + if(!can_use_bitmap && !( ret->ft_face->face_flags & ( 1L << 0 ) )) continue; + hflist = HeapAlloc(0, 0, sizeof(*hflist)); + hflist->hfont = hfont; + return ret; + } + } + return ((void *)0); +} + + + + +GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont) +{ + GdiFont *ret; + int can_use_bitmap; + LOGFONTW lf; + FMAT2 dcmat; + + if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != ((void *)0)) + return ret; + return alloc_font(); +} + +extern unsigned int f(void*,unsigned int g); + +static unsigned int get_glyph_index(void*font, unsigned int glyph) +{ + return f(font, glyph); +} + +unsigned int WineEngGetGlyphOutline(GdiFont *incoming_font, unsigned int glyph, unsigned int format, + void* lpgm, unsigned int buflen, void* buf, + const void* lpmat) +{ + unsigned int glyph_index; + + get_glyph_index_linked(incoming_font, glyph, &incoming_font, &glyph_index); + return 0; +} + +static int load_child_font(GdiFont *font, CHILD_FONT *child) +{ + child->font = alloc_font(); + child->font->ft_face = OpenFontFace(child->font, child->face, 0, -font->ppem); + if(!child->font->ft_face) + return 0; + return 1; +} + +static int get_glyph_index_linked(GdiFont *font, unsigned int c, GdiFont **linked_font, unsigned int *glyph) +{ + unsigned int g; + CHILD_FONT *child_font; + + for ((child_font) = ((CHILD_FONT *)((char *)((&font->child_fonts)->next) - (unsigned long)(&((CHILD_FONT *)0)->entry))); &(child_font)->entry != (&font->child_fonts); (child_font) = ((CHILD_FONT *)((char *)((child_font)->entry.next) - (unsigned long)(&((CHILD_FONT *)0)->entry)))) + { + if(!load_child_font(font, child_font)) + continue; + + g = get_glyph_index(child_font->font, c); + if(g) { + *glyph = g; + *linked_font = child_font->font; + return 1; + } + } + return 0; +} + +unsigned int WineEngGetFontData(GdiFont *font, unsigned int table, unsigned int offset, void* buf, + unsigned int cbData) +{ + unsigned long len; + load_sfnt_table(font->ft_face, table, offset, buf, &len); + return len; +} + +int WineEngGetLinkedHFont(DC *dc, unsigned short c, HFONT *new_hfont, unsigned int *glyph) { + return get_glyph_index_linked(0, 0, 0, 0); +} + |