Bug 836438 - Always implement nsresult using an unsigned 32-bit integer type. r=ehsan
authorJeff Walden <jwalden@mit.edu>
Wed, 30 Jan 2013 15:32:44 -0800
changeset 131183 091c6ec1944429d16789846c46fd62f368241302
parent 131182 14550ec92519d20f5a325b18e32b693be7825f27
child 131184 c6a2e0805de7a5c74c0229018a7913b259f4e0c6
push id317
push userbbajaj@mozilla.com
push dateTue, 07 May 2013 01:20:33 +0000
treeherdermozilla-release@159a10910249 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs836438
milestone21.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
Bug 836438 - Always implement nsresult using an unsigned 32-bit integer type. r=ehsan
dom/browser-element/BrowserElementParent.js
mfbt/TypedEnum.h
xpcom/base/Makefile.in
xpcom/base/nsError.h
xpcom/base/nsErrorAsserts.cpp
xpcom/base/nsErrorAssertsC.c
xpcom/base/nscore.h
--- a/mfbt/TypedEnum.h
+++ b/mfbt/TypedEnum.h
@@ -5,16 +5,18 @@
 
 /* Macros to emulate C++11 typed enums and enum classes. */
 
 #ifndef mozilla_TypedEnum_h_
 #define mozilla_TypedEnum_h_
 
 #include "mozilla/Attributes.h"
 
+#if defined(__cplusplus)
+
 #if defined(__clang__)
    /*
     * Per Clang documentation, "Note that marketing version numbers should not
     * be used to check for language features, as different vendors use different
     * numbering schemes. Instead, use the feature checking macros."
     */
 #  ifndef __has_extension
 #    define __has_extension __has_feature /* compatibility, for older versions of clang */
@@ -206,9 +208,11 @@
      inline int& operator%=(int&, const Name::Enum&) MOZ_DELETE; \
      inline int& operator&=(int&, const Name::Enum&) MOZ_DELETE; \
      inline int& operator|=(int&, const Name::Enum&) MOZ_DELETE; \
      inline int& operator^=(int&, const Name::Enum&) MOZ_DELETE; \
      inline int& operator<<=(int&, const Name::Enum&) MOZ_DELETE; \
      inline int& operator>>=(int&, const Name::Enum&) MOZ_DELETE;
 #endif
 
+#endif /* __cplusplus */
+
 #endif  /* mozilla_TypedEnum_h_ */
--- a/xpcom/base/Makefile.in
+++ b/xpcom/base/Makefile.in
@@ -49,16 +49,20 @@ CPPSRCS		= \
 ifeq ($(OS_ARCH),Linux)
 CPPSRCS += MapsMemoryReporter.cpp
 endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS		+= nsMacUtilsImpl.cpp
 endif
 
+CSRCS = \
+		nsErrorAssertsC.c \
+		$(NULL)
+
 EXPORTS		= \
 		nsAgg.h \
 		nsAutoRef.h \
 		nsCom.h \
 		nsDebugImpl.h \
 		nsIAllocator.h \
 		nsIID.h \
 		nsISizeOf.h \
--- a/xpcom/base/nsError.h
+++ b/xpcom/base/nsError.h
@@ -2,22 +2,19 @@
 /* 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/. */
 
 #ifndef nsError_h__
 #define nsError_h__
 
 #include "mozilla/Likely.h"
+#include "mozilla/StandardInteger.h"
 #include "mozilla/TypedEnum.h"
 
-#ifndef nscore_h___
-#include "nscore.h"  /* needed for nsresult */
-#endif
-
 /*
  * To add error code to your module, you need to do the following:
  *
  * 1) Add a module offset code.  Add yours to the bottom of the list
  *    right below this comment, adding 1.
  *
  * 2) In your module, define a header file which uses one of the
  *    NE_ERROR_GENERATExxxxxx macros.  Some examples below:
@@ -115,45 +112,63 @@
  * doesn't really work for nsresult.  We need constants like NS_OK with type
  * nsresult, but they can't be used in (e.g.) switch cases if they're objects.
  * But if we define them to be of type nsresult::Enum instead, that causes
  *   return foo ? F() : NS_ERROR_FAILURE;
  * to fail, because nsresult and nsresult::Enum are two distinct types and
  * either can be converted to the other, so it's ambiguous.  So we have to fall
  * back to a regular enum.
  */
-#if defined(__cplusplus)
 #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
   typedef enum class tag_nsresult : uint32_t
