ereport-with-do-while-1.patch
text/x-diff
Filename: ereport-with-do-while-1.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/bootstrap/bootscanner.l | 6 | 1 |
| src/backend/parser/scan.l | 8 | 1 |
| src/backend/replication/repl_scanner.l | 7 | 1 |
| src/backend/utils/error/elog.c | 12 | 0 |
| src/include/utils/elog.h | 16 | 7 |
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index bdd7dcb..b97bee4 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -42,8 +42,13 @@
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#undef fprintf
-#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
+#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
+static void
+fprintf_to_ereport(char *fmt, const char *msg)
+{
+ ereport(ERROR, (errmsg_internal("%s", msg)));
+}
static int yyline = 1; /* line number for error reporting */
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 622cb1f..877345b 100644
--- a/src/backend/parser/scan.l
+++ b/src/backend/parser/scan.l
@@ -42,7 +42,14 @@
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#undef fprintf
-#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
+#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
+
+static void
+fprintf_to_ereport(char *fmt, const char *msg)
+{
+ ereport(ERROR, (errmsg_internal("%s", msg)));
+}
+
/*
* GUC variables. This is a DIRECT violation of the warning given at the
diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l
index 9ccf02a..b62625b 100644
--- a/src/backend/replication/repl_scanner.l
+++ b/src/backend/replication/repl_scanner.l
@@ -19,7 +19,13 @@
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
#undef fprintf
-#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
+#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg)
+
+static void
+fprintf_to_ereport(char *fmt, const char *msg)
+{
+ ereport(ERROR, (errmsg_internal("%s", msg)));
+}
/* Handle to the buffer that the lexer uses internally */
static YY_BUFFER_STATE scanbufhandle;
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index e710f22..92940e9 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -380,6 +380,18 @@ errstart(int elevel, const char *filename, int lineno,
return true;
}
+void
+errfinish_noreturn(int dummy,...)
+{
+#ifdef USE_ASSERT_CHECKING
+ ErrorData *edata = &errordata[errordata_stack_depth];
+ int elevel = edata->elevel;
+ Assert(elevel >= ERROR);
+#endif
+ errfinish(dummy);
+ abort();
+}
+
/*
* errfinish --- end an error-reporting cycle
*
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index cbbda04..523ce5c 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -101,15 +101,23 @@
* ereport_domain() directly, or preferably they can override the TEXTDOMAIN
* macro.
*
- * When elevel >= ERROR, we add an abort() call to give the compiler a hint
- * that the ereport() expansion will not return, but the abort() isn't actually
- * reached because the longjmp happens in errfinish().
+ * When elevel >= ERROR, we use errfinish_noreturn, which is identical to
+ * errfinish, but is annotated with the noreturn compiler attribute to tell
+ * the compiler that it doesn't return.
*----------
*/
-#define ereport_domain(elevel, domain, rest) \
- (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \
- (errfinish rest) : (void) 0), \
- ((elevel) >= ERROR ? abort() : (void) 0)
+#define ereport_domain(elevel, domain, rest) \
+ do { \
+ const int elevel_ = elevel; \
+ if (errstart(elevel_,__FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) || elevel_>= ERROR) \
+ { \
+ (void) rest; \
+ if (elevel_>= ERROR) \
+ errfinish_noreturn(1); \
+ else \
+ errfinish(1); \
+ } \
+ } while(0)
#define ereport(elevel, rest) \
ereport_domain(elevel, TEXTDOMAIN, rest)
@@ -119,6 +127,7 @@
extern bool errstart(int elevel, const char *filename, int lineno,
const char *funcname, const char *domain);
extern void errfinish(int dummy,...);
+extern void errfinish_noreturn(int dummy,...) __attribute__((noreturn));
extern int errcode(int sqlerrcode);