This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix 64-bit *intmax_t definitions on IRIX
- From: Rainer Orth <ro at CeBiTec dot Uni-Bielefeld dot DE>
- To: gcc-patches at gcc dot gnu dot org
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>, Richard Sandiford <rdsandiford at googlemail dot com>
- Date: Thu, 01 Mar 2012 19:53:32 +0100
- Subject: Fix 64-bit *intmax_t definitions on IRIX
The 64-bit gcc.dg/intmax_t-1.c was failing on IRIX 6.5:
FAIL: gcc.dg/intmax_t-1.c (test for excess errors)
Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/gcc.dg/intmax_t-1.c:19:10: warning: assignment from incompatible pointer type [enabled by default]
/vol/gcc/src/hg/trunk/local/gcc/testsuite/gcc.dg/intmax_t-1.c:25:11: warning: assignment from incompatible pointer type [enabled by default]
There's an inconsistency between iris6.h
#define INTMAX_TYPE "long long int"
#define UINTMAX_TYPE "long long unsigned int"
and <inttypes.h>: it has
typedef __int64_t intmax_t;
typedef __uint64_t uintmax_t;
with <sgidefs.h>:
#if (_MIPS_SZLONG == 64)
typedef long __int64_t;
typedef unsigned long __uint64_t;
#else
#if defined(_LONGLONG)
/* Its alright to use long long in definitions */
typedef long long __int64_t;
typedef unsigned long long __uint64_t;
OTOH, for the C99 case, <stdint.h> has
typedef signed long long intmax_t;
typedef unsigned long long uintmax_t;
for both 32 and 64-bit.
Resolving this turned out to be messy: since INTMAX_TYPE is used outside
the C frontent (fortran/iso-c-binding.def), I cannot check flag_isoc99
directly. Instead, I introduce a tri-state long_intmax variable and set
it in SUBTARGET_OVERRIDE_OPTIONS (always) or C_COMMON_OVERRIDE_OPTIONS
(for C-family languages). Since C_COMMON_OVERRIDE_OPTIONS is called
after TARGET_OPTION_OVERRIDE, I need to be careful not to undo the
effect of the former. As an additional complication, I cannot use
LONG_TYPE_SIZE since that (resp. TARGET_LONG64) is only set in
mips_option_override long after after C_COMMON_OVERRIDE_OPTIONS and also
after SUBTARGET_OVERRIDE_OPTIONS. I'm checking mips_abi instead, which
is set early by the option processing machinery.
With this patch, the three affected testcases
gcc.dg/c99-stdint-5.c
gcc.dg/c99-stdint-6.c
gcc.dg/intmax_t-1.c
all pass for both 32 and 64-bit, and f951 does link.
Since a complete bootstrap/test cycle takes 36 hours, I'll include the
patch in this weekend's bootstrap. Ok for mainline if that passes?
Thanks.
Rainer
2012-02-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config/mips/iris6.h [!USED_FOR_TARGET] (long_intmax): Declare.
(INTMAX_TYPE): Use it.
(UINTMAX_TYPE): Likewise.
(SUBTARGET_OVERRIDE_OPTIONS): Define.
(irix6_c_common_override_options): Declare.
(C_COMMON_OVERRIDE_OPTIONS): Define.
* config/mips/mips.c [TARGET_IRIX6] (long_intmax): Define.
* config/mips/irix6-c.c: New file.
* config/mips/t-irix6 (irix6-c.o): New target.
* config.gcc (mips-sgi-irix6.5): Set c_target_objs,
cxx_target_objs.
# HG changeset patch
# Parent 203f32f0782387e4800848f2fd446b7ce909b384
Fix 64-bit *intmax_t definitions on IRIX
diff --git a/gcc/config.gcc b/gcc/config.gcc
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1707,6 +1707,8 @@ microblaze*-*-*)
mips-sgi-irix6.5*)
tm_file="elfos.h ${tm_file} mips/iris6.h"
tmake_file="mips/t-irix6 t-slibgcc"
+ c_target_objs="irix6-c.o"
+ cxx_target_objs="irix6-c.o"
extra_options="${extra_options} rpath.opt mips/iris6.opt"
target_cpu_default="MASK_ABICALLS"
tm_defines="${tm_defines} MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_N32"
diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h
--- a/gcc/config/mips/iris6.h
+++ b/gcc/config/mips/iris6.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler. IRIX 6.5 version.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -121,6 +121,11 @@ extern const char *host_detect_local_cpu
#undef WINT_TYPE_SIZE
#define WINT_TYPE_SIZE INT_TYPE_SIZE
+#ifndef USED_FOR_TARGET
+/* Use long for intmax_t, uintmax_t? */
+extern int long_intmax;
+#endif
+
/* C99 stdint.h types. */
#define INT8_TYPE "signed char"
#define INT16_TYPE "short int"
@@ -149,8 +154,8 @@ extern const char *host_detect_local_cpu
#define UINT_FAST32_TYPE "unsigned int"
#define UINT_FAST64_TYPE "long long unsigned int"
-#define INTMAX_TYPE "long long int"
-#define UINTMAX_TYPE "long long unsigned int"
+#define INTMAX_TYPE (long_intmax ? "long int" : "long long int")
+#define UINTMAX_TYPE (long_intmax ? "long unsigned int" : "long long unsigned int")
#define INTPTR_TYPE "long int"
#define UINTPTR_TYPE "long unsigned int"
@@ -206,6 +211,20 @@ extern const char *host_detect_local_cpu
} \
while (0)
+/* SUBTARGET_OVERRIDE_OPTIONS is run after C_COMMON_OVERRIDE_OPTIONS, so
+ only set long_intmax if uninitialized. */
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+ do \
+ { \
+ if (long_intmax == -1) \
+ long_intmax = mips_abi == ABI_64; \
+ } \
+ while (0)
+
+extern void irix6_c_common_override_options (void);
+#define C_COMMON_OVERRIDE_OPTIONS irix6_c_common_override_options()
+
#undef SUBTARGET_CC1_SPEC
#define SUBTARGET_CC1_SPEC "%{static: -mno-abicalls}"
diff --git a/gcc/config/mips/irix6-c.c b/gcc/config/mips/irix6-c.c
new file mode 100644
--- /dev/null
+++ b/gcc/config/mips/irix6-c.c
@@ -0,0 +1,38 @@
+/* IRIX 6 support needed only by C/C++ frontends.
+ Copyright (C) 2012 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tm.h"
+#include "c-family/c-common.h"
+
+/* For C99, intmax_t, uintmax_t are always long long int, otherwise the
+ type differs between 32-bit and 64-bit compilations. */
+void
+irix6_c_common_override_options (void)
+{
+ if (flag_isoc99 || c_dialect_cxx ())
+ long_intmax = 0;
+ else
+ /* Cannot use LONG_TYPE_SIZE == 64. LONG_TYPE_SIZE is only set in
+ mips_option_override after C_COMMON_OVERRIDE_OPTIONS. */
+ long_intmax = mips_abi == ABI_64;
+}
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -539,6 +539,12 @@ int mips_isa;
/* The architecture selected by -mipsN, or null if -mipsN wasn't used. */
static const struct mips_cpu_info *mips_isa_option_info;
+#if TARGET_IRIX6
+/* On IRIX 6, intmax_t and uintmax_t depend on __c99, which is only
+ available in C-family compilers. See irix6_c_common_override_options. */
+int long_intmax = -1;
+#endif
+
/* Which cost information to use. */
static const struct mips_rtx_cost_data *mips_cost;
diff --git a/gcc/config/mips/t-irix6 b/gcc/config/mips/t-irix6
--- a/gcc/config/mips/t-irix6
+++ b/gcc/config/mips/t-irix6
@@ -2,3 +2,7 @@ MULTILIB_OPTIONS=mabi=n32/mabi=64
MULTILIB_DIRNAMES=n32 64
MULTILIB_MATCHES=
MULTILIB_OSDIRNAMES=../lib32 ../lib64
+
+irix6-c.o: $(srcdir)/config/mips/irix6-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ tree.h $(TM_H) $(C_COMMON_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University