-#elif defined(MOZ_HAVE_CXX11_ENUM_TYPE)
-  /* Need underlying type for workaround of Microsoft compiler (Bug 794734) */
-  typedef enum tag_nsresult : uint32_t
-#else
-  /* no strong enums */
-  typedef enum tag_nsresult
-#endif
   {
     #undef ERROR
     #define ERROR(key, val) key = val
     #include "ErrorList.h"
     #undef ERROR
   } nsresult;
 
-#if defined(MOZ_HAVE_CXX11_STRONG_ENUMS)
-  /* We're using enum classes, so we need #define's to put the constants in
-   * global scope for compatibility with old code. */
+  /*
+   * enum classes don't place their initializers in the global scope, so we need
+   * #define's for compatibility with old code.
+   */
   #include "ErrorListCxxDefines.h"
-#endif
-#else /* defined(__cplusplus) */
-  /* C enum can't have a value outside the range of 'int'.
-   * C const can't initialize with an expression involving other variables
-   * even if it is const. So we have to fall back to bad old #defines. */
+#elif defined(MOZ_HAVE_CXX11_ENUM_TYPE)
+  typedef enum tag_nsresult : uint32_t
+  {
+    #undef ERROR
+    #define ERROR(key, val) key = val
+    #include "ErrorList.h"
+    #undef ERROR
+  } nsresult;
+#elif defined(__cplusplus)
+  /*
+   * We're C++ in an old compiler lacking enum classes *and* typed enums (likely
+   * gcc < 4.5.1 as clang/MSVC have long supported one or both), or compiler
+   * support is unknown.  Yet nsresult must have unsigned 32-bit representation.
+   * So just make it a typedef, and implement the constants with global consts.
+   */
+  typedef uint32_t nsresult;
+
+  const nsresult
+  #undef ERROR
+  #define ERROR(key, val) key = val
+  #include "ErrorList.h"
+  #undef ERROR
+    ;
+#else
+  /*
+   * C doesn't have any way to fix the type underlying an enum, and enum
+   * initializers can't have values outside the range of 'int'.  So typedef
+   * nsresult to the correct unsigned type, and fall back to using #defines for
+   * all error constants.
+   */
   typedef uint32_t nsresult;
   #include "ErrorListCDefines.h"
-#endif /* defined(__cplusplus) */
+#endif
 
 #undef SUCCESS_OR_FAILURE
 #undef SUCCESS
 #undef FAILURE
 
 /**
  * @name Standard Error Handling Macros
  * @return 0 or 1 (false/true with bool type for C++)
--- a/xpcom/base/nsErrorAsserts.cpp
+++ b/xpcom/base/nsErrorAsserts.cpp
@@ -1,7 +1,10 @@
+#include "mozilla/Assertions.h"
+
 #include "nsError.h"
-#include "mozilla/Assertions.h"
 
 // No reason to pull in Assertions.h for every single file that includes
 // nsError.h, so let's put this in its own .cpp file instead of in the .h.
+MOZ_STATIC_ASSERT(((nsresult)0) < ((nsresult)-1),
+                  "nsresult must be an unsigned type");
 MOZ_STATIC_ASSERT(sizeof(nsresult) == sizeof(uint32_t),
                   "nsresult must be 32 bits");
new file mode 100644
--- /dev/null
+++ b/xpcom/base/nsErrorAssertsC.c
@@ -0,0 +1,12 @@
+#include "mozilla/Assertions.h"
+
+#include "nsError.h"
+
+/*
+ * No reason to pull in Assertions.h for every single file that includes
+ * nsError.h, so let's put this in its own .c file instead of in the .h.
+ */
+MOZ_STATIC_ASSERT(((nsresult)0) < ((nsresult)-1),
+                  "nsresult must be an unsigned type");
+MOZ_STATIC_ASSERT(sizeof(nsresult) == sizeof(uint32_t),
+                  "nsresult must be 32 bits");
--- a/xpcom/base/nscore.h
+++ b/xpcom/base/nscore.h
@@ -320,18 +320,16 @@ typedef size_t(*nsMallocSizeOfFun)(const
  * IUnknown.
  */
 #ifdef XP_WIN
 typedef unsigned long nsrefcnt;
 #else
 typedef uint32_t nsrefcnt;
 #endif
 
-#include "nsError.h"
-
 /* ------------------------------------------------------------------------ */
 /* Casting macros for hiding C++ features from older compilers */
 
   /* under VC++ (Windows), we don't have autoconf yet */
 #if defined(_MSC_VER)
   #define HAVE_CPP_2BYTE_WCHAR_T
 #endif