author | Jeff Walden <jwalden@mit.edu> |
Thu, 15 Dec 2011 00:27:42 -0500 | |
changeset 145274 | a90c62555235c1525c3134ec030736be5c51de6a |
parent 145273 | 7d8b339221780205a0f16a83b159e23eabf81670 |
child 145294 | 75556cd1a5234a95e0a542dc5122983642678881 |
push id | 33226 |
push user | jwalden@mit.edu |
push date | Tue, 03 Sep 2013 10:51:25 +0000 |
treeherder | mozilla-inbound@a90c62555235 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | espindola |
bugs | 730805 |
milestone | 26.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/configure.in +++ b/configure.in @@ -1728,16 +1728,26 @@ case "$host" in ;; *) HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}" ;; esac +dnl Check for using a custom <inttypes.h> implementation +dnl ======================================================== +AC_MSG_CHECKING(for custom <inttypes.h> implementation) +if test "$MOZ_CUSTOM_INTTYPES_H"; then + AC_DEFINE_UNQUOTED(MOZ_CUSTOM_INTTYPES_H, "$MOZ_CUSTOM_INTTYPES_H") + AC_MSG_RESULT(using $MOZ_CUSTOM_INTTYPES_H) +else + AC_MSG_RESULT(none specified) +fi + dnl Get mozilla version from central milestone file MOZILLA_VERSION=`$PERL $srcdir/config/milestone.pl -topsrcdir $srcdir` MOZILLA_UAVERSION=`$PERL $srcdir/config/milestone.pl -topsrcdir $srcdir -uaversion` dnl Get version of various core apps from the version files. FIREFOX_VERSION=`cat $_topsrcdir/browser/config/version.txt` if test -z "$FIREFOX_VERSION"; then
--- a/ipc/chromium/src/base/basictypes.h +++ b/ipc/chromium/src/base/basictypes.h @@ -7,17 +7,17 @@ #include <limits.h> // So we can set the bounds of our types #include <stddef.h> // For size_t #include <string.h> // for memcpy #include "base/port.h" // Types that only need exist on certain systems #include "mozilla/Assertions.h" -#include <stdint.h> +#include "mozilla/IntegerPrintfMacros.h" // A type to represent a Unicode code-point value. As of Unicode 4.0, // such values require up to 21 bits. // (For type-checking on pointers, make this explicitly signed, // and it should always be the signed version of whatever int32_t is.) typedef signed int char32; const uint8_t kuint8max = (( uint8_t) 0xFF); @@ -30,25 +30,20 @@ const int16_t kint16min = (( int16_t) const int16_t kint16max = (( int16_t) 0x7FFF); const int32_t kint32min = (( int32_t) 0x80000000); const int32_t kint32max = (( int32_t) 0x7FFFFFFF); const int64_t kint64min = (( int64_t) GG_LONGLONG(0x8000000000000000)); const int64_t kint64max = (( int64_t) GG_LONGLONG(0x7FFFFFFFFFFFFFFF)); // Platform- and hardware-dependent printf specifiers # if defined(OS_POSIX) -# define __STDC_FORMAT_MACROS 1 -# include <inttypes.h> // for 64-bit integer format macros # define PRId64L "I64d" # define PRIu64L "I64u" # define PRIx64L "I64x" # elif defined(OS_WIN) -# define PRId64 "I64d" -# define PRIu64 "I64u" -# define PRIx64 "I64x" # define PRId64L L"I64d" # define PRIu64L L"I64u" # define PRIx64L L"I64x" # endif // A macro to disallow the copy constructor and operator= functions // This should be used in the private: declarations for a class #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
--- a/js/public/RequiredDefines.h +++ b/js/public/RequiredDefines.h @@ -10,14 +10,22 @@ * or SpiderMonkey public headers may not work correctly. */ #ifndef js_RequiredDefines_h #define js_RequiredDefines_h /* * The c99 defining the limit macros (UINT32_MAX for example), says: - * C++ implementations should define these macros only when __STDC_LIMIT_MACROS - * is defined before <stdint.h> is included. + * + * C++ implementations should define these macros only when + * __STDC_LIMIT_MACROS is defined before <stdint.h> is included. + * + * The same also occurs with __STDC_CONSTANT_MACROS for the constant macros + * (INT8_C for example) used to specify a literal constant of the proper type, + * and with __STDC_FORMAT_MACROS for the format macros (PRId32 for example) used + * with the fprintf function family. */ #define __STDC_LIMIT_MACROS +#define __STDC_CONSTANT_MACROS +#define __STDC_FORMAT_MACROS #endif /* js_RequiredDefines_h */
--- a/js/src/configure.in +++ b/js/src/configure.in @@ -1354,16 +1354,26 @@ case "$host" in ;; *) HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}" ;; esac +dnl Check for using a custom <inttypes.h> implementation +dnl ======================================================== +AC_MSG_CHECKING(for custom <inttypes.h> implementation) +if test "$MOZ_CUSTOM_INTTYPES_H"; then + AC_DEFINE_UNQUOTED(MOZ_CUSTOM_INTTYPES_H, "$MOZ_CUSTOM_INTTYPES_H") + AC_MSG_RESULT(using $MOZ_CUSTOM_INTTYPES_H) +else + AC_MSG_RESULT(none specified) +fi + MOZ_DOING_LTO(lto_is_enabled) dnl ======================================================== dnl System overrides of the defaults for target dnl ======================================================== case "$target" in *-aix*)
new file mode 100644 --- /dev/null +++ b/mfbt/IntegerPrintfMacros.h @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Implements the C99 <inttypes.h> interface, minus the SCN* format macros. */ + +#ifndef mozilla_IntegerPrintfMacros_h_ +#define mozilla_IntegerPrintfMacros_h_ + +/* + * MSVC++ doesn't include <inttypes.h>, even in versions shipping <stdint.h>, so + * we have to reimplement it there. Note: <inttypes.h> #includes <stdint.h>. + * + * Note that this header DOES NOT implement <inttypes.h>'s scanf macros. MSVC's + * scanf doesn't have sufficient format specifier support to implement them + * (specifically, to implement scanning into an 8-bit location). + * + * http://stackoverflow.com/questions/3036396/scanfd-char-char-as-int-format-string + * + * Moreover, scanf is a footgun: if the input number exceeds the bounds of the + * target type, behavior is undefined (in the compiler sense: that is, this code + * could overwrite your hard drive with zeroes): + * + * uint8_t u; + * sscanf("256", "%" SCNu8, &u); // BAD + * + * This header will sometimes provide SCN* macros, by dint of being implemented + * using <inttypes.h>. But for these reasons, *never* use them! + */ + +#if defined(MOZ_CUSTOM_INTTYPES_H) +# include MOZ_CUSTOM_INTTYPES_H +#elif defined(_MSC_VER) +# include "mozilla/MSIntTypes.h" +#else +# include <inttypes.h> +#endif + +#endif /* mozilla_IntegerPrintfMacros_h_ */
--- a/mfbt/MSIntTypes.h +++ b/mfbt/MSIntTypes.h @@ -35,17 +35,17 @@ #ifndef _MSC_INTTYPES_H_ // [ #define _MSC_INTTYPES_H_ #if _MSC_VER > 1000 #pragma once #endif -#include "stdint.h" +#include <stdint.h> // 7.8 Format conversion of integer types typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; @@ -146,125 +146,18 @@ typedef struct { #define PRIxMAX "I64x" #define PRIXMAX "I64X" #define PRIoPTR "Io" #define PRIuPTR "Iu" #define PRIxPTR "Ix" #define PRIXPTR "IX" -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] +// DO NOT SUPPORT THE scanf MACROS! See the comment at the top of +// IntegerPrintfMacros.h. #endif // __STDC_FORMAT_MACROS ] // 7.8.2 Functions for greatest-width integer types // 7.8.2.1 The imaxabs function #define imaxabs _abs64
--- a/mfbt/exported_headers.mk +++ b/mfbt/exported_headers.mk @@ -23,16 +23,17 @@ EXPORTS_mozilla += \ Constants.h \ DebugOnly.h \ decimal/Decimal.h \ Endian.h \ EnumSet.h \ FloatingPoint.h \ GuardObjects.h \ HashFunctions.h \ + IntegerPrintfMacros.h \ Likely.h \ LinkedList.h \ MathAlgorithms.h \ Maybe.h \ MemoryChecking.h \ MemoryReporting.h \ MSIntTypes.h \ Move.h \
new file mode 100644 --- /dev/null +++ b/mfbt/tests/TestIntegerPrintfMacros.cpp @@ -0,0 +1,1264 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Assertions.h" +#include "mozilla/IntegerPrintfMacros.h" // this must pick up <stdint.h> + +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +/* Output array and poisoning method shared by all tests. */ +static char output[32]; + +static void +PoisonOutput() +{ + memset(output, 0xDA, sizeof(output)); +} + +/* + * The fprintf macros for signed integers are: + * + * PRIdN PRIdLEASTN PRIdFASTN PRIdMAX PRIdPTR + * PRIiN PRIiLEASTN PRIiFASTN PRIiMAX PRIiPTR + * + * In these names N is the width of the type as described in C99 7.18.1. + */ + +static void +TestPrintSigned8() +{ + PoisonOutput(); + sprintf(output, "%" PRId8, int8_t(-17)); + MOZ_ASSERT(!strcmp(output, "-17")); + + PoisonOutput(); + sprintf(output, "%" PRIi8, int8_t(42)); + MOZ_ASSERT(!strcmp(output, "42")); +} + +static void +TestPrintSigned16() +{ + PoisonOutput(); + sprintf(output, "%" PRId16, int16_t(-289)); + MOZ_ASSERT(!strcmp(output, "-289")); + + PoisonOutput(); + sprintf(output, "%" PRIi16, int16_t(728)); + MOZ_ASSERT(!strcmp(output, "728")); +} + +static void +TestPrintSigned32() +{ + PoisonOutput(); + sprintf(output, "%" PRId32, int32_t(-342178)); + MOZ_ASSERT(!strcmp(output, "-342178")); + + PoisonOutput(); + sprintf(output, "%" PRIi32, int32_t(5719283)); + MOZ_ASSERT(!strcmp(output, "5719283")); +} + +static void +TestPrintSigned64() +{ + PoisonOutput(); + sprintf(output, "%" PRId64, int64_t(-INT64_C(432157943248732))); + MOZ_ASSERT(!strcmp(output, "-432157943248732")); + + PoisonOutput(); + sprintf(output, "%" PRIi64, int64_t(INT64_C(325719232983))); + MOZ_ASSERT(!strcmp(output, "325719232983")); +} + +static void +TestPrintSignedN() +{ + TestPrintSigned8(); + TestPrintSigned16(); + TestPrintSigned32(); + TestPrintSigned64(); +} + +static void +TestPrintSignedLeast8() +{ + PoisonOutput(); + sprintf(output, "%" PRIdLEAST8, int_least8_t(-17)); + MOZ_ASSERT(!strcmp(output, "-17")); + + PoisonOutput(); + sprintf(output, "%" PRIiLEAST8, int_least8_t(42)); + MOZ_ASSERT(!strcmp(output, "42")); +} + +static void +TestPrintSignedLeast16() +{ + PoisonOutput(); + sprintf(output, "%" PRIdLEAST16, int_least16_t(-289)); + MOZ_ASSERT(!strcmp(output, "-289")); + + PoisonOutput(); + sprintf(output, "%" PRIiLEAST16, int_least16_t(728)); + MOZ_ASSERT(!strcmp(output, "728")); +} + +static void +TestPrintSignedLeast32() +{ + PoisonOutput(); + sprintf(output, "%" PRIdLEAST32, int_least32_t(-342178)); + MOZ_ASSERT(!strcmp(output, "-342178")); + + PoisonOutput(); + sprintf(output, "%" PRIiLEAST32, int_least32_t(5719283)); + MOZ_ASSERT(!strcmp(output, "5719283")); +} + +static void +TestPrintSignedLeast64() +{ + PoisonOutput(); + sprintf(output, "%" PRIdLEAST64, int_least64_t(-INT64_C(432157943248732))); + MOZ_ASSERT(!strcmp(output, "-432157943248732")); + + PoisonOutput(); + sprintf(output, "%" PRIiLEAST64, int_least64_t(INT64_C(325719232983))); + MOZ_ASSERT(!strcmp(output, "325719232983")); +} + +static void +TestPrintSignedLeastN() +{ + TestPrintSignedLeast8(); + TestPrintSignedLeast16(); + TestPrintSignedLeast32(); + TestPrintSignedLeast64(); +} + +static void +TestPrintSignedFast8() +{ + PoisonOutput(); + sprintf(output, "%" PRIdFAST8, int_fast8_t(-17)); + MOZ_ASSERT(!strcmp(output, "-17")); + + PoisonOutput(); + sprintf(output, "%" PRIiFAST8, int_fast8_t(42)); + MOZ_ASSERT(!strcmp(output, "42")); +} + +static void +TestPrintSignedFast16() +{ + PoisonOutput(); + sprintf(output, "%" PRIdFAST16, int_fast16_t(-289)); + MOZ_ASSERT(!strcmp(output, "-289")); + + PoisonOutput(); + sprintf(output, "%" PRIiFAST16, int_fast16_t(728)); + MOZ_ASSERT(!strcmp(output, "728")); +} + +static void +TestPrintSignedFast32() +{ + PoisonOutput(); + sprintf(output, "%" PRIdFAST32, int_fast32_t(-342178)); + MOZ_ASSERT(!strcmp(output, "-342178")); + + PoisonOutput(); + sprintf(output, "%" PRIiFAST32, int_fast32_t(5719283)); + MOZ_ASSERT(!strcmp(output, "5719283")); +} + +static void +TestPrintSignedFast64() +{ + PoisonOutput(); + sprintf(output, "%" PRIdFAST64, int_fast64_t(-INT64_C(432157943248732))); + MOZ_ASSERT(!strcmp(output, "-432157943248732")); + + PoisonOutput(); + sprintf(output, "%" PRIiFAST64, int_fast64_t(INT64_C(325719232983))); + MOZ_ASSERT(!strcmp(output, "325719232983")); +} + +static void +TestPrintSignedFastN() +{ + TestPrintSignedFast8(); + TestPrintSignedFast16(); + TestPrintSignedFast32(); + TestPrintSignedFast64(); +} + +static void +TestPrintSignedMax() +{ + PoisonOutput(); + sprintf(output, "%" PRIdMAX, intmax_t(-INTMAX_C(432157943248732))); + MOZ_ASSERT(!strcmp(output, "-432157943248732")); + + PoisonOutput(); + sprintf(output, "%" PRIiMAX, intmax_t(INTMAX_C(325719232983))); + MOZ_ASSERT(!strcmp(output, "325719232983")); +} + +static void +TestPrintSignedPtr() +{ + PoisonOutput(); + sprintf(output, "%" PRIdPTR, intptr_t(reinterpret_cast<void*>(12345678))); + MOZ_ASSERT(!strcmp(output, "12345678")); + + PoisonOutput(); + sprintf(output, "%" PRIiPTR, intptr_t(reinterpret_cast<void*>(87654321))); + MOZ_ASSERT(!strcmp(output, "87654321")); +} + +static void +TestPrintSigned() +{ + TestPrintSignedN(); + TestPrintSignedLeastN(); + TestPrintSignedFastN(); + TestPrintSignedMax(); + TestPrintSignedPtr(); +} + +/* + * The fprintf macros for unsigned integers are: + * + * PRIoN PRIoLEASTN PRIoFASTN PRIoMAX PRIoPTR + * PRIuN PRIuLEASTN PRIuFASTN PRIuMAX PRIuPTR + * PRIxN PRIxLEASTN PRIxFASTN PRIxMAX PRIxPTR + * PRIXN PRIXLEASTN PRIXFASTN PRIXMAX PRIXPTR + * + * In these names N is the width of the type as described in C99 7.18.1. + */ + +static void +TestPrintUnsigned8() +{ + PoisonOutput(); + sprintf(output, "%" PRIo8, uint8_t(042)); + MOZ_ASSERT(!strcmp(output, "42")); + + PoisonOutput(); + sprintf(output, "%" PRIu8, uint8_t(17)); + MOZ_ASSERT(!strcmp(output, "17")); + + PoisonOutput(); + sprintf(output, "%" PRIx8, uint8_t(0x2a)); + MOZ_ASSERT(!strcmp(output, "2a")); + + PoisonOutput(); + sprintf(output, "%" PRIX8, uint8_t(0xCD)); + MOZ_ASSERT(!strcmp(output, "CD")); +} + +static void +TestPrintUnsigned16() +{ + PoisonOutput(); + sprintf(output, "%" PRIo16, uint16_t(04242)); + MOZ_ASSERT(!strcmp(output, "4242")); + + PoisonOutput(); + sprintf(output, "%" PRIu16, uint16_t(1717)); + MOZ_ASSERT(!strcmp(output, "1717")); + + PoisonOutput(); + sprintf(output, "%" PRIx16, uint16_t(0x2a2a)); + MOZ_ASSERT(!strcmp(output, "2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIX16, uint16_t(0xCDCD)); + MOZ_ASSERT(!strcmp(output, "CDCD")); +} + +static void +TestPrintUnsigned32() +{ + PoisonOutput(); + sprintf(output, "%" PRIo32, uint32_t(0424242)); + MOZ_ASSERT(!strcmp(output, "424242")); + + PoisonOutput(); + sprintf(output, "%" PRIu32, uint32_t(171717)); + MOZ_ASSERT(!strcmp(output, "171717")); + + PoisonOutput(); + sprintf(output, "%" PRIx32, uint32_t(0x2a2a2a)); + MOZ_ASSERT(!strcmp(output, "2a2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIX32, uint32_t(0xCDCDCD)); + MOZ_ASSERT(!strcmp(output, "CDCDCD")); +} + +static void +TestPrintUnsigned64() +{ + PoisonOutput(); + sprintf(output, "%" PRIo64, uint64_t(UINT64_C(0424242424242))); + MOZ_ASSERT(!strcmp(output, "424242424242")); + + PoisonOutput(); + sprintf(output, "%" PRIu64, uint64_t(UINT64_C(17171717171717171717))); + MOZ_ASSERT(!strcmp(output, "17171717171717171717")); + + PoisonOutput(); + sprintf(output, "%" PRIx64, uint64_t(UINT64_C(0x2a2a2a2a2a2a2a))); + MOZ_ASSERT(!strcmp(output, "2a2a2a2a2a2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIX64, uint64_t(UINT64_C(0xCDCDCDCDCDCD))); + MOZ_ASSERT(!strcmp(output, "CDCDCDCDCDCD")); +} + +static void +TestPrintUnsignedN() +{ + TestPrintUnsigned8(); + TestPrintUnsigned16(); + TestPrintUnsigned32(); + TestPrintUnsigned64(); +} + +static void +TestPrintUnsignedLeast8() +{ + PoisonOutput(); + sprintf(output, "%" PRIoLEAST8, uint_least8_t(042)); + MOZ_ASSERT(!strcmp(output, "42")); + + PoisonOutput(); + sprintf(output, "%" PRIuLEAST8, uint_least8_t(17)); + MOZ_ASSERT(!strcmp(output, "17")); + + PoisonOutput(); + sprintf(output, "%" PRIxLEAST8, uint_least8_t(0x2a)); + MOZ_ASSERT(!strcmp(output, "2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXLEAST8, uint_least8_t(0xCD)); + MOZ_ASSERT(!strcmp(output, "CD")); +} + +static void +TestPrintUnsignedLeast16() +{ + PoisonOutput(); + sprintf(output, "%" PRIoLEAST16, uint_least16_t(04242)); + MOZ_ASSERT(!strcmp(output, "4242")); + + PoisonOutput(); + sprintf(output, "%" PRIuLEAST16, uint_least16_t(1717)); + MOZ_ASSERT(!strcmp(output, "1717")); + + PoisonOutput(); + sprintf(output, "%" PRIxLEAST16, uint_least16_t(0x2a2a)); + MOZ_ASSERT(!strcmp(output, "2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXLEAST16, uint_least16_t(0xCDCD)); + MOZ_ASSERT(!strcmp(output, "CDCD")); +} + +static void +TestPrintUnsignedLeast32() +{ + PoisonOutput(); + sprintf(output, "%" PRIoLEAST32, uint_least32_t(0424242)); + MOZ_ASSERT(!strcmp(output, "424242")); + + PoisonOutput(); + sprintf(output, "%" PRIuLEAST32, uint_least32_t(171717)); + MOZ_ASSERT(!strcmp(output, "171717")); + + PoisonOutput(); + sprintf(output, "%" PRIxLEAST32, uint_least32_t(0x2a2a2a)); + MOZ_ASSERT(!strcmp(output, "2a2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXLEAST32, uint_least32_t(0xCDCDCD)); + MOZ_ASSERT(!strcmp(output, "CDCDCD")); +} + +static void +TestPrintUnsignedLeast64() +{ + PoisonOutput(); + sprintf(output, "%" PRIoLEAST64, uint_least64_t(UINT64_C(0424242424242))); + MOZ_ASSERT(!strcmp(output, "424242424242")); + + PoisonOutput(); + sprintf(output, "%" PRIuLEAST64, uint_least64_t(UINT64_C(17171717171717171717))); + MOZ_ASSERT(!strcmp(output, "17171717171717171717")); + + PoisonOutput(); + sprintf(output, "%" PRIxLEAST64, uint_least64_t(UINT64_C(0x2a2a2a2a2a2a2a))); + MOZ_ASSERT(!strcmp(output, "2a2a2a2a2a2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXLEAST64, uint_least64_t(UINT64_C(0xCDCDCDCDCDCD))); + MOZ_ASSERT(!strcmp(output, "CDCDCDCDCDCD")); +} + +static void +TestPrintUnsignedLeastN() +{ + TestPrintUnsignedLeast8(); + TestPrintUnsignedLeast16(); + TestPrintUnsignedLeast32(); + TestPrintUnsignedLeast64(); +} + +static void +TestPrintUnsignedFast8() +{ + PoisonOutput(); + sprintf(output, "%" PRIoFAST8, uint_fast8_t(042)); + MOZ_ASSERT(!strcmp(output, "42")); + + PoisonOutput(); + sprintf(output, "%" PRIuFAST8, uint_fast8_t(17)); + MOZ_ASSERT(!strcmp(output, "17")); + + PoisonOutput(); + sprintf(output, "%" PRIxFAST8, uint_fast8_t(0x2a)); + MOZ_ASSERT(!strcmp(output, "2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXFAST8, uint_fast8_t(0xCD)); + MOZ_ASSERT(!strcmp(output, "CD")); +} + +static void +TestPrintUnsignedFast16() +{ + PoisonOutput(); + sprintf(output, "%" PRIoFAST16, uint_fast16_t(04242)); + MOZ_ASSERT(!strcmp(output, "4242")); + + PoisonOutput(); + sprintf(output, "%" PRIuFAST16, uint_fast16_t(1717)); + MOZ_ASSERT(!strcmp(output, "1717")); + + PoisonOutput(); + sprintf(output, "%" PRIxFAST16, uint_fast16_t(0x2a2a)); + MOZ_ASSERT(!strcmp(output, "2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXFAST16, uint_fast16_t(0xCDCD)); + MOZ_ASSERT(!strcmp(output, "CDCD")); +} + +static void +TestPrintUnsignedFast32() +{ + PoisonOutput(); + sprintf(output, "%" PRIoFAST32, uint_fast32_t(0424242)); + MOZ_ASSERT(!strcmp(output, "424242")); + + PoisonOutput(); + sprintf(output, "%" PRIuFAST32, uint_fast32_t(171717)); + MOZ_ASSERT(!strcmp(output, "171717")); + + PoisonOutput(); + sprintf(output, "%" PRIxFAST32, uint_fast32_t(0x2a2a2a)); + MOZ_ASSERT(!strcmp(output, "2a2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXFAST32, uint_fast32_t(0xCDCDCD)); + MOZ_ASSERT(!strcmp(output, "CDCDCD")); +} + +static void +TestPrintUnsignedFast64() +{ + PoisonOutput(); + sprintf(output, "%" PRIoFAST64, uint_fast64_t(UINT64_C(0424242424242))); + MOZ_ASSERT(!strcmp(output, "424242424242")); + + PoisonOutput(); + sprintf(output, "%" PRIuFAST64, uint_fast64_t(UINT64_C(17171717171717171717))); + MOZ_ASSERT(!strcmp(output, "17171717171717171717")); + + PoisonOutput(); + sprintf(output, "%" PRIxFAST64, uint_fast64_t(UINT64_C(0x2a2a2a2a2a2a2a))); + MOZ_ASSERT(!strcmp(output, "2a2a2a2a2a2a2a")); + + PoisonOutput(); + sprintf(output, "%" PRIXFAST64, uint_fast64_t(UINT64_C(0xCDCDCDCDCDCD))); + MOZ_ASSERT(!strcmp(output, "CDCDCDCDCDCD")); +} + +static void +TestPrintUnsignedFastN() +{ + TestPrintUnsignedFast8(); + TestPrintUnsignedFast16(); + TestPrintUnsignedFast32(); + TestPrintUnsignedFast64(); +} + +static void +TestPrintUnsignedMax() +{ + PoisonOutput(); + sprintf(output, "%" PRIoMAX, uintmax_t(UINTMAX_C(432157943248732))); + MOZ_ASSERT(!strcmp(output, "14220563454333534")); + + PoisonOutput(); + sprintf(output, "%" PRIuMAX, uintmax_t(UINTMAX_C(325719232983))); + MOZ_ASSERT(!strcmp(output, "325719232983")); + + PoisonOutput(); + sprintf(output, "%" PRIxMAX, uintmax_t(UINTMAX_C(327281321873))); + MOZ_ASSERT(!strcmp(output, "4c337ca791")); + + PoisonOutput(); + sprintf(output, "%" PRIXMAX, uintmax_t(UINTMAX_C(912389523743523))); + MOZ_ASSERT(!strcmp(output, "33DD03D75A323")); +} + +static void +TestPrintUnsignedPtr() +{ + PoisonOutput(); + sprintf(output, "%" PRIoPTR, uintptr_t(reinterpret_cast<void*>(12345678))); + MOZ_ASSERT(!strcmp(output, "57060516")); + + PoisonOutput(); + sprintf(output, "%" PRIuPTR, uintptr_t(reinterpret_cast<void*>(87654321))); + MOZ_ASSERT(!strcmp(output, "87654321")); + + PoisonOutput(); + sprintf(output, "%" PRIxPTR, uintptr_t(reinterpret_cast<void*>(0x4c3a791))); + MOZ_ASSERT(!strcmp(output, "4c3a791")); + + PoisonOutput(); + sprintf(output, "%" PRIXPTR, uintptr_t(reinterpret_cast<void*>(0xF328DB))); + MOZ_ASSERT(!strcmp(output, "F328DB")); +} + +static void +TestPrintUnsigned() +{ + TestPrintUnsignedN(); + TestPrintUnsignedLeastN(); + TestPrintUnsignedFastN(); + TestPrintUnsignedMax(); + TestPrintUnsignedPtr(); +} + +static void +TestPrint() +{ + TestPrintSigned(); + TestPrintUnsigned(); +} + +/* + * The fscanf macros for signed integers are: + * + * SCNdN SCNdLEASTN SCNdFASTN SCNdMAX SCNdPTR + * SCNiN SCNiLEASTN SCNiFASTN SCNiMAX SCNiPTR + * + * In these names N is the width of the type as described in C99 7.18.1. + */ + +/* + * MSVC's scanf is insufficiently powerful to implement all the SCN* macros. + * Rather than support some subset of them, we instead support none of them. + * See the comment at the top of IntegerPrintfMacros.h. But in case we ever do + * support them, the following tests should adequately test implementation + * correctness. (Indeed, these tests *revealed* MSVC's limitations.) + * + * That said, even if MSVC ever picks up complete support, we still probably + * don't want to support these, because of the undefined-behavior issue noted + * further down in the comment atop IntegerPrintfMacros.h. + */ +#define SHOULD_TEST_SCANF_MACROS 0 + +#if SHOULD_TEST_SCANF_MACROS + +/* + * glibc header definitions for SCN{d,i,o,u,x}{,LEAST,FAST}8 use the "hh" length + * modifier, which is new in C99 (and C++11, by reference). We compile this + * file as C++11, so if "hh" is used in these macros, it's standard. But some + * versions of gcc wrongly think it isn't and warn about a "non-standard" + * modifier. And since these tests mostly exist to verify format-macro/type + * consistency (particularly through compiler warnings about incorrect formats), + * these warnings are unacceptable. So for now, compile tests for those macros + * only if we aren't compiling with gcc. + */ +#define SHOULD_TEST_8BIT_FORMAT_MACROS (!(MOZ_IS_GCC)) + +template<typename T> +union Input +{ + T i; + unsigned char pun[16]; +}; + +template<typename T> +static void +PoisonInput(Input<T>& input) +{ + memset(input.pun, 0xDA, sizeof(input.pun)); +} + +template<typename T> +static bool +ExtraBitsUntouched(const Input<T>& input) +{ + for (size_t i = sizeof(input.i); i < sizeof(input); i++) { + if (input.pun[i] != 0xDA) + return false; + } + + return true; +} + +static void +TestScanSigned8() +{ +#if SHOULD_TEST_8BIT_FORMAT_MACROS + Input<int8_t> u; + + PoisonInput(u); + sscanf("-17", "%" SCNd8, &u.i); + MOZ_ASSERT(u.i == -17); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("042", "%" SCNi8, &u.i); + MOZ_ASSERT(u.i == 042); + MOZ_ASSERT(ExtraBitsUntouched(u)); +#endif +} + +static void +TestScanSigned16() +{ + Input<int16_t> u; + + PoisonInput(u); + sscanf("-1742", "%" SCNd16, &u.i); + MOZ_ASSERT(u.i == -1742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("04217", "%" SCNi16, &u.i); + MOZ_ASSERT(u.i == 04217); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSigned32() +{ + Input<int32_t> u; + + PoisonInput(u); + sscanf("-174257", "%" SCNd32, &u.i); + MOZ_ASSERT(u.i == -174257); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("0423571", "%" SCNi32, &u.i); + MOZ_ASSERT(u.i == 0423571); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSigned64() +{ + Input<int64_t> u; + + PoisonInput(u); + sscanf("-17425238927232", "%" SCNd64, &u.i); + MOZ_ASSERT(u.i == -INT64_C(17425238927232)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("042333576571", "%" SCNi64, &u.i); + MOZ_ASSERT(u.i == INT64_C(042333576571)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedN() +{ + TestScanSigned8(); + TestScanSigned16(); + TestScanSigned32(); + TestScanSigned64(); +} + +static void +TestScanSignedLeast8() +{ +#if SHOULD_TEST_8BIT_FORMAT_MACROS + Input<int_least8_t> u; + + PoisonInput(u); + sscanf("-17", "%" SCNdLEAST8, &u.i); + MOZ_ASSERT(u.i == -17); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("042", "%" SCNiLEAST8, &u.i); + MOZ_ASSERT(u.i == 042); + MOZ_ASSERT(ExtraBitsUntouched(u)); +#endif +} + +static void +TestScanSignedLeast16() +{ + Input<int_least16_t> u; + + PoisonInput(u); + sscanf("-1742", "%" SCNdLEAST16, &u.i); + MOZ_ASSERT(u.i == -1742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("04217", "%" SCNiLEAST16, &u.i); + MOZ_ASSERT(u.i == 04217); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedLeast32() +{ + Input<int_least32_t> u; + + PoisonInput(u); + sscanf("-174257", "%" SCNdLEAST32, &u.i); + MOZ_ASSERT(u.i == -174257); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("0423571", "%" SCNiLEAST32, &u.i); + MOZ_ASSERT(u.i == 0423571); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedLeast64() +{ + Input<int_least64_t> u; + + PoisonInput(u); + sscanf("-17425238927232", "%" SCNdLEAST64, &u.i); + MOZ_ASSERT(u.i == -INT64_C(17425238927232)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("042333576571", "%" SCNiLEAST64, &u.i); + MOZ_ASSERT(u.i == INT64_C(042333576571)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedLeastN() +{ + TestScanSignedLeast8(); + TestScanSignedLeast16(); + TestScanSignedLeast32(); + TestScanSignedLeast64(); +} + +static void +TestScanSignedFast8() +{ +#if SHOULD_TEST_8BIT_FORMAT_MACROS + Input<int_fast8_t> u; + + PoisonInput(u); + sscanf("-17", "%" SCNdFAST8, &u.i); + MOZ_ASSERT(u.i == -17); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("042", "%" SCNiFAST8, &u.i); + MOZ_ASSERT(u.i == 042); + MOZ_ASSERT(ExtraBitsUntouched(u)); +#endif +} + +static void +TestScanSignedFast16() +{ + Input<int_fast16_t> u; + + PoisonInput(u); + sscanf("-1742", "%" SCNdFAST16, &u.i); + MOZ_ASSERT(u.i == -1742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("04217", "%" SCNiFAST16, &u.i); + MOZ_ASSERT(u.i == 04217); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedFast32() +{ + Input<int_fast32_t> u; + + PoisonInput(u); + sscanf("-174257", "%" SCNdFAST32, &u.i); + MOZ_ASSERT(u.i == -174257); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("0423571", "%" SCNiFAST32, &u.i); + MOZ_ASSERT(u.i == 0423571); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedFast64() +{ + Input<int_fast64_t> u; + + PoisonInput(u); + sscanf("-17425238927232", "%" SCNdFAST64, &u.i); + MOZ_ASSERT(u.i == -INT64_C(17425238927232)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("042333576571", "%" SCNiFAST64, &u.i); + MOZ_ASSERT(u.i == INT64_C(042333576571)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedFastN() +{ + TestScanSignedFast8(); + TestScanSignedFast16(); + TestScanSignedFast32(); + TestScanSignedFast64(); +} + +static void +TestScanSignedMax() +{ + Input<intmax_t> u; + + PoisonInput(u); + sscanf("-432157943248732", "%" SCNdMAX, &u.i); + MOZ_ASSERT(u.i == -INTMAX_C(432157943248732)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("04233357236571", "%" SCNiMAX, &u.i); + MOZ_ASSERT(u.i == INTMAX_C(04233357236571)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSignedPtr() +{ + Input<intptr_t> u; + + PoisonInput(u); + sscanf("12345678", "%" SCNdPTR, &u.i); + MOZ_ASSERT(u.i == intptr_t(reinterpret_cast<void*>(12345678))); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("04233357236", "%" SCNiPTR, &u.i); + MOZ_ASSERT(u.i == intptr_t(reinterpret_cast<void*>(04233357236))); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanSigned() +{ + TestScanSignedN(); + TestScanSignedLeastN(); + TestScanSignedFastN(); + TestScanSignedMax(); + TestScanSignedPtr(); +} + +/* + * The fscanf macros for unsigned integers are: + * + * SCNoN SCNoLEASTN SCNoFASTN SCNoMAX SCNoPTR + * SCNuN SCNuLEASTN SCNuFASTN SCNuMAX SCNuPTR + * SCNxN SCNxLEASTN SCNxFASTN SCNxMAX SCNxPTR + * + * In these names N is the width of the type as described in C99 7.18.1. + */ + +static void +TestScanUnsigned8() +{ +#if SHOULD_TEST_8BIT_FORMAT_MACROS + Input<uint8_t> u; + + PoisonInput(u); + sscanf("17", "%" SCNo8, &u.i); + MOZ_ASSERT(u.i == 017); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("42", "%" SCNu8, &u.i); + MOZ_ASSERT(u.i == 42); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2A", "%" SCNx8, &u.i); + MOZ_ASSERT(u.i == 0x2A); + MOZ_ASSERT(ExtraBitsUntouched(u)); +#endif +} + +static void +TestScanUnsigned16() +{ + Input<uint16_t> u; + + PoisonInput(u); + sscanf("1742", "%" SCNo16, &u.i); + MOZ_ASSERT(u.i == 01742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4217", "%" SCNu16, &u.i); + MOZ_ASSERT(u.i == 4217); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2ABC", "%" SCNx16, &u.i); + MOZ_ASSERT(u.i == 0x2ABC); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsigned32() +{ + Input<uint32_t> u; + + PoisonInput(u); + sscanf("17421742", "%" SCNo32, &u.i); + MOZ_ASSERT(u.i == 017421742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4217867", "%" SCNu32, &u.i); + MOZ_ASSERT(u.i == 4217867); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2ABCBEEF", "%" SCNx32, &u.i); + MOZ_ASSERT(u.i == 0x2ABCBEEF); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsigned64() +{ + Input<uint64_t> u; + + PoisonInput(u); + sscanf("17421742173", "%" SCNo64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(017421742173)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("421786713579", "%" SCNu64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(421786713579)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("DEADBEEF7457E", "%" SCNx64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(0xDEADBEEF7457E)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedN() +{ + TestScanUnsigned8(); + TestScanUnsigned16(); + TestScanUnsigned32(); + TestScanUnsigned64(); +} + +static void +TestScanUnsignedLeast8() +{ +#if SHOULD_TEST_8BIT_FORMAT_MACROS + Input<uint_least8_t> u; + + PoisonInput(u); + sscanf("17", "%" SCNoLEAST8, &u.i); + MOZ_ASSERT(u.i == 017); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("42", "%" SCNuLEAST8, &u.i); + MOZ_ASSERT(u.i == 42); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2A", "%" SCNxLEAST8, &u.i); + MOZ_ASSERT(u.i == 0x2A); + MOZ_ASSERT(ExtraBitsUntouched(u)); +#endif +} + +static void +TestScanUnsignedLeast16() +{ + Input<uint_least16_t> u; + + PoisonInput(u); + sscanf("1742", "%" SCNoLEAST16, &u.i); + MOZ_ASSERT(u.i == 01742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4217", "%" SCNuLEAST16, &u.i); + MOZ_ASSERT(u.i == 4217); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2ABC", "%" SCNxLEAST16, &u.i); + MOZ_ASSERT(u.i == 0x2ABC); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedLeast32() +{ + Input<uint_least32_t> u; + + PoisonInput(u); + sscanf("17421742", "%" SCNoLEAST32, &u.i); + MOZ_ASSERT(u.i == 017421742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4217867", "%" SCNuLEAST32, &u.i); + MOZ_ASSERT(u.i == 4217867); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2ABCBEEF", "%" SCNxLEAST32, &u.i); + MOZ_ASSERT(u.i == 0x2ABCBEEF); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedLeast64() +{ + Input<uint_least64_t> u; + + PoisonInput(u); + sscanf("17421742173", "%" SCNoLEAST64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(017421742173)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("421786713579", "%" SCNuLEAST64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(421786713579)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("DEADBEEF7457E", "%" SCNxLEAST64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(0xDEADBEEF7457E)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedLeastN() +{ + TestScanUnsignedLeast8(); + TestScanUnsignedLeast16(); + TestScanUnsignedLeast32(); + TestScanUnsignedLeast64(); +} + +static void +TestScanUnsignedFast8() +{ +#if SHOULD_TEST_8BIT_FORMAT_MACROS + Input<uint_fast8_t> u; + + PoisonInput(u); + sscanf("17", "%" SCNoFAST8, &u.i); + MOZ_ASSERT(u.i == 017); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("42", "%" SCNuFAST8, &u.i); + MOZ_ASSERT(u.i == 42); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2A", "%" SCNxFAST8, &u.i); + MOZ_ASSERT(u.i == 0x2A); + MOZ_ASSERT(ExtraBitsUntouched(u)); +#endif +} + +static void +TestScanUnsignedFast16() +{ + Input<uint_fast16_t> u; + + PoisonInput(u); + sscanf("1742", "%" SCNoFAST16, &u.i); + MOZ_ASSERT(u.i == 01742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4217", "%" SCNuFAST16, &u.i); + MOZ_ASSERT(u.i == 4217); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2ABC", "%" SCNxFAST16, &u.i); + MOZ_ASSERT(u.i == 0x2ABC); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedFast32() +{ + Input<uint_fast32_t> u; + + PoisonInput(u); + sscanf("17421742", "%" SCNoFAST32, &u.i); + MOZ_ASSERT(u.i == 017421742); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4217867", "%" SCNuFAST32, &u.i); + MOZ_ASSERT(u.i == 4217867); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("2ABCBEEF", "%" SCNxFAST32, &u.i); + MOZ_ASSERT(u.i == 0x2ABCBEEF); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedFast64() +{ + Input<uint_fast64_t> u; + + PoisonInput(u); + sscanf("17421742173", "%" SCNoFAST64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(017421742173)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("421786713579", "%" SCNuFAST64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(421786713579)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("DEADBEEF7457E", "%" SCNxFAST64, &u.i); + MOZ_ASSERT(u.i == UINT64_C(0xDEADBEEF7457E)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedFastN() +{ + TestScanUnsignedFast8(); + TestScanUnsignedFast16(); + TestScanUnsignedFast32(); + TestScanUnsignedFast64(); +} + +static void +TestScanUnsignedMax() +{ + Input<uintmax_t> u; + + PoisonInput(u); + sscanf("14220563454333534", "%" SCNoMAX, &u.i); + MOZ_ASSERT(u.i == UINTMAX_C(432157943248732)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("432157943248732", "%" SCNuMAX, &u.i); + MOZ_ASSERT(u.i == UINTMAX_C(432157943248732)); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4c337ca791", "%" SCNxMAX, &u.i); + MOZ_ASSERT(u.i == UINTMAX_C(327281321873)); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsignedPtr() +{ + Input<uintptr_t> u; + + PoisonInput(u); + sscanf("57060516", "%" SCNoPTR, &u.i); + MOZ_ASSERT(u.i == uintptr_t(reinterpret_cast<void*>(12345678))); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("87654321", "%" SCNuPTR, &u.i); + MOZ_ASSERT(u.i == uintptr_t(reinterpret_cast<void*>(87654321))); + MOZ_ASSERT(ExtraBitsUntouched(u)); + + PoisonInput(u); + sscanf("4c3a791", "%" SCNxPTR, &u.i); + MOZ_ASSERT(u.i == uintptr_t(reinterpret_cast<void*>(0x4c3a791))); + MOZ_ASSERT(ExtraBitsUntouched(u)); +} + +static void +TestScanUnsigned() +{ + TestScanUnsignedN(); + TestScanUnsignedLeastN(); + TestScanUnsignedFastN(); + TestScanUnsignedMax(); + TestScanUnsignedPtr(); +} + +static void +TestScan() +{ + TestScanSigned(); + TestScanUnsigned(); +} + +#endif /* SHOULD_TEST_SCANF_MACROS */ + +int +main() +{ + TestPrint(); +#if SHOULD_TEST_SCANF_MACROS + TestScan(); +#endif + return 0; +}
--- a/mfbt/tests/TestPoisonArea.cpp +++ b/mfbt/tests/TestPoisonArea.cpp @@ -74,34 +74,25 @@ * *64*-bit processes on Linux - and we don't even run this code for * 64-bit processes. * * 4. VirtualQuery() does not produce any useful information if * applied to kernel memory - in fact, it doesn't write its output * at all. Thus, it is not used here. */ +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/NullPtr.h" -// MAP_ANON(YMOUS) is not in any standard, and the C99 PRI* macros are -// not in C++98. Add defines as necessary. -#define __STDC_FORMAT_MACROS +// MAP_ANON(YMOUS) is not in any standard. Add defines as necessary. #define _GNU_SOURCE 1 #define _DARWIN_C_SOURCE 1 #include <stddef.h> -#ifndef _WIN32 -#include <inttypes.h> -#else -#define PRIxPTR "Ix" -typedef unsigned int uint32_t; -// MSVC defines uintptr_t in <crtdefs.h> which is brought in implicitly -#endif - #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _WIN32 #include <windows.h> #elif defined(__OS2__)
--- a/mfbt/tests/moz.build +++ b/mfbt/tests/moz.build @@ -9,16 +9,17 @@ CPP_UNIT_TESTS += [ 'TestBloomFilter.cpp', 'TestCasting.cpp', 'TestCeilingFloor.cpp', 'TestCheckedInt.cpp', 'TestCountZeroes.cpp', 'TestEndian.cpp', 'TestEnumSet.cpp', 'TestFloatingPoint.cpp', + 'TestIntegerPrintfMacros.cpp', 'TestSHA1.cpp', 'TestTypeTraits.cpp', 'TestWeakPtr.cpp', ] if not CONFIG['MOZ_ASAN']: CPP_UNIT_TESTS += [ 'TestPoisonArea.cpp',
--- a/mozilla-config.h.in +++ b/mozilla-config.h.in @@ -3,23 +3,34 @@ * Do not edit. */ #ifndef _MOZILLA_CONFIG_H_ #define _MOZILLA_CONFIG_H_ @ALLDEFINES@ -/* The c99 defining the limit macros (UINT32_MAX for example), says: - * C++ implementations should define these macros only when __STDC_LIMIT_MACROS - * is defined before <stdint.h> is included. */ +/* + * The c99 defining the limit macros (UINT32_MAX for example), says: + * + * C++ implementations should define these macros only when + * __STDC_LIMIT_MACROS is defined before <stdint.h> is included. + * + * The same also occurs with __STDC_CONSTANT_MACROS for the constant macros + * (INT8_C for example) used to specify a literal constant of the proper type, + * and with __STDC_FORMAT_MACROS for the format macros (PRId32 for example) used + * with the fprintf function family. + */ #define __STDC_LIMIT_MACROS +#define __STDC_CONSTANT_MACROS +#define __STDC_FORMAT_MACROS -/* Force-include hunspell_alloc_hooks.h and hunspell_fopen_hooks.h for hunspell, - * so that we don't need to modify it directly. +/* + * Force-include hunspell_alloc_hooks.h and hunspell_fopen_hooks.h for hunspell, + * so that we don't need to modify them directly. * * HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in, * unless --enable-system-hunspell is defined. */ #if defined(HUNSPELL_STATIC) #include "hunspell_alloc_hooks.h" #include "hunspell_fopen_hooks.h" #endif
--- a/security/manager/boot/src/Makefile.in +++ b/security/manager/boot/src/Makefile.in @@ -5,16 +5,15 @@ DEPTH = @DEPTH@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk EXPORT_LIBRARY = 1 -DEFINES += -D__STDC_CONSTANT_MACROS include $(topsrcdir)/config/rules.mk INCLUDES += \ -I$(DIST)/public/nss \ $(NULL)