Subject: Debian 12 gcc warning

From: Bruce Momjian <[email-masked]>
Date: Mon, 28 Aug 2023 15:37:20 -0400

On Debian 12, gcc version 12.2.0 (Debian 12.2.0-14) generates a warning
on PG 13 to current, but only with -O1 optimization level, and not at
-O0/-O2/-O3:

	clauses.c: In function ‘recheck_cast_function_args’:
	clauses.c:4293:19: warning: ‘actual_arg_types’ may be used uninitialized [-Wmaybe-uninitialized]
	 4293 |         rettype = enforce_generic_type_consistency(actual_arg_types,
	      |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	 4294 |                                                                                            declared_arg_types,
	      |                                                                                            ~~~~~~~~~~~~~~~~~~~
	 4295 |                                                                                            nargs,
	      |                                                                                            ~~~~~~
	 4296 |                                                                                            funcform->prorettype,
	      |                                                                                            ~~~~~~~~~~~~~~~~~~~~~
	 4297 |                                                                                            false);
	      |                                                                                            ~~~~~~
	In file included from clauses.c:45:
	../../../../src/include/parser/parse_coerce.h:82:17: note: by argument 1 of type ‘const Oid *’ {aka ‘const unsigned int *’} to ‘enforce_generic_type_consistency’ declared here
	   82 | extern Oid      enforce_generic_type_consistency(const Oid *actual_arg_types,
	      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	clauses.c:4279:33: note: ‘actual_arg_types’ declared here
	 4279 |         Oid                     actual_arg_types[FUNC_MAX_ARGS];
	      |                                 ^~~~~~~~~~~~~~~~

The code is:

	static void
	recheck_cast_function_args(List *args, Oid result_type,
	                           Oid *proargtypes, int pronargs,
	                           HeapTuple func_tuple)
	{
	    Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple);
	    int         nargs;
	    Oid         actual_arg_types[FUNC_MAX_ARGS];
	    Oid         declared_arg_types[FUNC_MAX_ARGS];
	    Oid         rettype;
	    ListCell   *lc;
	
	    if (list_length(args) > FUNC_MAX_ARGS)
	        elog(ERROR, "too many function arguments");
	    nargs = 0;
	    foreach(lc, args)
	    {
	        actual_arg_types[nargs++] = exprType((Node *) lfirst(lc));
	    }
	    Assert(nargs == pronargs);
	    memcpy(declared_arg_types, proargtypes, pronargs * sizeof(Oid));
-->	    rettype = enforce_generic_type_consistency(actual_arg_types,
	                                               declared_arg_types,
	                                               nargs,
	                                               funcform->prorettype,
	                                               false);
	    /* let's just check we got the same answer as the parser did ... */

I don't see a clean way of avoiding the warning except by initializing
the array, which seems wasteful.

-- 
  Bruce Momjian  <[email-masked]>        https://momjian.us
  EDB                                      https://enterprisedb.com

  Only you can decide what is important to you.

---

From: Michael Paquier <[email-masked]>
Date: Tue, 29 Aug 2023 07:30:15 +0900

> the array, which seems wasteful.

Or just initialize the array with a {0}?
--
Michael

---

From: Bruce Momjian <[email-masked]>
Date: Mon, 28 Aug 2023 19:10:38 -0400

> Or just initialize the array with a {0}?

Uh, doesn't that set all elements to zero?  See:

	https://stackoverflow.com/questions/2589749/how-to-initialize-array-to-0-in-c

---

From: David Rowley <[email-masked]>
Date: Tue, 29 Aug 2023 11:55:48 +1200

>                 actual_arg_types[nargs++] = exprType((Node *) lfirst(lc));

Does it still produce the warning if you form the above more like?

nargs = list_length(args);
for (int i = 0; i < nargs; i++)
    actual_arg_types[i] = exprType((Node *) list_nth(args, i));

I'm just not sure if it's unable to figure out if at least nargs
elements is set or if it won't be happy until all 100 elements are
set.

David

---

From: Bruce Momjian <[email-masked]>
Date: Mon, 28 Aug 2023 21:00:37 -0400

> 	https://stackoverflow.com/questions/2589749/how-to-initialize-array-to-0-in-c

FYI, that does stop the warning.

---

From: John Naylor <[email-masked]>
Date: Tue, 29 Aug 2023 10:26:27 +0700

> elements is set or if it won't be happy until all 100 elements are

It looks like the former, since I can silence it on gcc 13 / -O1 by doing:

/* keep compiler quiet */
actual_arg_types[0] = InvalidOid;

--
John Naylor
EDB: http://www.enterprisedb.com