$ gcc -V 4.3 -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure linux gnu Thread model: posix gcc version 4.3.0 20080219 (prerelease) [gcc-4_3-branch revision 132456] (Debian 4.3-20080219-1) $ gcc -V 4.3 fs.i -funsigned-char -Os -Wall -S -o fs.S fs.i: In function ‘DOS_analyse’: fs.i:149: warning: array subscript is above array bounds The warning is in a inline function, setting it non-inline make the warning disappear - and I still have no clue where is the problem in this file fs.i: typedef struct { unsigned magic; unsigned short version; struct gujin_param_compilation_attrib { unsigned short vga_support:1; unsigned short big_malloc:1; unsigned short bios_only:1; unsigned short initrd_loader:1; unsigned short vmlinuz_loader:1; unsigned short reserved:11; } __attribute__ ((packed)) compilation_attrib; char dot_msg[4]; char go_msg[8]; char scanpath[16]; unsigned short default_video_mode, default_text_video_mode, default_graphic_video_mode; unsigned char min_nb_initrd; unsigned char stop_emulation; struct gujin_param_attrib { unsigned verbose:1; unsigned lock_bpp:1; unsigned lock_text_graphic:1; unsigned menu_with_disk:1; unsigned menu_with_parttype:1; unsigned menu_with_partition:1; unsigned menu_with_initrd:1; unsigned force_textmode:1; unsigned force_bzimage_protocol:1; unsigned force_probe_root:1; unsigned IDE_in_BIOS_order:1; unsigned ignore_kernel_option:1; unsigned disk_write_enable:1; unsigned hide_unhide_partitions:1; unsigned VGA_interface:1; unsigned download_ansi_font:1; unsigned VESA_interface:1; unsigned enable_VESA_hardwin:1; unsigned VESA2_interface:1; unsigned enable_joystick:1; unsigned search_disk_mbr:1; unsigned search_part_mbr:1; unsigned keep_all_part_mbr:1; unsigned search_el_torito:1; unsigned search_topdir_kernel:1; unsigned search_subdir_kernel:1; unsigned probe_bios_floppy_disk:1; unsigned probe_bios_hard_disk:1; unsigned probe_ide_disk:1; unsigned probe_cdrom:1; unsigned probe_dos_disk:1; unsigned write_disabled_written_once:1; } __attribute__ ((packed)) attrib; struct autoload_str { unsigned char last_loaded; unsigned char total_loadable; unsigned char init_page; unsigned char total_page; } __attribute__ ((packed)) autoload; unsigned char timeout_autoload; unsigned char kbdmap; signed char time_hour_offset, time_minute_offset; unsigned reserved2[4]; char extra_cmdline[64]; unsigned char cardname[32]; unsigned char VGA_valid_mode[16]; struct vga_mode_str { unsigned isgraphic:1; unsigned reserved:1; unsigned number:7; unsigned bpp:4; unsigned height:11; unsigned width_div8:8; } __attribute__ ((packed)) vga_mode[30]; unsigned short partial_checksum __attribute__ ((aligned (2))); } __attribute__ ((packed)) gujin_param_t; void __ERROR (void); extern char memory[]; extern inline void _memcpy (void *dst, const void *src, unsigned size) { asm (" cld # _memcpy modify %3 \n" " rep movsb %%ds:(%%esi),%%es:(%%edi) \n": "+c" (size), "+D" (dst), "+S" (src), "=m" (*memory): "m" (*memory):"cc", "memory"); } extern inline int _memeql (const void *s1, const void *s2, unsigned nb) { asm ("cld; repe cmpsb %%es:(%%edi),%%ds:(%%esi) ": "+c" (nb), "+S" (s1), "+D" (s2):"m" (*memory)); return !nb; } extern inline const char * _strnchr (const char *str, char c, unsigned size) { asm ("cld ; repne scasb %%es:(%%edi),%%al": "+c" (size), "+D" (str): "a" (c), "X" (*str):"cc"); return str - 1; } extern inline int hexval (char c) { extern const char *const itoa_array; extern const unsigned itoa_len; const char *ptr = _strnchr (itoa_array, c, itoa_len); if (*ptr == c) return (ptr - itoa_array) & 0x0F; return -1; } extern inline void * memcpy (void *dst, const void *src, const unsigned size) { if (__builtin_constant_p (size)) { if (size == 1) { ((unsigned char *) dst)[0] = ((const unsigned char *) src)[0]; return dst; } else if (size == 2) { ((unsigned short *) dst)[0] = ((const unsigned short *) src)[0]; return dst; } else if (size == 3) { ((unsigned short *) dst)[0] = ((const unsigned short *) src)[0]; ((unsigned char *) dst)[2] = ((const unsigned char *) src)[2]; return dst; } else if (size == 4) { ((unsigned *) dst)[0] = ((const unsigned *) src)[0]; return dst; } else if (size == 5) { ((unsigned *) dst)[0] = ((const unsigned *) src)[0]; ((unsigned char *) dst)[4] = ((const unsigned char *) src)[4]; return dst; } else if (size == 6) { ((unsigned *) dst)[0] = ((const unsigned *) src)[0]; ((unsigned short *) dst)[2] = ((const unsigned short *) src)[2]; return dst; } else if (size == 8) { ((unsigned *) dst)[0] = ((const unsigned *) src)[0]; ((unsigned *) dst)[1] = ((const unsigned *) src)[1]; return dst; } } _memcpy (dst, src, size); return dst; } extern inline unsigned memeql (const void *dst, const void *src, const unsigned size) { if (__builtin_constant_p (size)) { if (size == 0) { __ERROR (); } else if (size == 1) { return ((const unsigned char *) dst)[0] == ((const unsigned char *) src)[0]; } else if (size == 2) { return ((const unsigned short *) dst)[0] == ((const unsigned short *) src)[0]; } else if (size == 3) { return ((((const unsigned *) dst)[0] ^ ((const unsigned *) src)[0]) & 0x00FFFFFF) == 0; } else if (size == 4) { return ((const unsigned *) dst)[0] == ((const unsigned *) src)[0]; } else if (size == 5) { return ((const unsigned *) dst)[0] == ((const unsigned *) src)[0] && ((const unsigned char *) dst)[4] == ((const unsigned char *) src)[4]; } else if (size == 6) { return ((const unsigned *) dst)[0] == ((const unsigned *) src)[0] && ((const unsigned short *) dst)[2] == ((const unsigned short *) src)[2]; } else if (size == 7) { return ((const unsigned *) dst)[0] == ((const unsigned *) src)[0] && ((((const unsigned *) dst)[1] ^ ((const unsigned *) src)[1]) & 0x00FFFFFF) == 0; } else if (size == 8) { return ((const unsigned *) dst)[0] == ((const unsigned *) src)[0] && ((const unsigned *) dst)[1] == ((const unsigned *) src)[1]; } } return _memeql (dst, src, size); } extern inline int memcmp (const void *s1, const void *s2, unsigned nb) { return __builtin_memcmp (s1, s2, nb); } extern inline unsigned strlen (const char *str) { return _strnchr (str, '\0', (~0)) - str; } extern inline void _strncpy (char *dst, const char *src, unsigned nb) { unsigned len = strlen (src); if (len > nb) len = nb; memcpy (dst, src, len); dst[len] = '\0'; } extern inline char * strncpy (char *dst, const char *src, unsigned nb) { _strncpy (dst, src, nb); return dst; } extern inline char * strcpy (char *dst, const char *src) { return strncpy (dst, src, (~0)); } extern inline char * strcat (char *dst, const char *src) { strcpy (dst + strlen (dst), src); return dst; } extern inline void strlwr (char *str) { if (!str) return; while (*str) { if (*str >= 'A' && *str <= 'Z') *str += 'a' - 'A'; str++; } } typedef unsigned farptr; typedef struct { unsigned short extended_fct:1; unsigned short removable:1; unsigned short enhanced:1; unsigned short reserved:13; } __attribute__ ((packed)) ebios_bitmap_t; struct config_multiword_dma_s { unsigned short mode0:1; unsigned short mode1:1; unsigned short mode2:1; unsigned short reserved:13; } __attribute__ ((packed)); struct config_ultra_dma_s { unsigned short mode0:1; unsigned short mode1:1; unsigned short mode2:1; unsigned short mode3:1; unsigned short mode4:1; unsigned short mode5:1; unsigned short reserved:10; } __attribute__ ((packed)); struct config_feature_s { unsigned short smart_feature:1; unsigned short smart_selftest:1; unsigned short smart_errorlog:1; unsigned short security:1; unsigned short standby_powerup:1; unsigned short RW_DMA_queued:1; unsigned short acoustic:1; unsigned short host_prot_area:1; unsigned short lba48:1; unsigned short reserved:7; } __attribute__ ((packed)); enum IDE_security_enum { IDE_security_unlock_user = 0, IDE_security_unlock_master = 1, IDE_security_set_pw_user = 2, IDE_security_set_pw_master = 3, IDE_security_disable_user = 4, IDE_security_disable_master = 5, IDE_security_erase_user = 6, IDE_security_erase_master = 7, }; enum sector_type_enum { all_sector_type = 0, CD_DA_sector_type = 1, mode_1_sector_type = 2, mode_2_formless_sector_type = 3, mode_2_form_1_sector_type = 4, mode_2_form_2_sector_type = 5 }; struct diskparam_str; extern struct disk_interface_str { unsigned nbdisk; unsigned char max_disk, max_partition, max_freelist, max_IDE_found; unsigned short sizeof_diskparam_str, sizeof_partition_str; unsigned short sizeof_freelist_str, sizeof_IDE_found_str; unsigned char nb_bios_fd, nb_bios_hd, cannot_reset_floppy, nb_bios_blacklist; unsigned char bios_blacklist[4]; unsigned reserved1[2]; unsigned char (*readsector) (struct diskparam_str * dp, int partition, unsigned long long lba, unsigned number, farptr buffer); unsigned char (*writesector) (struct diskparam_str * dp, int partition, unsigned long long lba, unsigned number, farptr buffer); int (*ideSecurity) (struct diskparam_str * dp, char password[32], enum IDE_security_enum action); unsigned long long last_lba_read_or_write; struct diskparam_str { enum { bios_chs, ebios_lba, hardide_chs, hardide_lba, hardide_lba48, hardide_atapi, dos_part } access:8; unsigned char disknb; unsigned char biostype; unsigned char drivetype; unsigned char diskname[32]; struct ide_attribute_str { unsigned smart:1; unsigned host_protected_area:1; unsigned security:1; unsigned lba48:1; unsigned removable:1; unsigned SAORAB:1; unsigned config_overlay:1; unsigned reserved:25; } ide_attribute; struct error_log_str { unsigned read_media:1; unsigned write_media:1; unsigned access_over_disk_tryed:1; unsigned access_over_partition_tryed:1; unsigned no_ebios_fct:1; unsigned ebios_size_zero:1; unsigned chs_bios_part_mismatch:1; unsigned chs_ajusted_bootsect:1; unsigned diskheader_ignored:1; unsigned disk_locked:1; unsigned disk_was_pw_locked:1; unsigned SMART_disabled:1; unsigned SMART_failure:1; unsigned analyse_partition_failed:1; unsigned NB_PARTITION_exceded:1; unsigned partition_overlap:1; unsigned partition_over_limit:1; unsigned beer_checksum_error:1; unsigned beer_in_extended_partition:1; unsigned read_media_retried:1; unsigned ideReadConfig_failed:1; unsigned reserved:11; } error_log; unsigned short bytepersector; unsigned short nbhead; unsigned nbcylinder; unsigned BEER_size; unsigned long long BEER_sector; unsigned long long BEER_HostProtectedArea_start; unsigned long long BEER_ReservedAreaBootCodeAddress; unsigned long long BEER_disksize; signed long long fulldisk_offset; unsigned long long fulldisk_size; unsigned long long nbtotalsector; unsigned long long config_max_lba; unsigned short nbsectorpertrack; unsigned short infobit; unsigned char ebios_version; unsigned char ebios_extension; ebios_bitmap_t ebios_bitmap; unsigned short reserved3; unsigned short reserved4; unsigned short ide_master_password_revision; unsigned short ideIOadr; unsigned short ideIOctrladr; unsigned char lba_slave_mask; unsigned char irq; unsigned char multiplemode; unsigned char BEER_device_index; struct config_multiword_dma_s initial_multiDMA, maximum_multiDMA; struct config_ultra_dma_s initial_ultraDMA, maximum_ultraDMA; struct config_feature_s initial_feature, maximum_feature; unsigned CalibrationIdeloop; unsigned short bios_nbcylinder; unsigned char bios_nbhead; unsigned char bios_nbsectorpertrack; unsigned char bootable; unsigned char OSdisknumber; unsigned short nbpartition; unsigned short nbOSnumber; unsigned short reserved5; unsigned first_ext_partition_start; struct partition_str { unsigned long long start, length; unsigned char type, OSnumber; struct partition_misc_str { unsigned char order:6; unsigned char fsanalyse_toobig:1; unsigned char fsanalyse_error:1; unsigned char maybe_root:1; unsigned char fat_bootable:1; unsigned char beer_partition:1; unsigned char swap_partition:1; unsigned char reserved:2; enum part_state { part_invalid = 0, part_active, part_inactive, part_extended } active:2; } __attribute__ ((packed)) misc; unsigned char name[(64 - 20 - 4)]; } __attribute__ ((packed)) * partition; unsigned nbfreelist; struct freelist_str { unsigned long long start, length; } *freelist; char set_max_password[32]; } *param; unsigned nb_IDE_found; struct IDE_found_str { unsigned short ideIOadr; unsigned short ideIOctrladr; unsigned char irq; unsigned char bios_order; unsigned short reserved; } *IDE_found; } DI; extern struct BOOTWAY_str { unsigned short nb, nb_initrd, sizeof_desc_str, nb_bdi; unsigned char max_name_length, max_desc_array; struct desc_str { unsigned inode; unsigned filesize; unsigned char disk; unsigned char partition; unsigned char name_offset; enum curdir_e { inRoot = 0, inSlashBoot, inSlashImage } curdir:3; enum boottype_e { is_MBR, is_PBR, is_kernel_with_header, is_kernel_without_header, is_initrd, is_bdi_file, is_el_torito, is_initramfs, is_multiboot } boottype:4; unsigned char unused:1; char filename[52]; } __attribute__ ((packed)) * desc; } BOOTWAY; void *malloc (unsigned size); char getScanPath (unsigned); struct sector_chain_str { unsigned lba; unsigned nb; }; struct treat_directory_str { unsigned nb; struct desc_str *array; enum curdir_e curdir; struct gujin_param_attrib gujin_attr; union filesystem_union { struct common_filesystem { unsigned disk, part; unsigned sector_per_block; unsigned byte_per_block; unsigned first_data_block; unsigned blocks_count; unsigned inodes_count; struct { unsigned inode, size; } slash, slashboot; int (*treatdir) (void *, unsigned char *, unsigned); struct sector_chain_str *(*get_sector_chain) (union filesystem_union * fs, struct sector_chain_str ** sector_chain_buffer_ptr); } common; struct { struct common_filesystem common; unsigned start_fat; unsigned fat_size; unsigned start_dir; unsigned short nb_fat; unsigned short fatbit; struct { char name[256]; unsigned char sequence; unsigned char chksum; } lfn; } fat; struct { struct common_filesystem common; unsigned inode_size; unsigned inodes_per_group; } e2fs; struct { struct common_filesystem common; unsigned volume_sequence_number; unsigned boot_catalog_lba; } iso; } filesystem; }; const char *const filename_array[] = { "initrd", "initra", "vmlinuz", "bzImage", "zImage", }; typedef union { union { struct { unsigned char xl, xh; } __attribute__ ((packed)) b; unsigned short xw; } __attribute__ ((packed)) w; unsigned xl; } __attribute__ ((packed)) Qreg; struct DOS_attribute_str { unsigned short read_only:1; unsigned short hidden:1; unsigned short system:1; unsigned short volume_label:1; unsigned short directory:1; unsigned short archive:1; unsigned short reserved:10; } __attribute__ ((packed)); struct file_attr_str { unsigned char readonly:1; unsigned char hidden:1; unsigned char system:1; unsigned char volumelabel:1; unsigned char subdirectory:1; unsigned char archive:1; unsigned char unused:2; } __attribute__ ((packed)) attributes; struct DOS_DTA_str { unsigned char OSdepend[0x15]; struct file_attr_str attribute; unsigned short time; unsigned short date; unsigned size; char name_ext[13]; } __attribute__ ((packed)); extern inline void DOS_SetDTA (struct DOS_DTA_str *dta_atr) { Qreg ax, dx; ax.w.b.xh = 0x1A; dx.w.xw = (unsigned short) (unsigned) dta_atr; asm volatile (" int $0x21 # DOS_SetDTA "::"a" (ax), "d" (dx)); } extern inline unsigned char DOS_FindFirst (const char *pattern, struct DOS_attribute_str attribute, unsigned short *errorcode) { unsigned char carry; Qreg ax; ax.w.b.xh = 0x4E; ax.w.b.xl = 1; asm volatile (" int $0x21 # DOS_FindFirst \n" " setc %0 \n":"=qm" (carry), "=a" (*errorcode):"a" (ax), "c" (attribute), "d" (pattern), "X" (*pattern):"memory", "cc"); return carry; } extern inline unsigned char DOS_FindNext (unsigned short *errorcode) { unsigned char carry; Qreg ax; ax.w.b.xh = 0x4F; asm volatile (" int $0x21 # DOS_FindNext \n" " setc %0 \n":"=qm" (carry), "=a" (*errorcode):"a" (ax):"memory", "cc"); return carry; } __attribute__ ((section (".xcode.DOS_analyse"))) void DOS_analyse (struct treat_directory_str *opaque) { unsigned short i, error; char pattern[52] = "A:\\*.*"; struct DOS_DTA_str DosDta; const struct DOS_attribute_str attr_allowable = { .read_only = 1,.hidden = 1,.system = 1, .volume_label = 0,.directory = 0,.archive = 1 }; DOS_SetDTA (&DosDta); { const struct DOS_attribute_str vol_label = { .read_only = 0,.hidden = 0,.system = 0, .volume_label = 1,.directory = 0,.archive = 0 }; ; pattern[0] = DI.param[opaque->filesystem.common.disk].disknb; DosDta.name_ext[0] = 0; if (DOS_FindFirst (pattern, vol_label, &error) == 0) { char *name_ext = DosDta.name_ext; DI.param[opaque->filesystem.common.disk].partition = malloc ((64 - 20 - 4) + 1); if (DI.param[opaque->filesystem.common.disk].partition != 0) { strncpy ((char *) DI.param[opaque->filesystem.common.disk]. partition, name_ext, (64 - 20 - 4)); ; } else; } else { DI.param[opaque->filesystem.common.disk].partition = 0; } } for (i = 0; i < 2 * ((sizeof (filename_array) / sizeof (filename_array[0])) + 1); i++) { char *pat = pattern; *pat++ = DI.param[opaque->filesystem.common.disk].disknb; *pat++ = ':'; *pat++ = '\\'; if (i & 1) { unsigned cpt = 0; if (!opaque->gujin_attr.search_subdir_kernel) continue; while ((*pat = getScanPath (cpt++)) != 0) pat++; *pat++ = '\\'; opaque->curdir = inSlashBoot; } else { if (!opaque->gujin_attr.search_topdir_kernel) continue; opaque->curdir = inRoot; } if ((i >> 1) == (sizeof (filename_array) / sizeof (filename_array[0]))) { ( { memcpy (pat, "*", sizeof ("*")); pat + sizeof ("*") - 1; } ); ( { memcpy (&pat[1], ".kgz", sizeof (".kgz")); &pat[1] + sizeof (".kgz") - 1; } ); } else { strcpy (pat, filename_array[i >> 1]); strcat (pat, "*.*"); } DosDta.name_ext[0] = 0; if (DOS_FindFirst (pattern, attr_allowable, &error) != 0) ; else { for (;;) { unsigned filesize; char *filename; struct desc_str *elem = &opaque->array[opaque->nb]; { filesize = DosDta.size; filename = DosDta.name_ext; } if (opaque->nb >= 100) { return; } elem->filesize = filesize; elem->curdir = (i & 1) ? inRoot : inSlashBoot; if ((unsigned) (i >> 1) == 0) elem->boottype = is_initrd; else if ((unsigned) (i >> 1) == 1) elem->boottype = is_initramfs; else elem->boottype = is_kernel_with_header; if ((i >> 1) == (sizeof (filename_array) / sizeof (filename_array[0]))) { elem->boottype = is_kernel_without_header; elem->name_offset = 0; while (filename[elem->name_offset] != '\0' && filename[elem->name_offset] != '-' && filename[elem->name_offset] != '+') elem->name_offset++; if (filename[elem->name_offset] != '-') elem->name_offset = 0; } else elem->name_offset = strlen (filename_array[i >> 1]); { char *ptr = elem->filename; elem->disk = opaque->filesystem.common.disk; elem->partition = opaque->filesystem.common.part; elem->curdir = opaque->curdir; if (opaque->curdir == inSlashBoot) { unsigned cpt = 0; *ptr++ = '/'; while ((*ptr = getScanPath (cpt++)) != 0) ptr++; *ptr++ = '/'; elem->name_offset += cpt + 2; } else { *ptr++ = '/'; elem->name_offset++; } strncpy (ptr, filename, sizeof (elem->filename) - 1 - (ptr - elem->filename)); strlwr (ptr); } opaque->nb++; if (DOS_FindNext (&error)) { break; } } } } }
*** This bug has been marked as a duplicate of 36902 ***
This is probably not fixed by the patch to PR 36902. They are totally different problems.
A reduced testcase: extern inline const char * _strnchr (const char *str, char c, unsigned size); extern inline void * _memcpy (void *dst, const void *src, const unsigned size) { if (__builtin_constant_p (size)) { if (size == 5) { ((unsigned *) dst)[0] = ((const unsigned *) src)[0]; ((unsigned char *) dst)[4] = ((const unsigned char *) src)[4]; return dst; } } return dst; } extern inline unsigned _strlen (const char *str) { return _strnchr (str, '\0', (~0)) - str; } extern inline char * _strncpy (char *dst, const char *src, unsigned size) { unsigned len = _strlen (src); if (len > size) len = size; _memcpy (dst, src, len); dst[len] = '\0'; return dst; } extern inline char * _strcpy (char *dst, const char *src) { return _strncpy (dst, src, (~0)); } extern inline char * _strcat (char *dst, const char *src) { _strcpy (dst + _strlen (dst), src); return dst; } struct treat_directory_str { unsigned nb; }; void DOS_analyse (struct treat_directory_str *opaque) { char pattern[52] = "A:\\*.*"; char *pat = pattern; _strcat (pat, "*.*"); opaque->nb++; } It is weird that removing the last line of DOS_analyse silences the warning.
Confirmed.
GCC 4.8.0 revision 196254 does not warn for the reduced testcase on i686-pc-linux-gnu. It also doesn't warn for the original testcase once the spurious linebreak inside the asm string on line 88 (probably an artifact of the web page formatting) is removed).
Thus, fixed for 4.8.