Tighten header pre-inclusions in headerscheck and cpluspluscheck.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 4 Mar 2023 17:11:50 +0000 (12:11 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 4 Mar 2023 17:11:50 +0000 (12:11 -0500)
We allow our header files to depend on the appropriate one of
postgres.h, postgres_fe.h, or c.h having already been included.
However, there are a few headers such as libpq-fe.h that are
meant to be used by client applications and therefore must
compile without any assumptions about previous inclusions.
These test scripts failed to consider that, which seems quite
hazardous since we might not immediately notice such a problem
otherwise.  Hence, adjust these scripts to test relevant libpq
and ecpg headers with no prior inclusion.

While at it, we can also make an effort to actually use the
relevant one of postgres.h, postgres_fe.h, or c.h.  I added
some rules that guess which one to use based on the first-level
src subdirectory, e.g. use postgres_fe.h under src/bin/.
These rules are hardly water-tight but they seem to work today,
and we can always refine them in the future.

These changes don't reveal any live problems today, which is good,
but they should make these scripts more able to catch future bugs.

Discussion: https://postgr.es/m/2488193.1677863247@sss.pgh.pa.us

src/tools/pginclude/cpluspluscheck
src/tools/pginclude/headerscheck

index 2c5042eb417a8f6b24fe682adb45550637bce8c8..b0e9aa99a2cc87b90140dfb193189f5b403d1794 100755 (executable)
@@ -161,7 +161,33 @@ do
    # OK, create .c file to include this .h file.
    {
        echo 'extern "C" {'
-       test "$f" != src/include/postgres_fe.h && echo '#include "postgres.h"'
+       # Ideally we'd pre-include only the appropriate one of
+       # postgres.h, postgres_fe.h, or c.h.  We don't always have enough
+       # info to guess which, but in some subdirectories there's a
+       # reasonable choice to make, and otherwise we use postgres.h.
+       # Also, those three files should compile with no pre-include, as
+       # should src/interfaces headers meant to be exposed to clients.
+       case "$f" in
+       src/include/postgres.h) ;;
+       src/include/postgres_fe.h) ;;
+       src/include/c.h) ;;
+       src/interfaces/libpq/libpq-fe.h) ;;
+       src/interfaces/libpq/libpq-events.h) ;;
+       src/interfaces/ecpg/ecpglib/ecpglib_extern.h)
+           echo '#include "postgres_fe.h"' ;;
+       src/interfaces/ecpg/ecpglib/*) ;;
+       src/interfaces/*)
+           echo '#include "postgres_fe.h"' ;;
+       src/bin/*)
+           echo '#include "postgres_fe.h"' ;;
+       src/fe_utils/*)
+           echo '#include "postgres_fe.h"' ;;
+       src/port/*) ;;
+       src/common/*)
+           echo '#include "c.h"' ;;
+       *)
+           echo '#include "postgres.h"' ;;
+       esac
        echo "#include \"$f\""
        echo '};'
    } >$tmp/test.cpp
@@ -174,9 +200,9 @@ do
        EXTRAINCLUDES="$python_includespec" ;;
        src/interfaces/ecpg/*)
        EXTRAINCLUDES="-I $builddir/src/interfaces/ecpg/include -I $srcdir/src/interfaces/ecpg/include" ;;
-       src/backend/parser/*)
+       src/backend/parser/*)
        EXTRAINCLUDES="-I $builddir/src/backend/parser/" ;;
-       src/backend/utils/adt/*)
+       src/backend/utils/adt/*)
        EXTRAINCLUDES="-I $builddir/src/backend/utils/adt/" ;;
        *)
        EXTRAINCLUDES="" ;;
index abbba7aa6366d6951dfb4bb57ed6d8dbbfb937fd..8dee1b56709d06a9ef1f5e80b956a079fa8a1e6a 100755 (executable)
@@ -142,7 +142,33 @@ do
 
    # OK, create .c file to include this .h file.
    {
-       test "$f" != src/include/postgres_fe.h && echo '#include "postgres.h"'
+       # Ideally we'd pre-include only the appropriate one of
+       # postgres.h, postgres_fe.h, or c.h.  We don't always have enough
+       # info to guess which, but in some subdirectories there's a
+       # reasonable choice to make, and otherwise we use postgres.h.
+       # Also, those three files should compile with no pre-include, as
+       # should src/interfaces headers meant to be exposed to clients.
+       case "$f" in
+       src/include/postgres.h) ;;
+       src/include/postgres_fe.h) ;;
+       src/include/c.h) ;;
+       src/interfaces/libpq/libpq-fe.h) ;;
+       src/interfaces/libpq/libpq-events.h) ;;
+       src/interfaces/ecpg/ecpglib/ecpglib_extern.h)
+           echo '#include "postgres_fe.h"' ;;
+       src/interfaces/ecpg/ecpglib/*) ;;
+       src/interfaces/*)
+           echo '#include "postgres_fe.h"' ;;
+       src/bin/*)
+           echo '#include "postgres_fe.h"' ;;
+       src/fe_utils/*)
+           echo '#include "postgres_fe.h"' ;;
+       src/port/*) ;;
+       src/common/*)
+           echo '#include "c.h"' ;;
+       *)
+           echo '#include "postgres.h"' ;;
+       esac
        echo "#include \"$f\""
    } >$tmp/test.c