This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]