diff -r 9b2c774a6b05 src/backend/tcop/Makefile --- a/src/backend/tcop/Makefile +++ b/src/backend/tcop/Makefile @@ -14,6 +14,11 @@ OBJS= dest.o fastpath.o postgres.o pquery.o utility.o +# Designate modules to be compiled as C++ when 'configure --enable-cplusplus' +ifeq ($(enable_cplusplus),yes) +CXXOBJS = postgres.o +endif + ifneq (,$(filter $(PORTNAME),cygwin win32)) override CPPFLAGS += -DWIN32_STACK_RLIMIT=$(WIN32_STACK_RLIMIT) endif diff -r 9b2c774a6b05 src/backend/tcop/postgres.c --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -33,6 +33,17 @@ #endif #ifdef HAVE_GETOPT_H #include +#endif + +#ifdef ENABLE_CPLUSPLUS +#ifndef __cplusplus +#error --enable-cplusplus configure option specified; this file should be compiled as C++ +#endif +#include +#endif + +#ifdef __cplusplus +extern "C" { #endif #ifndef HAVE_GETRUSAGE @@ -163,6 +174,11 @@ #endif /* TCOP_DONTUSENEWLINE */ +#ifdef __cplusplus +} /* extern "C" */ +#endif + + /* ---------------------------------------------------------------- * decls for routines only used in this file * ---------------------------------------------------------------- @@ -1212,7 +1228,7 @@ if (log_parser_stats) ResetUsage(); - query = parse_analyze_varparams(copyObject(raw_parse_tree), + query = parse_analyze_varparams((Node *)copyObject(raw_parse_tree), query_string, ¶mTypes, &numParams); @@ -1679,7 +1695,7 @@ * we have to make a copy of the parse trees. FIXME someday. */ oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal)); - query_list = copyObject(cplan->stmt_list); + query_list = (List *)copyObject(cplan->stmt_list); plan_list = pg_plan_queries(query_list, 0, params, true); MemoryContextSwitchTo(oldContext); @@ -2791,6 +2807,29 @@ return NULL; } + + +#ifdef ENABLE_CPLUSPLUS +/* + * PostgresMainUncaught + * Called when C++ code throws an exception which is not caught. + * + * NB: On some platforms when C++ code calls C code, and the C code calls + * a deeper layer of C++ code, the outer C++ code can't catch exceptions + * thrown by the inner C++ code. The search for a matching 'catch' is + * abandoned upon encountering an intervening C stack frame, and the + * exception is considered uncaught. + */ +static void +PostgresMainUncaught() +{ + /* Context callbacks might not work right if call stack has been unwound */ + error_context_stack = NULL; + + elog(FATAL, "Unexpected internal error: Unhandled C++ exception"); + abort(); /* not reached */ +} +#endif /* ENABLE_CPLUSPLUS */ /* ---------------------------------------------------------------- @@ -2850,6 +2889,11 @@ /* Set up reference point for stack depth checking */ stack_base_ptr = &stack_base; +#ifdef ENABLE_CPLUSPLUS + /* Any unhandled C++ exception is to be treated as a FATAL error. */ + std::set_terminate(PostgresMainUncaught); +#endif + /* Compute paths, if we didn't inherit them from postmaster */ if (my_exec_path[0] == '\0') { @@ -3108,10 +3152,10 @@ char *name; char *value; - name = lfirst(gucopts); + name = (char *)lfirst(gucopts); gucopts = lnext(gucopts); - value = lfirst(gucopts); + value = (char *)lfirst(gucopts); gucopts = lnext(gucopts); if (IsSuperuserConfigOption(name))