Bug 113776 - [14 regression] postgresql-16.1 build failure with -Werror=vla in configure test since r14-8641
Summary: [14 regression] postgresql-16.1 build failure with -Werror=vla in configure t...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 14.0
: P1 normal
Target Milestone: 14.0
Assignee: Joseph S. Myers
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2024-02-05 19:51 UTC by Sam James
Modified: 2024-02-08 04:38 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-02-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sam James 2024-02-05 19:51:00 UTC
I'm not sure if this is an issue in the configure test that postgres is using. If so, I'll report it over there or to autoconf as appropriate.

(I think pg is doing something wrong here anyway as it's using CFLAGS it tests for itself for all of its configure tests.)

Anyway, I originally reported this downstream in Gentoo at https://bugs.gentoo.org/923804.

pg fails to build like:
```
pg_collation.c:46:1: error: conflicting types for ‘CollationCreate’; have ‘Oid(const char *, Oid,  Oid,  char,  _Bool,  int32,  const char *, const char *, const char *, const char *, const char *, _Bool,  _Bool)’ {aka ‘unsigned int(const char *, unsigned int,  unsigned int,  char,  _Bool,  int,  const char *, const char *, const char *, const char *, const char *, _Bool,  _Bool)’}
   46 | CollationCreate(const char *collname, Oid collnamespace,
      | ^~~~~~~~~~~~~~~
In file included from pg_collation.c:25:
../../../src/include/catalog/pg_collation.h:88:17: note: previous declaration of ‘CollationCreate’ with type ‘Oid(const char *, Oid,  Oid,  char,  bool,  int32,  const char *, const char *, const char *, const char *, const char *, bool,  bool)’ {aka ‘unsigned int(const char *, unsigned int,  unsigned int,  char,  unsigned char,  int,  const char *, const char *, const char *, const char *, const char *, unsigned char,  unsigned char)’}
   88 | extern Oid      CollationCreate(const char *collname, Oid collnamespace,
      |                 ^~~~~~~~~~~~~~~
pg_collation.c: In function ‘CollationCreate’:
pg_collation.c:207:48: error: passing argument 3 of ‘heap_form_tuple’ from incompatible pointer type [-Wincompatible-pointer-types]
  207 |         tup = heap_form_tuple(tupDesc, values, nulls);
      |                                                ^~~~~
      |                                                |
      |                                                _Bool *
In file included from pg_collation.c:18:
../../../src/include/access/htup_details.h:715:87: note: expected ‘bool *’ {aka ‘unsigned char *’} but argument is of type ‘_Bool *’
  715 |                                                                  Datum *values, bool *isnull);
```

This turns out to be because of a configure test getting confused:
```

#include <stdbool.h>
#ifndef bool
"error: bool is not defined"
#endif
#ifndef false
    "error: false is not defined"
#endif
#if false
"error: false is not 0"
#endif
#ifndef true
    "error: true is not defined"
#endif
#if true != 1
    "error: true is not 1"
#endif
#ifndef __bool_true_false_are_defined
    "error: __bool_true_false_are_defined is not defined"
#endif

    struct s {
    _Bool s : 1;
    _Bool t;
} s;

char a[true == 1 ? 1 : -1];
char b[false == 0 ? 1 : -1];
char c[__bool_true_false_are_defined == 1 ? 1 : -1];
char d[(bool)0.5 == true ? 1 : -1];
/* See body of main program for 'e'.  */
char f[(_Bool)0.0 == false ? 1 : -1];
char g[true];
char h[sizeof(_Bool)];
char i[sizeof s.t];
enum { j = false, k = true, l = false * true, m = true * 256 };
/* The following fails for
HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
_Bool n[m];
char o[sizeof n == m * sizeof n[0] ? 1 : -1];
char p[-1 - (_Bool)0 < 0 && -1 - (bool)0 < 0 ? 1 : -1];
/* Catch a bug in an HP-UX C compiler.  See
http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
*/
_Bool q = true;
_Bool *pq = &q;

int main() {
    bool e = &s;
    *pq |= q;
    *pq |= !q;
    /* Refer to every declared value, to avoid compiler optimizations.  */
    return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m +
            !n + !o + !p + !q + !pq);
    return 0;
}
```

With -O2 -Werror=vla, it recently started emitting:
```
<source>:30:1: warning: variably modified 'd' at file scope
   30 | char d[(bool)0.5 == true ? 1 : -1];
      | ^~~~
<source>:30:1: error: ISO C90 forbids array 'd' whose size cannot be evaluated [-Werror=vla]
<source>:32:1: warning: variably modified 'f' at file scope
   32 | char f[(_Bool)0.0 == false ? 1 : -1];
      | ^~~~
<source>:32:1: error: ISO C90 forbids array 'f' whose size cannot be evaluated [-Werror=vla]
cc1: some warnings being treated as errors
Compiler returned: 1
```

Is this intentional or not? GCC 13 doesn't error, nor does Clang 17.
Comment 1 Sam James 2024-02-05 19:51:42 UTC
tl;dr: are d and f supposed to be compilable / are they constant expressions in C?
Comment 2 Jakub Jelinek 2024-02-05 20:05:10 UTC
This boils down to
char d[(_Bool)0.5 == 1 ? 1 : -1];
char f[(_Bool)0.0 == 0 ? 1 : -1];
which started warning with r14-8641-g35de88e2ed0aa78f6e3306c8560cd6bb15ce0ffe
Comment 3 Joseph S. Myers 2024-02-07 22:19:20 UTC
Testing a patch.
Comment 4 GCC Commits 2024-02-08 01:35:07 UTC
The master branch has been updated by Joseph Myers <jsm28@gcc.gnu.org>:

https://gcc.gnu.org/g:bfd72bb44eca83b0db2b0bab895f27a8a44247a2

commit r14-8874-gbfd72bb44eca83b0db2b0bab895f27a8a44247a2
Author: Joseph Myers <josmyers@redhat.com>
Date:   Thu Feb 8 01:34:09 2024 +0000

    c: Fix boolean conversion of floating constant as integer constant expression [PR113776]
    
    My fix for bug 111059 and bug 111911 caused a conversion of a floating
    constant to boolean to wrongly no longer be considered an integer
    constant expression, because logic to insert a NOP_EXPR in
    c_objc_common_truthvalue_conversion for an argument not an integer
    constant expression itself now took place after rather than before the
    conversion to bool.  In the specific case of casting a floating
    constant to bool, the result is an integer constant expression even
    though the argument isn't (build_c_cast deals with ensuring that casts
    to integer type of anything of floating type more complicated than a
    single floating constant don't get wrongly treated as integer constant
    expressions even if they fold to constants), so fix the logic in
    c_objc_common_truthvalue_conversion to handle that special case.
    
    Bootstrapped with no regressions for x86_64-pc-linux-gnu.
    
            PR c/113776
    
    gcc/c
            * c-typeck.cc (c_objc_common_truthvalue_conversion): Return an
            integer constant expression for boolean conversion of floating
            constant.
    
    gcc/testsuite/
            * gcc.dg/pr113776-1.c, gcc.dg/pr113776-2.c, gcc.dg/pr113776-3.c,
            gcc.dg/pr113776-4.c: New tests.
Comment 5 Joseph S. Myers 2024-02-08 01:40:49 UTC
Fixed for GCC 14.
Comment 6 Sam James 2024-02-08 04:38:12 UTC
Thank you!