elog/ereport noreturn decoration - Mailing list pgsql-hackers

From Peter Eisentraut
Subject elog/ereport noreturn decoration
Date
Msg-id 1341002113.488.16.camel@vanquo.pezone.net
Whole thread Raw
Responses Re: elog/ereport noreturn decoration  (Tom Lane <tgl@sss.pgh.pa.us>)
Re: elog/ereport noreturn decoration  (Peter Eisentraut <peter_e@gmx.net>)
List pgsql-hackers
There is continued interest in static analyzers (clang, coverity), and
the main problem with those is that they don't know that elog and
ereport with level >= ERROR don't return, leading to lots of false
positives.

I looked in the archive; there were some attempts to fix this some time
ago.  One was putting an __attribute__((analyzer_noreturn)) on these
functions, but that was decided to be incorrect (and it would only work
for clang anyway).  Another went along the lines of what I'm proposing
here (but before ereport was introduced, if I read it correctly), but
didn't go anywhere.

My proposal with ereport would be to do this:

diff --git i/src/include/utils/elog.h w/src/include/utils/elog.h
--- i/src/include/utils/elog.h
+++ w/src/include/utils/elog.h
@@ -104,7 +104,8 @@
  */
 #define ereport_domain(elevel, domain, rest)   \
        (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \
-        (errfinish rest) : (void) 0)
+        (errfinish rest) : (void) 0),                                     \
+               (elevel >= ERROR ? abort() : (void) 0)

There are no portability problems with that.

With elog, I would do this:

diff --git i/src/include/utils/elog.h w/src/include/utils/elog.h
@@ -196,7 +197,11 @@
  *             elog(ERROR, "portal \"%s\" not found", stmt->portalname);
  *----------
  */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#define elog(elevel, ...)      elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish(elevel, __VA_ARGS__),
(elevel>= ERROR ? abort() : (void) 0) 
+#else
 #define elog   elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish
+#endif

I think the issue here was that if we support two separate code paths,
we still need to do the actually unreachable /* keep compiler happy */
bits, and that compilers that know about elog not returning would
complain about unreachable code.  But I have never seen warnings like
that, so maybe it's a nonissue.  But it could be tested if there are
concerns.

Complete patch attached for easier applying and testing.

For clang aficionados: This reduces scan-build warnings from 1222 to 553
for me.

Attachment

pgsql-hackers by date:

Previous
From: Merlin Moncure
Date:
Subject: Re: Posix Shared Mem patch
Next
From: Dimitri Fontaine
Date:
Subject: Re: Event Triggers reduced, v1