[PATCH fixincludes] AIX stdio inclhack - fixes PR20366

Peter O'Gorman gcc-patches@mlists.thewrittenword.com
Mon Mar 3 20:34:00 GMT 2008


Hi,

On AIX systems, if _LARGE_FILES is defined then 64 bit file operations
are the default. This is, unfortunately, accomplished by #defines in
stdio.h.

Autoconf has a macro AC_SYS_LARGEFILE,
(http://www.gnu.org/software/autoconf/manual/autoconf.html#System-Services)
which is meant to enable support for large files. On AIX systems it
defines _LARGE_FILES.

It works well for xlc and for gcc, again, unfortunately, g++ fails to
compile even a very simple test case with -D_LARGE_FILES because
cstdio has #undefs for most of the functions declared in stdio.h. This
means that after preprocessing the compiler sees a declaration for,
e.g. fopen64, but not fopen, and then it sees 'using ::fopen;' and
rightly errors out.

This patch uses the fixincludes machinery to modify stdio.h so that,
if __GNUG__, _LARGE_FILES, and __cplusplus are defined it undefs the
fopen etc and uses __asm__ to alias the symbols instead.

The test case simply tests that the  prototypes from including
<cstdio> with -D_LARGE_FILES match what we would get with the #define
in the original headers.

Note that although the generated fixincl.x is included in this patch,
the committer may want/need to use a later version of autogen to get
the gplv3 version.

We do not have write access to the gcc repository, so would be
grateful if someone could apply this for us if approved.

Thank you,
Peter
-------------- next part --------------
fixincludes/ChangeLog

2008-??-??  Peter O'Gorman  <pogma@thewrittenword.com>

	PR c++/20366
	* inclhack.def (AAB_aix_stdio): Hack stdio.h for -D_LARGE_FILES.
	* fixincl.x: Regenerate.
	* tests/base/stdio.h: Add test.

gcc/testsuite/ChangeLog

2008-??-??  Peter O'Gorman  <pogma@thewrittenword.com>

	PR c++/20366
	* g++.dg/other/pr20366.C: New test.

Index: gcc/testsuite/g++.dg/other/pr20366.C
===================================================================
--- gcc/testsuite/g++.dg/other/pr20366.C	(revision 0)
+++ gcc/testsuite/g++.dg/other/pr20366.C	(revision 0)
@@ -0,0 +1,80 @@
+// Test fix for PR20366
+// 
+// { dg-do compile  { target *-*-aix* } }
+// { dg-options "-D_LARGE_FILES" }
+//
+// cstdio includes stdio.h and undefs most of the functions declared
+// therein, unfortunately this means that #define fopen fopen64 goes
+// away. This tests the fix, and ensures that with -D_LARGE_FILES
+// fopen et. al. are indeed aliased to the large file equivalents.
+//
+// There are many other #define foo foo64 in the AIX headers, but
+// these all work out fine as they are not undefined in libstdc++.
+// This list is probably incomplete:
+//
+// Symbol          Return type     Large file declaration.
+// 
+// aio.h                      (different for different AIX versions)
+// =====
+// aio_read        int        aio_read64(int, struct aiocb64 *);
+// aio_write       int        aio_write64(int, struct aiocb64 *);
+// lio_listio      int        lio_listio64(int, struct liocb64 *[], int, void *);
+// aio_cancel      int        aio_cancel64(int, struct aiocb64 *);
+// aio_suspend     int        aio_suspend64(int, struct aiocb64 *[]);
+// 
+// stdio.h
+// =======
+// fgetpos         int        fgetpos64(FILE *, fpos64_t *);
+// fopen           FILE      *fopen64(const char *, const char *);
+// freopen         FILE      *freopen64(const char *, const char *, FILE *);
+// fseeko          int        fseeko64(FILE *, off64_t, int);
+// fsetpos         int        fsetpos64(FILE *, const fpos64_t *);
+// ftello          off64_t    ftello64(FILE *);
+// 
+// unistd.h
+// ========
+// fclear          off64_t    fclear64(int, off64_t);
+// fsync_range     int        fsync_range64(int, int, off64_t, off64_t);
+// ftruncate       int        ftruncate64(int, off64_t);
+// truncate        int        truncate64(const char *, off64_t);
+// lseek           off64_t    lseek64(int, off64_t, int);
+// pread           ssize_t    pread64(int, void *, size_t, off64_t);
+// pwrite          ssize_t    pwrite64(int, const void *, size_t, off64_t);
+// 
+// fcntl.h
+// =======
+// open            int        open64(const char *, int, ...);
+// creat           int        creat64(const char *, mode_t);
+// 
+// sys/stat.h
+// ==========
+// stat            int        stat64(const char *, struct stat64 *);
+// fstat           int        fstat64(int, struct stat64 *);
+// lstat           int        lstat64(const char *, struct stat64 *);
+// 
+// stdlib.h
+// ========
+// mkstemp         int        mkstemp64(char *);
+// 
+// ftw.h
+// =====
+// ftw             int        ftw64(const char *, int (*)(const char *,const struct stat64 *, int), int);
+// nftw            int        nftw64(const char *, int (*)(const char *, const struct stat64 *, int, struct FTW*), int, int);
+//
+// It seems unlikely that any of these will be used (and #undef'ed) by
+// libstdc++ in the future, if they are then this test and its
+// associated patch to fixincludes will have to be revisited.
+
+#include <cstdio>
+
+extern "C" {
+int        fgetpos(FILE *, fpos64_t *);
+FILE      *fopen(const char *, const char *);
+FILE      *freopen(const char *, const char *, FILE *);
+int        fseeko(FILE *, off64_t, int);
+int        fsetpos(FILE *, const fpos64_t *);
+off64_t    ftello(FILE *);
+}
+int main() { 
+  return 0;
+}
Index: fixincludes/fixincl.x
===================================================================
--- fixincludes/fixincl.x	(revision 132770)
+++ fixincludes/fixincl.x	(working copy)
@@ -2,11 +2,11 @@
  * 
  * DO NOT EDIT THIS FILE   (fixincl.x)
  * 
- * It has been AutoGen-ed  Wednesday February 20, 2008 at 05:10:00 AM CET
+ * It has been AutoGen-ed  Friday February 29, 2008 at 10:51:30 AM CST
  * From the definitions    inclhack.def
  * and the template file   fixincl
  */
-/* DO NOT SVN-MERGE THIS FILE, EITHER Wed Feb 20 05:10:00 CET 2008
+/* DO NOT SVN-MERGE THIS FILE, EITHER Fri Feb 29 10:51:30 CST 2008
  *
  * You must regenerate it.  Use the ./genfixes script.
  *
@@ -15,7 +15,7 @@
  * certain ANSI-incompatible system header files which are fixed to work
  * correctly with ANSI C and placed in a directory that GNU C will search.
  *
- * This file contains 212 fixup descriptions.
+ * This file contains 213 fixup descriptions.
  *
  * See README for more information.
  *
@@ -43,6 +43,64 @@
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * *
  *
+ *  Description of Aab_Aix_Stdio fix
+ */
+tSCC zAab_Aix_StdioName[] =
+     "AAB_aix_stdio";
+
+/*
+ *  File name selection pattern
+ */
+tSCC zAab_Aix_StdioList[] =
+  "stdio.h\0";
+/*
+ *  Machine/OS name selection pattern
+ */
+tSCC* apzAab_Aix_StdioMachs[] = {
+        "*-*-aix*",
+        (const char*)NULL };
+
+/*
+ *  content selection pattern - do fix if pattern found
+ */
+tSCC zAab_Aix_StdioSelect0[] =
+       "define fopen fopen64";
+
+#define    AAB_AIX_STDIO_TEST_CT  1
+static tTestDesc aAab_Aix_StdioTests[] = {
+  { TT_EGREP,    zAab_Aix_StdioSelect0, (regex_t*)NULL }, };
+
+/*
+ *  Fix Command Arguments for Aab_Aix_Stdio
+ */
+static const char* apzAab_Aix_StdioPatch[] = {
+    "wrap",
+    "",
+    "\n\
+#if defined __GNUG__ && defined _LARGE_FILES && defined __cplusplus\n\
+#define __need__aix_stdio_h_fix\n\
+#ifdef __need__aix_stdio_h_fix\n\
+#undef fseeko\n\
+#undef ftello\n\
+#undef fgetpos\n\
+#undef fsetpos\n\
+#undef fopen\n\
+#undef freopen\n\
+/* Alias the symbols using asm */\n\
+extern \"C\" {\n\
+extern int fgetpos(FILE *, fpos64_t *) __asm__(\"fgetpos64\");\n\
+extern FILE *fopen(const char *, const char *) __asm__(\"fopen64\");\n\
+extern FILE *freopen(const char *, const char *, FILE *) __asm__(\"freopen64\");\n\
+extern int fseeko(FILE *, off64_t, int) __asm__(\"fseeko64\");\n\
+extern int fsetpos(FILE *, const fpos64_t *) __asm__(\"fsetpos64\");\n\
+extern off64_t ftello(FILE *) __asm__(\"ftello64\");\n\
+}\n\
+#endif\n\
+#endif\n",
+    (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
  *  Description of Aab_Darwin7_9_Long_Double_Funcs fix
  */
 tSCC zAab_Darwin7_9_Long_Double_FuncsName[] =
@@ -8611,14 +8669,15 @@
  *
  *  List of all fixes
  */
-#define REGEX_COUNT          255
+#define REGEX_COUNT          256
 #define MACH_LIST_SIZE_LIMIT 261
-#define FIX_COUNT            212
+#define FIX_COUNT            213
 
 /*
  *  Enumerate the fixes
  */
 typedef enum {
+    AAB_AIX_STDIO_FIXIDX,
     AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_FIXIDX,
     AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_2_FIXIDX,
     AAB_FD_ZERO_ASM_POSIX_TYPES_H_FIXIDX,
@@ -8834,6 +8893,11 @@
 } t_fixinc_idx;
 
 tFixDesc fixDescList[ FIX_COUNT ] = {
+  {  zAab_Aix_StdioName,    zAab_Aix_StdioList,
+     apzAab_Aix_StdioMachs,
+     AAB_AIX_STDIO_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+     aAab_Aix_StdioTests,   apzAab_Aix_StdioPatch, 0 },
+
   {  zAab_Darwin7_9_Long_Double_FuncsName,    zAab_Darwin7_9_Long_Double_FuncsList,
      apzAab_Darwin7_9_Long_Double_FuncsMachs,
      AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
Index: fixincludes/tests/base/stdio.h
===================================================================
--- fixincludes/tests/base/stdio.h	(revision 132770)
+++ fixincludes/tests/base/stdio.h	(working copy)
@@ -14,6 +14,11 @@
 #include <stdarg.h>
 
 
+#if defined( AAB_AIX_STDIO_CHECK )
+
+#endif  /* AAB_AIX_STDIO_CHECK */
+
+
 #if defined( ALPHA_GETOPT_CHECK )
 extern int getopt(int, char *const[], const char *);
 #endif  /* ALPHA_GETOPT_CHECK */
Index: fixincludes/inclhack.def
===================================================================
--- fixincludes/inclhack.def	(revision 132770)
+++ fixincludes/inclhack.def	(working copy)
@@ -20,7 +20,48 @@
 FIXINC_DEBUG = yes;
 #endif
 
+/* On AIX when _LARGE_FILES is defined stdio.h defines fopen to
+ * fopen64 etc. and this causes problems when building with g++
+ * because cstdio udefs everything from stdio.h, leaving us with
+ * ::fopen has not been declared errors. This fixes stdio.h to
+ * undef those defines and use __asm__ to alias the symbols if
+ * building with g++ and -D_LARGE_FILES
+ */
+fix = {
+	hackname  = AAB_aix_stdio;
+	files     = stdio.h;
+	select    = "define fopen fopen64";
+	mach      = "*-*-aix*";
 
+	c_fix	  = wrap;
+
+	c_fix_arg = "";
+
+	c_fix_arg = "\n" 
+	"#if defined __GNUG__ && defined _LARGE_FILES && defined __cplusplus\n"
+	"#define __need__aix_stdio_h_fix\n"
+	"#ifdef __need__aix_stdio_h_fix\n"
+	"#undef fseeko\n"
+	"#undef ftello\n"
+	"#undef fgetpos\n"
+	"#undef fsetpos\n"
+	"#undef fopen\n"
+	"#undef freopen\n"
+	"/* Alias the symbols using asm */\n"
+	"extern \"C\" {\n"
+	"extern int fgetpos(FILE *, fpos64_t *) __asm__(\"fgetpos64\");\n"
+	"extern FILE *fopen(const char *, const char *) __asm__(\"fopen64\");\n"
+	"extern FILE *freopen(const char *, const char *, FILE *) __asm__(\"freopen64\");\n"
+	"extern int fseeko(FILE *, off64_t, int) __asm__(\"fseeko64\");\n"
+	"extern int fsetpos(FILE *, const fpos64_t *) __asm__(\"fsetpos64\");\n"
+	"extern off64_t ftello(FILE *) __asm__(\"ftello64\");\n"
+	"}\n"
+	"#endif\n"
+	"#endif\n";
+	test_text = "";
+};
+
+
 /*
  *  On Mac OS 10.3.9, the 'long double' functions are available in
  *  libSystem, but are not prototyped in math.h.


More information about the Gcc-patches mailing list