On Thu, May 26, 2022 at 11:01:44PM -0400, Tom Lane wrote:
> Michael Paquier <mich...@paquier.xyz> writes:
>> FWIW, I would be fine to backpatch the NULL handling for short_desc,
>> while treating the addition of nonnull as a HEAD-only change.
> 
> Yeah, sounds about right to me.  My guess is that we will need
> a configure check for nonnull, but perhaps I'm wrong.

Makes sense.  Here's a new patch set.  0001 is the part intended for
back-patching, and 0002 is the rest (i.e., adding pg_attribute_nonnull()).
I switched to using __has_attribute to discover whether nonnull was
supported, as that seemed cleaner.  I didn't see any need for a new
configure check, but maybe I am missing something.

-- 
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
>From c2760bf3db292fb55b6448f22eaeee38656083b5 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandboss...@gmail.com>
Date: Fri, 27 May 2022 09:48:51 -0700
Subject: [PATCH v4 1/2] Properly handle NULL short descriptions for custom
 variables.

If a NULL short description is specified in one of the
DefineCustomXXXVariable functions, SHOW ALL will segfault.  This
change teaches SHOW ALL to properly handle NULL short descriptions.

Back-patch to all supported versions.

Reported by: Steve Chavez
Author: Steve Chavez
Reviewed by: Nathan Bossart, Michael Paquier, Andred Freund, Tom Lane
Discussion: https://postgr.es/m/CAGRrpzY6hO-Kmykna_XvsTv8P2DshGiU6G3j8yGao4mk0CqjHA%40mail.gmail.com
---
 src/backend/utils/misc/guc.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8e9b71375c..55d41ae7d6 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -9780,7 +9780,16 @@ ShowAllGUCConfig(DestReceiver *dest)
 			isnull[1] = true;
 		}
 
-		values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
+		if (conf->short_desc)
+		{
+			values[2] = PointerGetDatum(cstring_to_text(conf->short_desc));
+			isnull[2] = false;
+		}
+		else
+		{
+			values[2] = PointerGetDatum(NULL);
+			isnull[2] = true;
+		}
 
 		/* send it to dest */
 		do_tup_output(tstate, values, isnull);
@@ -9792,7 +9801,8 @@ ShowAllGUCConfig(DestReceiver *dest)
 			pfree(setting);
 			pfree(DatumGetPointer(values[1]));
 		}
-		pfree(DatumGetPointer(values[2]));
+		if (conf->short_desc)
+			pfree(DatumGetPointer(values[2]));
 	}
 
 	end_tup_output(tstate);
@@ -10002,7 +10012,7 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
 	values[3] = _(config_group_names[conf->group]);
 
 	/* short_desc */
-	values[4] = _(conf->short_desc);
+	values[4] = conf->short_desc != NULL ? _(conf->short_desc) : NULL;
 
 	/* extra_desc */
 	values[5] = conf->long_desc != NULL ? _(conf->long_desc) : NULL;
-- 
2.25.1

>From bd05e7092f45f416476cc02a21f8d0bb069a313f Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathandboss...@gmail.com>
Date: Fri, 27 May 2022 10:10:09 -0700
Subject: [PATCH v4 2/2] Introduce pg_attribute_nonnull() and use it for
 DefineCustomXXXVariable().

pg_attribute_nonnull() can be used to generate compiler warnings
when a function is called with the specified arguments set to NULL.
An empty argument list indicates that all pointer arguments must
not be NULL.  pg_attribute_nonnull() only works for compilers that
support the nonnull function attribute.  If nonnull is not
supported, pg_attribute_nonnull() has no effect.

In addition to introducing pg_attribute_nonnull(), this change uses
it for the DefineCustomXXXVariable() functions to generate warnings
when the "name" and "valueAddr" arguments are set to NULL.

Idea by: Andres Freund
Author: Nathan Bossart
Reviewed by: Michael Paquier, Tom Lane
Discussion: https://postgr.es/m/20220525061739.ur7x535vtzyzkmqo%40alap3.anarazel.de
---
 src/include/c.h         | 11 +++++++++++
 src/include/utils/guc.h | 10 +++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/include/c.h b/src/include/c.h
index 4f16e589b3..0c64557c62 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -144,6 +144,17 @@
 #define pg_attribute_no_sanitize_alignment()
 #endif
 
+/*
+ * pg_attribute_nonnull means the compiler should warn if the function is called
+ * with the listed arguments set to NULL.  If no arguments are listed, the
+ * compiler should warn if any pointer arguments are set to NULL.
+ */
+#if __has_attribute (nonnull)
+#define pg_attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__)))
+#else
+#define pg_attribute_nonnull(...)
+#endif
+
 /*
  * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only
  * used in assert-enabled builds, to avoid compiler warnings about unused
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index efcbad7842..be691c5e9c 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -303,7 +303,7 @@ extern void DefineCustomBoolVariable(const char *name,
 									 int flags,
 									 GucBoolCheckHook check_hook,
 									 GucBoolAssignHook assign_hook,
-									 GucShowHook show_hook);
+									 GucShowHook show_hook) pg_attribute_nonnull(1, 4);
 
 extern void DefineCustomIntVariable(const char *name,
 									const char *short_desc,
@@ -316,7 +316,7 @@ extern void DefineCustomIntVariable(const char *name,
 									int flags,
 									GucIntCheckHook check_hook,
 									GucIntAssignHook assign_hook,
-									GucShowHook show_hook);
+									GucShowHook show_hook) pg_attribute_nonnull(1, 4);
 
 extern void DefineCustomRealVariable(const char *name,
 									 const char *short_desc,
@@ -329,7 +329,7 @@ extern void DefineCustomRealVariable(const char *name,
 									 int flags,
 									 GucRealCheckHook check_hook,
 									 GucRealAssignHook assign_hook,
-									 GucShowHook show_hook);
+									 GucShowHook show_hook) pg_attribute_nonnull(1, 4);
 
 extern void DefineCustomStringVariable(const char *name,
 									   const char *short_desc,
@@ -340,7 +340,7 @@ extern void DefineCustomStringVariable(const char *name,
 									   int flags,
 									   GucStringCheckHook check_hook,
 									   GucStringAssignHook assign_hook,
-									   GucShowHook show_hook);
+									   GucShowHook show_hook) pg_attribute_nonnull(1, 4);
 
 extern void DefineCustomEnumVariable(const char *name,
 									 const char *short_desc,
@@ -352,7 +352,7 @@ extern void DefineCustomEnumVariable(const char *name,
 									 int flags,
 									 GucEnumCheckHook check_hook,
 									 GucEnumAssignHook assign_hook,
-									 GucShowHook show_hook);
+									 GucShowHook show_hook) pg_attribute_nonnull(1, 4);
 
 extern void MarkGUCPrefixReserved(const char *className);
 
-- 
2.25.1

Reply via email to