StdLib: Fix build errors caused by differences between the minGW 4.3 and GCC 4.4 compilers.

There are several significant differences between the mingw32 (gcc 4.3.0 based) compiler and the GCC 4.4 and later compilers.

Mingw32 requires that types int, long, long long, unsigned { int, long, long long}, float, and double be the only types passed to va_arg(). This requires the programmer to ensure that va_arg is called with type int for arguments of any type with a size less-than or equal-to int.  GCC 4.4 and later does not require this and performs the appropriate promotions for you.

Mingw32 uses 32-bit long in both ia32 and x64 mode.  GCC 4.4 makes long a 64-bit value when in x64 mode.

Signed-off-by: darylm503
Reviewed-by: jcarsey


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12258 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
darylm503 2011-09-01 21:56:45 +00:00
parent b2824a8e13
commit 5244f47e46
4 changed files with 58 additions and 25 deletions

View File

@ -3,22 +3,37 @@
#define __POINTER_BIT 64
#if defined(__GNUC__)
#define __LONG_BIT 64
/** minimum value for an object of type long int **/
#define __LONG_MIN (-9223372036854775807LL - 1LL) // -(2^63 - 1)
#if __GNUC_PREREQ__(4,4)
#define __LONG_BIT 64
/** maximum value for an object of type long int **/
#define __LONG_MAX +9223372036854775807LL // 2^63 - 1
/** minimum value for an object of type long int **/
#define __LONG_MIN (-9223372036854775807LL - 1LL) // -(2^63 - 2)
/** maximum value for an object of type unsigned long int **/
#define __ULONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1
/** maximum value for an object of type long int **/
#define __LONG_MAX (9223372036854775807LL) // 2^63 - 1
/** maximum value for an object of type unsigned long int **/
#define __ULONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1
#else
#define __LONG_BIT 32
/** minimum value for an object of type long int **/
#define __LONG_MIN (-2147483647L - 1L) // -(2^31 - 1)
/** maximum value for an object of type long int **/
#define __LONG_MAX 2147483647L // 2^31 - 1
/** maximum value for an object of type unsigned long int **/
#define __ULONG_MAX 0xffffffff // 2^32 - 1
#endif
#else /* NOT defined(__GNUC__) */
#define __LONG_BIT 32
/** minimum value for an object of type long int **/
#define __LONG_MIN (-2147483647L - 1L) // -(2^31 - 1)
/** maximum value for an object of type long int **/
#define __LONG_MAX +2147483647L // 2^31 - 1
#define __LONG_MAX 2147483647L // 2^31 - 1
/** maximum value for an object of type unsigned long int **/
#define __ULONG_MAX 0xffffffff // 2^32 - 1

View File

@ -1,11 +1,11 @@
/** @file
Machine dependent type definitions.
Portions Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License that accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@ -46,10 +46,6 @@
#include <sys/EfiCdefs.h>
#include <machine/int_types.h>
/* Handle the long and unsigned long data types which EFI doesn't directly support. */
//typedef long int LONGN; // 32-bit
//typedef long unsigned int ULONGN; // 32-bit
typedef PHYSICAL_ADDRESS paddr_t;
typedef UINT64 psize_t;
typedef PHYSICAL_ADDRESS vaddr_t;

View File

@ -102,6 +102,7 @@
//#define _EFI_WINT_MIN (0)
//#define _EFI_WINT_MAX (0xFFFF)
#define _EFI_PTRDIFF_T_ __PTRDIFF_TYPE__ /* ptr1 - ptr2 --- Must be same size as size_t */
#else
#define _EFI_SIZE_T_ UINTN /* sizeof() */
#define _EFI_WCHAR_T UINT16
@ -338,13 +339,29 @@ extern int _fltused; // VC++ requires this if you use floating point. KEEP f
#define _DIAGASSERT(e)
// Types used to replace long so that it will have constant length regardless of compiler.
typedef INT32 EFI_LONG_T; // Equivalent to long in VS200?
typedef UINT32 EFI_ULONG_T; // Equivalent to unsigned long in VS200?
typedef INTN LONGN;
typedef UINTN ULONGN;
typedef INT32 LONG32;
typedef INT32 LONG32;
typedef UINT32 ULONG32;
typedef INT64 LONG64;
typedef UINT64 ULONG64;
typedef INT32 EFI_LONG_T;
typedef UINT32 EFI_ULONG_T;
/* These types reflect the compiler's size for long */
#if defined(__GNUC__)
#if __GNUC_PREREQ__(4,4)
/* GCC 4.4 or later */
typedef INT64 LONGN;
typedef UINT64 ULONGN;
#else
/* minGW gcc variant */
typedef INT32 LONGN;
typedef UINT32 ULONGN;
#endif /* __GNUC_PREREQ__(4,4) */
#else /* NOT GCC */
/* Microsoft or Intel compilers */
typedef INT32 LONGN;
typedef UINT32 ULONGN;
#endif /* defined(__GNUC__) */
#endif /* _EFI_CDEFS_H */

View File

@ -1003,7 +1003,12 @@ reswitch: switch (ch) {
mbs = initial;
mbseqlen = wcrtomb(buf,
(wchar_t)GETARG(wint_t), &mbs);
/* The compiler "knows" that wint_t may be smaller than an int so
it warns about it when used as the type argument to va_arg().
Since any type of parameter smaller than an int is promoted to an int on a
function call, we must call GETARG with type int instead of wint_t.
*/
(wchar_t)GETARG(int), &mbs);
if (mbseqlen == (size_t)-1) {
fp->_flags |= __SERR;
goto error;
@ -1015,7 +1020,7 @@ reswitch: switch (ch) {
}
#else
if (flags & LONGINT)
*buf = (wchar_t)GETARG(wint_t);
*buf = (wchar_t)GETARG(int);
else
*buf = (wchar_t)btowc(GETARG(int));
size = 1;
@ -1915,7 +1920,7 @@ done:
(*argtable) [n].pvoidarg = va_arg (ap, void *);
break;
case T_WINT:
(*argtable) [n].wintarg = va_arg (ap, wint_t);
(*argtable) [n].wintarg = va_arg (ap, int);
break;
case TP_WCHAR:
(*argtable) [n].pwchararg = va_arg (ap, wchar_t *);