Bug 711775 - Implement MOZ_NORETURN to encapsulate this-function-doesn't-return semantics. r=cjones
--- a/Makefile.in
+++ b/Makefile.in
@@ -57,16 +57,17 @@ TIERS += base
#
# tier "base" - basic setup
#
tier_base_dirs = \
config \
build \
probes \
+ mfbt \
$(NULL)
ifndef LIBXUL_SDK
ifeq (android,$(MOZ_WIDGET_TOOLKIT))
tier_base_dirs += other-licenses/android other-licenses/skia-npapi
endif
tier_base_dirs += memory
--- a/configure.in
+++ b/configure.in
@@ -4136,23 +4136,16 @@ AC_CACHE_CHECK(for __attribute__((malloc
AC_CACHE_CHECK(for __attribute__((warn_unused_result)),
ac_cv_attribute_warn_unused,
[AC_TRY_COMPILE([int f(void) __attribute__((warn_unused_result));],
[],
ac_cv_attribute_warn_unused=yes,
ac_cv_attribute_warn_unused=no)])
-AC_CACHE_CHECK(for __attribute__((noreturn)),
- ac_cv_attribute_noreturn,
- [AC_TRY_COMPILE([void f(void) __attribute__((noreturn));],
- [],
- ac_cv_attribute_noreturn=yes,
- ac_cv_attribute_noreturn=no)])
-
dnl End of C++ language/feature checks
AC_LANG_C
dnl ========================================================
dnl = Internationalization checks
dnl ========================================================
dnl
dnl Internationalization and Locale support is different
@@ -4198,22 +4191,16 @@ else
fi
if test "$ac_cv_attribute_warn_unused" = yes ; then
AC_DEFINE(NS_WARN_UNUSED_RESULT, [__attribute__((warn_unused_result))])
else
AC_DEFINE(NS_WARN_UNUSED_RESULT,)
fi
-if test "$ac_cv_attribute_noreturn" = yes ; then
- AC_DEFINE(NS_NORETURN, [__attribute__((noreturn))])
-else
- AC_DEFINE(NS_NORETURN,)
-fi
-
dnl We can't run TRY_COMPILE tests on Windows, so hard-code some
dnl features that Windows actually does support.
if test -n "$SKIP_COMPILER_CHECKS"; then
dnl Windows has malloc.h
AC_DEFINE(MALLOC_H, [<malloc.h>])
AC_DEFINE(HAVE_FORCEINLINE)
AC_DEFINE(HAVE_LOCALECONV)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -35,16 +35,17 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_dom_ContentChild_h
#define mozilla_dom_ContentChild_h
+#include "mozilla/Attributes.h"
#include "mozilla/dom/PContentChild.h"
#include "nsTArray.h"
#include "nsIConsoleListener.h"
struct ChromePackage;
class nsIObserver;
struct ResourceMapping;
@@ -189,17 +190,17 @@ private:
NS_OVERRIDE
virtual void ProcessingError(Result what);
/**
* Exit *now*. Do not shut down XPCOM, do not pass Go, do not run
* static destructors, do not collect $200.
*/
- NS_NORETURN void QuickExit();
+ MOZ_NORETURN void QuickExit();
InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
nsRefPtr<ConsoleListener> mConsoleListener;
#ifdef ANDROID
gfxIntSize mScreenSize;
#endif
AppInfo mAppInfo;
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -35,16 +35,18 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef dom_plugins_PluginModuleChild_h
#define dom_plugins_PluginModuleChild_h 1
+#include "mozilla/Attributes.h"
+
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "prlink.h"
#include "npapi.h"
@@ -187,17 +189,17 @@ protected:
virtual bool
AnswerPCrashReporterConstructor(PCrashReporterChild* actor,
mozilla::dom::NativeThreadId* id,
PRUint32* processType);
virtual void
ActorDestroy(ActorDestroyReason why);
- NS_NORETURN void QuickExit();
+ MOZ_NORETURN void QuickExit();
NS_OVERRIDE virtual bool
RecvProcessNativeEventsInRPCCall();
public:
PluginModuleChild();
virtual ~PluginModuleChild();
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -270,34 +270,20 @@ EXPORTS_js = \
HashTable.h \
LegacyIntTypes.h \
TemplateLib.h \
Utility.h \
Vector.h \
$(NULL)
###############################################
-# BEGIN include sources for low-level code shared with Gecko
+# BEGIN include sources for low-level code shared with mfbt
#
-VPATH += \
- $(srcdir)/../../mfbt \
- $(NULL)
-
-EXPORTS_NAMESPACES += mozilla
-
-EXPORTS_mozilla = \
- Attributes.h \
- GuardObjects.h \
- MSStdInt.h \
- RangedPtr.h \
- RefPtr.h \
- StdInt.h \
- Types.h \
- Util.h \
- $(NULL)
+VPATH += $(srcdir)/../../mfbt
+include $(srcdir)/../../mfbt/exported_headers.mk
ifdef ENABLE_METHODJIT
###############################################
# BEGIN include sources for the method JIT
#
VPATH += $(srcdir)/methodjit
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -3861,23 +3861,16 @@ AC_CACHE_CHECK(for __attribute__((malloc
AC_CACHE_CHECK(for __attribute__((warn_unused_result)),
ac_cv_attribute_warn_unused,
[AC_TRY_COMPILE([int f(void) __attribute__((warn_unused_result));],
[],
ac_cv_attribute_warn_unused=yes,
ac_cv_attribute_warn_unused=no)])
-AC_CACHE_CHECK(for __attribute__((noreturn)),
- ac_cv_attribute_noreturn,
- [AC_TRY_COMPILE([void f(void) __attribute__((noreturn));],
- [],
- ac_cv_attribute_noreturn=yes,
- ac_cv_attribute_noreturn=no)])
-
dnl End of C++ language/feature checks
AC_LANG_C
dnl ========================================================
dnl = Internationalization checks
dnl ========================================================
dnl
dnl Internationalization and Locale support is different
@@ -3923,22 +3916,16 @@ else
fi
if test "$ac_cv_attribute_warn_unused" = yes ; then
AC_DEFINE(NS_WARN_UNUSED_RESULT, [__attribute__((warn_unused_result))])
else
AC_DEFINE(NS_WARN_UNUSED_RESULT,)
fi
-if test "$ac_cv_attribute_noreturn" = yes ; then
- AC_DEFINE(NS_NORETURN, [__attribute__((noreturn))])
-else
- AC_DEFINE(NS_NORETURN,)
-fi
-
dnl We can't run TRY_COMPILE tests on Windows, so hard-code some
dnl features that Windows actually does support.
if test -n "$SKIP_COMPILER_CHECKS"; then
dnl Windows has malloc.h
AC_DEFINE(MALLOC_H, [<malloc.h>])
AC_DEFINE(HAVE_FORCEINLINE)
AC_DEFINE(HAVE_LOCALECONV)
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -33,19 +33,20 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-/*
- * PR assertion checker.
- */
+/* Various JS utility functions. */
+
+#include "mozilla/Attributes.h"
+
#include <stdio.h>
#include <stdlib.h>
#include "jstypes.h"
#include "jsstdint.h"
#include "jsutil.h"
#ifdef WIN32
# include "jswin.h"
--- a/memory/mozalloc/mozalloc_abort.h
+++ b/memory/mozalloc/mozalloc_abort.h
@@ -36,16 +36,18 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_mozalloc_abort_h
#define mozilla_mozalloc_abort_h
+#include "mozilla/Attributes.h"
+
#if defined(MOZALLOC_EXPORT)
// do nothing: it's been defined to __declspec(dllexport) by
// mozalloc*.cpp on platforms where that's required
#elif defined(XP_WIN) || (defined(XP_OS2) && defined(__declspec))
# define MOZALLOC_EXPORT __declspec(dllimport)
#elif defined(HAVE_VISIBILITY_ATTRIBUTE)
/* Make sure symbols are still exported even if we're wrapped in a
* |visibility push(hidden)| blanket. */
@@ -53,12 +55,12 @@
#else
# define MOZALLOC_EXPORT
#endif
/**
* Terminate this process in such a way that breakpad is triggered, if
* at all possible.
*/
-MOZALLOC_EXPORT void mozalloc_abort(const char* const msg) NS_NORETURN;
+MOZ_NORETURN MOZALLOC_EXPORT void mozalloc_abort(const char* const msg);
#endif /* ifndef mozilla_mozalloc_abort_h */
--- a/memory/mozalloc/throw_gcc.h
+++ b/memory/mozalloc/throw_gcc.h
@@ -36,117 +36,120 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_throw_gcc_h
#define mozilla_throw_gcc_h
+#include "mozilla/Attributes.h"
+#include "mozilla/Util.h"
+
#include <stdio.h> // snprintf
#include <string.h> // strerror
// For gcc, we define these inline to abort so that we're absolutely
// certain that (i) no exceptions are thrown from Gecko; (ii) these
// errors are always terminal and caught by breakpad.
#include "mozilla/mozalloc_abort.h"
namespace std {
// NB: user code is not supposed to touch the std:: namespace. We're
// doing this after careful review because we want to define our own
// exception throwing semantics. Don't try this at home!
-NS_ALWAYS_INLINE inline void NS_NORETURN
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
__throw_bad_exception(void)
{
mozalloc_abort("fatal: STL threw bad_exception");
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
__throw_bad_alloc(void)
{
mozalloc_abort("fatal: STL threw bad_alloc");
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
__throw_bad_cast(void)
{
mozalloc_abort("fatal: STL threw bad_cast");
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
__throw_bad_typeid(void)
{
mozalloc_abort("fatal: STL threw bad_typeid");
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
__throw_logic_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
__throw_domain_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_invalid_argument(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_invalid_argument(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_length_error(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_length_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_out_of_range(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_out_of_range(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_runtime_error(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_runtime_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_range_error(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_range_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_overflow_error(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_overflow_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_underflow_error(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_underflow_error(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_ios_failure(const char* msg)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_ios_failure(const char* msg)
{
mozalloc_abort(msg);
}
-NS_ALWAYS_INLINE inline void NS_NORETURN
-__throw_system_error(int err)
+MOZ_NORETURN MOZ_ALWAYS_INLINE void
+__throw_system_error(int err)
{
char error[128];
snprintf(error, sizeof(error)-1,
"fatal: STL threw system_error: %s (%d)", strerror(err), err);
mozalloc_abort(error);
}
} // namespace std
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -33,30 +33,26 @@
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
-/* Implementations of various C++ class and method modifier attributes. */
+/* Implementations of various class and method modifier attributes. */
#ifndef mozilla_Attributes_h_
#define mozilla_Attributes_h_
/*
* This header does not include any other headers so that it can be included by
* code that is (only currently) mfbt-incompatible.
*/
-#ifndef __cplusplus
-#error "mozilla/Attributes.h is only relevant to C++ code."
-#endif
-
/*
* g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
* without warnings (functionality used by the macros below). These modes are
* detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
* standardly, by checking whether __cplusplus has a C++11 or greater value.
* Current versions of g++ do not correctly set __cplusplus, so we check both
* for forward compatibility.
*/
@@ -71,16 +67,19 @@
# endif
# if __has_extension(cxx_deleted_functions)
# define MOZ_HAVE_CXX11_DELETE
# endif
# if __has_extension(cxx_override_control)
# define MOZ_HAVE_CXX11_OVERRIDE
# define MOZ_HAVE_CXX11_FINAL final
# endif
+# if __has_attribute(noreturn)
+# define MOZ_HAVE_NORETURN __attribute__((noreturn))
+# endif
#elif defined(__GNUC__)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if __GNUC__ > 4
# define MOZ_HAVE_CXX11_DELETE
# define MOZ_HAVE_CXX11_OVERRIDE
# define MOZ_HAVE_CXX11_FINAL final
# elif __GNUC__ == 4
# if __GNUC_MINOR__ >= 7
@@ -96,25 +95,49 @@
# if __GNUC__ > 4
# define MOZ_HAVE_CXX11_FINAL __final
# elif __GNUC__ == 4
# if __GNUC_MINOR__ >= 7
# define MOZ_HAVE_CXX11_FINAL __final
# endif
# endif
# endif
+# define MOZ_HAVE_NORETURN __attribute__((noreturn))
#elif defined(_MSC_VER)
# if _MSC_VER >= 1400
# define MOZ_HAVE_CXX11_OVERRIDE
/* MSVC currently spells "final" as "sealed". */
# define MOZ_HAVE_CXX11_FINAL sealed
# endif
+# define MOZ_HAVE_NORETURN __declspec(noreturn)
#endif
/*
+ * MOZ_NORETURN, specified at the start of a function declaration, indicates
+ * that the given function does not return. (The function definition does not
+ * need to be annotated.)
+ *
+ * MOZ_NORETURN void abort(const char* msg);
+ *
+ * This modifier permits the compiler to optimize code assuming a call to such a
+ * function will never return. It also enables the compiler to avoid spurious
+ * warnings about not initializing variables, or about any other seemingly-dodgy
+ * operations performed after the function returns.
+ *
+ * This modifier does not affect the corresponding function's linking behavior.
+ */
+#if defined(MOZ_HAVE_NORETURN)
+# define MOZ_NORETURN MOZ_HAVE_NORETURN
+#else
+# define MOZ_NORETURN /* no support */
+#endif
+
+#ifdef __cplusplus
+
+/*
* MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
* method declaration, attempts to delete that method from the corresponding
* class. An attempt to use the method will always produce an error *at compile
* time* (instead of sometimes as late as link time) when this macro can be
* implemented. For example, you can use MOZ_DELETE to produce classes with no
* implicit copy constructor or assignment operator:
*
* struct NonCopyable
@@ -242,9 +265,11 @@
* only as documentation.
*/
#if defined(MOZ_HAVE_CXX11_FINAL)
# define MOZ_FINAL MOZ_HAVE_CXX11_FINAL
#else
# define MOZ_FINAL /* no support */
#endif
+#endif /* __cplusplus */
+
#endif /* mozilla_Attributes_h_ */
new file mode 100644
--- /dev/null
+++ b/mfbt/Makefile.in
@@ -0,0 +1,52 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla Framework Based on Templates.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Jeff Walden <jwalden+code@mit.edu>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS =
+
+# exported_headers.mk defines the headers exported by mfbt. It is included by
+# mfbt itself and by the JS engine, which, when built standalone, must do the
+# work to install mfbt's exported headers itself.
+include $(srcdir)/exported_headers.mk
+
+include $(topsrcdir)/config/rules.mk
--- a/mfbt/Util.h
+++ b/mfbt/Util.h
@@ -35,16 +35,17 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_Util_h_
#define mozilla_Util_h_
+#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
/*
* XXX: we're cheating here in order to avoid creating object files
* for mfbt /just/ to provide a function like FatalError() to be used
* by MOZ_ASSERT(). (It'll happen eventually, but for just ASSERT()
* it isn't worth the pain.) JS_Assert(), although unfortunately
* named, is part of SpiderMonkey's stable, external API, so this
new file mode 100644
--- /dev/null
+++ b/mfbt/exported_headers.mk
@@ -0,0 +1,53 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Mozilla Framework Based on Templates.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Jeff Walden <jwalden+code@mit.edu>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# This file defines the headers exported by mfbt. It is included by mfbt
+# itself and by the JS engine, which, when built standalone, must install
+# mfbt's exported headers itself.
+
+EXPORTS_NAMESPACES += mozilla
+
+EXPORTS_mozilla += \
+ Attributes.h \
+ GuardObjects.h \
+ MSStdInt.h \
+ RangedPtr.h \
+ RefPtr.h \
+ StdInt.h \
+ Types.h \
+ Util.h \
+ $(NULL)