From 1f6e8bd31577a55dd794c9fdde04cfe1c2400d5e Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Fri, 2 Apr 2010 12:58:11 -0500 Subject: [PATCH] Bug 551254: Allow reviewed+approved STL headers to be included through . ( and are provisionally in the list because of their use in libpr0n, but need to be reviewed in followup bug 556700 and bug 556701). r=ehsan,ted,zwol --- config/Makefile.in | 20 +++ config/autoconf.mk.in | 3 + config/config.mk | 2 +- config/gcc-stl-wrapper.template.h | 85 +++++++++ config/make-stl-wrappers.py | 87 ++++++++++ config/msvc-stl-wrapper.template.h | 96 ++++++++++ config/stl-headers | 19 ++ configure.in | 8 + js/src/config/config.mk | 2 +- testing/mochitest/ssltunnel/Makefile.in | 4 + toolkit/crashreporter/client/Makefile.in | 4 + .../src/client/windows/sender/Makefile.in | 1 + .../src/common/windows/Makefile.in | 1 + tools/trace-malloc/lib/Makefile.in | 1 + xpcom/glue/Makefile.in | 6 + xpcom/glue/functexcept.h | 164 ++++++++++++++++++ 16 files changed, 501 insertions(+), 2 deletions(-) create mode 100644 config/gcc-stl-wrapper.template.h create mode 100644 config/make-stl-wrappers.py create mode 100644 config/msvc-stl-wrapper.template.h create mode 100644 config/stl-headers create mode 100644 xpcom/glue/functexcept.h diff --git a/config/Makefile.in b/config/Makefile.in index 04b03d42484..9d491a76e74 100644 --- a/config/Makefile.in +++ b/config/Makefile.in @@ -137,6 +137,26 @@ export:: GARBAGE_DIRS += system_wrappers endif +ifdef WRAP_STL_INCLUDES +ifdef GCC_VERSION +stl_compiler = gcc +else +stl_compiler = msvc +endif +endif + +ifdef stl_compiler +stl-wrappers-sentinel: $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS) + $(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers + $(PYTHON) $(srcdir)/nsinstall.py stl_wrappers $(DIST) + touch stl-wrappers-sentinel + +export:: stl-wrappers-sentinel + +GARBAGE += stl-wrappers-sentinel +GARBAGE_DIRS += stl_wrappers +endif + install:: $(SYSINSTALL) $(IFLAGS1) $(DEPTH)/mozilla-config.h $(DESTDIR)$(includedir) diff --git a/config/autoconf.mk.in b/config/autoconf.mk.in index fc95db2c746..1908cfd73ca 100644 --- a/config/autoconf.mk.in +++ b/config/autoconf.mk.in @@ -359,6 +359,9 @@ HAVE_GCC3_ABI = @HAVE_GCC3_ABI@ INTEL_CC = @INTEL_CC@ INTEL_CXX = @INTEL_CXX@ +STL_FLAGS = @STL_FLAGS@ +WRAP_STL_INCLUDES = @WRAP_STL_INCLUDES@ + HOST_CC = @HOST_CC@ HOST_CXX = @HOST_CXX@ HOST_CFLAGS = @HOST_CFLAGS@ diff --git a/config/config.mk b/config/config.mk index f1525fa8d51..3e354b92dad 100644 --- a/config/config.mk +++ b/config/config.mk @@ -526,7 +526,7 @@ OS_COMPILE_CMMFLAGS += -fobjc-exceptions endif COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) -COMPILE_CXXFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) +COMPILE_CXXFLAGS = $(VISIBILITY_FLAGS) $(STL_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) diff --git a/config/gcc-stl-wrapper.template.h b/config/gcc-stl-wrapper.template.h new file mode 100644 index 00000000000..739f6651821 --- /dev/null +++ b/config/gcc-stl-wrapper.template.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* ***** 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 Mozilla Code. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Jones + * + * 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 ***** */ + +#ifndef mozilla_${HEADER}_h +#define mozilla_${HEADER}_h + +#if __EXCEPTIONS +# error "STL code can only be used with -fno-exceptions" +#endif + +// See if we're in code that can use mozalloc. NB: this duplicates +// code in nscore.h because nscore.h pulls in prtypes.h, and chromium +// can't build with that being included before base/basictypes.h. +#if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC) +# include // to give mozalloc std::bad_alloc +# include // to give mozalloc malloc/free decls +# include +# include "mozilla/mozalloc.h" +#else +# error "STL code can only be used with infallible ::operator new()" +#endif + +#if defined(DEBUG) && !defined(_GLIBCXX_DEBUG) +// Enable checked iterators and other goodies +// +// FIXME/bug 551254: gcc's debug STL implementation requires -frtti. +// Figure out how to resolve this with -fno-rtti. Maybe build with +// -frtti in DEBUG builds? +// +// # define _GLIBCXX_DEBUG 1 +#endif + +#pragma GCC visibility push(default) +#include_next <${HEADER}> +#pragma GCC visibility pop + +// gcc calls a __throw_*() function from bits/functexcept.h when it +// wants to "throw an exception". functexcept exists nominally to +// support -fno-exceptions, but since we'll always use the system +// libstdc++, and it's compiled with exceptions, then in practice +// these __throw_*() functions will always throw exceptions (shades of +// -fshort-wchar). We don't want that and so define our own inlined +// __throw_*(). +#ifndef mozilla_functexcept_h +# include "mozilla/functexcept.h" +#endif + +#endif // if mozilla_${HEADER}_h diff --git a/config/make-stl-wrappers.py b/config/make-stl-wrappers.py new file mode 100644 index 00000000000..106dbd6547b --- /dev/null +++ b/config/make-stl-wrappers.py @@ -0,0 +1,87 @@ +# ***** 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 mozilla.org code. +# +# The Initial Developer of the Original Code is +# The Mozilla Foundation +# Portions created by the Initial Developer are Copyright (C) 2010 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Chris Jones +# +# Alternatively, the contents of this file may be used under the terms of +# either of 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 ***** + +import os, re, string, sys + +def find_in_path(file, searchpath): + for dir in searchpath.split(os.pathsep): + f = os.path.join(dir, file) + if os.path.exists(f): + return f + return '' + +def header_path(header, compiler): + if compiler == 'gcc': + # we use include_next on gcc + return header + elif compiler == 'msvc': + return find_in_path(header, os.environ.get('INCLUDE', '')) + else: + # hope someone notices this ... + raise NotImplementedError, compiler + +def is_comment(line): + return re.match(r'\s*#.*', line) + +def main(outdir, compiler, template_file, header_list_file): + if not os.path.isdir(outdir): + os.mkdir(outdir) + + template = open(template_file, 'r').read() + + for header in open(header_list_file, 'r'): + header = header.rstrip() + if 0 == len(header) or is_comment(header): + continue + + path = header_path(header, compiler) + try: + f = open(os.path.join(outdir, header), 'w') + f.write(string.Template(template).substitute(HEADER=header, + HEADER_PATH=path)) + finally: + f.close() + + +if __name__ == '__main__': + if 5 != len(sys.argv): + print >>sys.stderr, """Usage: + python %s OUT_DIR ('msvc'|'gcc') TEMPLATE_FILE HEADER_LIST_FILE +"""% (sys.argv[0]) + sys.exit(1) + + main(*sys.argv[1:]) diff --git a/config/msvc-stl-wrapper.template.h b/config/msvc-stl-wrapper.template.h new file mode 100644 index 00000000000..97d45c617c8 --- /dev/null +++ b/config/msvc-stl-wrapper.template.h @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=8 et : + */ +/* ***** 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 Mozilla Code. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Jones + * + * 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 ***** */ + +#ifndef mozilla_${HEADER}_h +#define mozilla_${HEADER}_h + +#if _HAS_EXCEPTIONS +# error "STL code can only be used with -fno-exceptions" +#endif + +// See if we're in code that can use mozalloc. NB: this duplicates +// code in nscore.h because nscore.h pulls in prtypes.h, and chromium +// can't build with that being included before base/basictypes.h. +#if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC) +# include // to give mozalloc std::bad_alloc +# include // to give mozalloc malloc/free decls +# include +# include "mozilla/mozalloc.h" +#else +# error "STL code can only be used with infallible ::operator new()" +#endif + +#ifdef DEBUG +// From +// http://msdn.microsoft.com/en-us/library/aa985982%28VS.80%29.aspx +// and +// http://msdn.microsoft.com/en-us/library/aa985965%28VS.80%29.aspx +// there appear to be two types of STL container checking. The +// former is enabled by -D_DEBUG (which is implied by -DDEBUG), and +// looks to be full generation/mutation checked iterators as done by +// _GLIBCXX_DEBUG. The latter appears to just be bounds checking, and +// is enabled by the following macros. It appears that the _DEBUG +// iterators subsume _SECURE_SCL, and the following settings are +// default anyway, so we'll just leave this commented out. +//# define _SECURE_SCL 1 +//# define _SECURE_SCL_THROWS 0 +#else +// Note: _SECURE_SCL iterators are on by default in opt builds. We +// could leave them on, but since gcc doesn't, we might as well +// preserve that behavior for perf reasons. nsTArray is in the same +// camp as gcc. Can revisit later. +// +// FIXME/bug 551254: because we're not wrapping all the STL headers we +// use, undefining this here can cause some headers to be built with +// iterator checking and others not. Turning this off until we have a +// better plan. +//# undef _SECURE_SCL +#endif + +// We know that code won't be able to catch exceptions, but that's OK +// because we're not throwing them. +#pragma warning( push ) +#pragma warning( disable : 4530 ) + +#include <${HEADER_PATH}> + +#pragma warning( pop ) + +#endif // if mozilla_${HEADER}_h diff --git a/config/stl-headers b/config/stl-headers new file mode 100644 index 00000000000..69790c9a1eb --- /dev/null +++ b/config/stl-headers @@ -0,0 +1,19 @@ +# +# This file contains a list the of STL headers that have been reviewed +# for exception safety and approved. See +# +# https://bugzilla.mozilla.org/show_bug.cgi?id=551254 +# +# At build time, each header listed here is converted into a "wrapper +# header" that is installed into dist/stl_includes. +# +# If you would like to request a new STL header be added, please +# file a Core:XPCOM bug with a title like "STL: Review exception +# safety of for gcc and MSVC". +# + +# FIXME: these headers haven't been reviewed yet, but we use them +# unsafely in modules/libpr0n, so we might as well prevent it from +# throwing exceptions +algorithm +vector diff --git a/configure.in b/configure.in index 8791dc36eeb..83c05e49f67 100644 --- a/configure.in +++ b/configure.in @@ -759,6 +759,9 @@ EOF AC_DEFINE_UNQUOTED(MOZ_NTDDI_WS03, 0x05020000) AC_DEFINE_UNQUOTED(MOZ_NTDDI_LONGHORN, 0x06000000) AC_DEFINE_UNQUOTED(MOZ_NTDDI_WIN7, 0x06010000) + + STL_FLAGS='-D_HAS_EXCEPTIONS=0 -I$(DIST)/stl_wrappers' + WRAP_STL_INCLUDES=1 ;; esac @@ -807,6 +810,9 @@ AC_SUBST(GNU_CXX) AC_SUBST(INTEL_CC) AC_SUBST(INTEL_CXX) +AC_SUBST(STL_FLAGS) +AC_SUBST(WRAP_STL_INCLUDES) + dnl ======================================================== dnl Checks for programs. dnl ======================================================== @@ -3126,6 +3132,8 @@ EOF "$ac_cv_have_visibility_class_bug" = "no"; then VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h' WRAP_SYSTEM_INCLUDES=1 + STL_FLAGS='-I$(DIST)/stl_wrappers' + WRAP_STL_INCLUDES=1 else VISIBILITY_FLAGS='-fvisibility=hidden' fi # have visibility pragma bug diff --git a/js/src/config/config.mk b/js/src/config/config.mk index f1525fa8d51..3e354b92dad 100644 --- a/js/src/config/config.mk +++ b/js/src/config/config.mk @@ -526,7 +526,7 @@ OS_COMPILE_CMMFLAGS += -fobjc-exceptions endif COMPILE_CFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CFLAGS) -COMPILE_CXXFLAGS = $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) +COMPILE_CXXFLAGS = $(VISIBILITY_FLAGS) $(STL_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(CXXFLAGS) $(RTL_FLAGS) $(OS_COMPILE_CXXFLAGS) COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) diff --git a/testing/mochitest/ssltunnel/Makefile.in b/testing/mochitest/ssltunnel/Makefile.in index 71a3d949567..160b97fc8e1 100644 --- a/testing/mochitest/ssltunnel/Makefile.in +++ b/testing/mochitest/ssltunnel/Makefile.in @@ -43,6 +43,10 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk +# This isn't XPCOM code, but it wants to use STL, so disable the STL +# wrappers +STL_FLAGS = + PROGRAM = ssltunnel$(BIN_SUFFIX) CPPSRCS = ssltunnel.cpp diff --git a/toolkit/crashreporter/client/Makefile.in b/toolkit/crashreporter/client/Makefile.in index f16b8baa235..f62d3b32cbf 100644 --- a/toolkit/crashreporter/client/Makefile.in +++ b/toolkit/crashreporter/client/Makefile.in @@ -44,6 +44,10 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk +# Don't use the STL wrappers in the crashreporter clients; they don't +# link with -lmozalloc, and it really doesn't matter here anyway. +STL_FLAGS = + PROGRAM = crashreporter$(BIN_SUFFIX) DIST_PROGRAM = crashreporter$(BIN_SUFFIX) diff --git a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/Makefile.in b/toolkit/crashreporter/google-breakpad/src/client/windows/sender/Makefile.in index 7d7eafe5088..3f86440940d 100644 --- a/toolkit/crashreporter/google-breakpad/src/client/windows/sender/Makefile.in +++ b/toolkit/crashreporter/google-breakpad/src/client/windows/sender/Makefile.in @@ -46,6 +46,7 @@ LIBRARY_NAME = crash_report_sender_s LOCAL_INCLUDES = -I$(srcdir)/../../.. DEFINES += -DUNICODE -D_UNICODE +STL_FLAGS = CPPSRCS = \ crash_report_sender.cc \ diff --git a/toolkit/crashreporter/google-breakpad/src/common/windows/Makefile.in b/toolkit/crashreporter/google-breakpad/src/common/windows/Makefile.in index ff74819a30a..1aeebf78435 100644 --- a/toolkit/crashreporter/google-breakpad/src/common/windows/Makefile.in +++ b/toolkit/crashreporter/google-breakpad/src/common/windows/Makefile.in @@ -46,6 +46,7 @@ LIBRARY_NAME = breakpad_windows_common_s LOCAL_INCLUDES = -I$(srcdir)/../.. DEFINES += -DUNICODE -D_UNICODE +STL_FLAGS = CPPSRCS = \ guid_string.cc \ diff --git a/tools/trace-malloc/lib/Makefile.in b/tools/trace-malloc/lib/Makefile.in index 33b890396ce..fe91cb63b57 100644 --- a/tools/trace-malloc/lib/Makefile.in +++ b/tools/trace-malloc/lib/Makefile.in @@ -51,6 +51,7 @@ FORCE_STATIC_LIB = 1 LIBXUL_LIBRARY = 1 +STL_FLAGS = CSRCS = \ nsTraceMalloc.c \ diff --git a/xpcom/glue/Makefile.in b/xpcom/glue/Makefile.in index 5db33876c0e..5b64237f6be 100644 --- a/xpcom/glue/Makefile.in +++ b/xpcom/glue/Makefile.in @@ -134,6 +134,12 @@ EXPORTS_mozilla = \ SSE.h \ $(NULL) +ifdef WRAP_STL_INCLUDES +ifdef GCC_VERSION +EXPORTS_mozilla += functexcept.h +endif +endif + SDK_LIBRARY = \ $(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \ $(NULL) diff --git a/xpcom/glue/functexcept.h b/xpcom/glue/functexcept.h new file mode 100644 index 00000000000..5492f8dd737 --- /dev/null +++ b/xpcom/glue/functexcept.h @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: sw=2 ts=2 et : + */ +/* ***** 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 Mozilla Code + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Chris Jones + * + * 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 ***** */ + +#ifndef mozilla_functexcept_h +#define mozilla_functexcept_h + +#include +#include +#include + +// 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. + +// NB: It would be nice to #include "nsDebug.h" and use +// NS_RUNTIMEABORT(), but because this file is used within chromium, +// and nsDebug pulls in nscore, and nscore pulls in prtypes, and +// chromium can't build with prtypes being included before +// base/basictypes, then we have to roll our own aborting impl. + +// Assume that if we're building with gcc, we're on a platform where +// abort() is fatal and triggers breakpad. +#define MOZ_FE_ABORT(_msg) \ + do { \ + fputs(_msg, stderr); \ + fputs("\n", stderr); \ + abort(); \ + } while (0) + +namespace std { + +inline void NS_NORETURN +__throw_bad_exception(void) +{ + MOZ_FE_ABORT("fatal: STL threw bad_exception"); +} + +inline void NS_NORETURN +__throw_bad_alloc(void) +{ + MOZ_FE_ABORT("fatal: STL threw bad_alloc"); +} + +inline void NS_NORETURN +__throw_bad_cast(void) +{ + MOZ_FE_ABORT("fatal: STL threw bad_cast"); +} + +inline void NS_NORETURN +__throw_bad_typeid(void) +{ + MOZ_FE_ABORT("fatal: STL threw bad_typeid"); +} + +inline void NS_NORETURN +__throw_logic_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_domain_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_invalid_argument(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_length_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_out_of_range(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_runtime_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_range_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_overflow_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_underflow_error(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_ios_failure(const char* msg) +{ + MOZ_FE_ABORT(msg); +} + +inline void NS_NORETURN +__throw_system_error(int err) +{ + char error[128]; + snprintf(error, sizeof(error)-1, + "fatal: STL threw system_error: %s (%d)", strerror(err), err); + MOZ_FE_ABORT(error); +} + +} // namespace std + +#endif // mozilla_functexcept_h