From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.gentoo.org (mail.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) by sourceware.org (Postfix) with ESMTP id CA0163858C5F for ; Thu, 8 Feb 2024 07:09:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CA0163858C5F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gentoo.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gentoo.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CA0163858C5F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:470:ea4a:1:5054:ff:fec7:86e4 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707376191; cv=none; b=fmew3pMF4FaFSuAqpDyAwBhq3cTVau2Cq4D4puFv3l3dTNx4K+FC+PJUzOpDomqcsikNPlpFzHb0xfB8ASxMCnsjKcsaGLBsyRHziHDs2PDmxhFooPZP1xCc2ARq/CHIhO0h9fLYwJ3/nM1gclHSTi5s3FQ0eowEu2vinZNCnBw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707376191; c=relaxed/simple; bh=+hJ/Ayxvg4w9GeDStJuenG4De/q3eGHmHUFOlATxS6w=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=GmekkMcuIFw2XloRhJedIhx1VZRd0WSX2Go3sI8YN0fcUxFrUwoRdgjgGb8sWG69h2zOwj9w4h3YyBKJFwyKf4DOEVVIYEJbBYsxNSMZu455loYU92qYh/iLJX0tD3QKyOoBSWaOHiqsz/npSnX4Pw5SHzkO/H301SKtsJTE2r8= ARC-Authentication-Results: i=1; server2.sourceware.org References: <87v876ssxg.fsf@oldenburg.str.redhat.com> User-agent: mu4e 1.10.8; emacs 30.0.50 From: Sam James To: Florian Weimer Cc: gcc-patches@gcc.gnu.org, Gerald Pfeifer Subject: Re: [PATCH] Notes on the warnings-as-errors change in GCC 14 Date: Thu, 08 Feb 2024 07:04:13 +0000 Organization: Gentoo In-reply-to: <87v876ssxg.fsf@oldenburg.str.redhat.com> Message-ID: <87cyt7toso.fsf@gentoo.org> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,JMQ_SPF_NEUTRAL,KAM_DMARC_STATUS,KAM_NUMSUBJECT,KAM_SHORT,SPF_HELO_PASS,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Florian Weimer writes: > --- > htdocs/gcc-14/porting_to.html | 465 ++++++++++++++++++++++++++++++++++++= ++++++ > 1 file changed, 465 insertions(+) > Can't approve but LGTM. Thank you for being so thorough - it'll be helpful when showing upstreams. > diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html > index 3e4cedc3..4c8f9c8f 100644 > --- a/htdocs/gcc-14/porting_to.html > +++ b/htdocs/gcc-14/porting_to.html > @@ -24,6 +24,471 @@ porting to GCC 14. This document is an effort to iden= tify common issues > and provide solutions. Let us know if you have suggestions for improveme= nts! >

>=20=20 > +

C language issues

> + > +

Certain warnings are now errors

> + > +
> + Function prototyping was added, first to help enforce type checking > + on both the types of the arguments passed to the function, and also > + to check the assignment compatibility of the function return type. > +
> + Standard C: The ANSI Draft Grows Up. > + PC Magazine, September 13, 1988, page 117. > +
> +
> + > +The initial ISO C standard and its 1999 revision removed support for > +many C language features that were widely known as sources of > +application bugs due to accidental misuse. For backwards > +compatibility, GCC 13 and earlier compiler versions diagnosed use of > +these features as warnings only. Although these warnings have been > +enabled by default for many releases, experience shows that these > +warnings are easily ignored, resulting in difficult-to-diagnose bugs. > +In GCC 14, these issues are now reported as errors, and no output file > +is created, providing clearer feedback to programmers that something > +is wrong. > + > +

> +Most components of the GNU project have already been fixed for > +compatibility, but not all of them have had releases since fixes were > +applied. Programs that bundle parts > +of gnulib or > +autoconf-arch= ive > +may need to update these sources files from their upstream versions. > + > +

> +Several GNU/Linux distributions have shared patches from their porting > +efforts on relevant upstream mailing lists and bug trackers, but of > +course there is a strong overlap between programs that have these > +historic C compatibility issues and are dormant today. > + > +

Implicit int types (-Werror= =3Dimplicit-int)

> + > +In most cases, simply adding the missing int keyword > +addresses the error. For example, a flag like > + > +
> +  static initialized;
> +
> + > +might turn into: > + > +
> +  static int initialized;
> +
> + > +

If the return type of a function is omitted, the correct type to > +add could be int or void, depending on > +whether the function returns a value or not. > + > +

In some cases, the previously implied int type > +was not correct. This mostly happens in function definitions > +that are not prototypes, when argument types are not > +declared outside the parameter list. Using the correct > +type maybe required to avoid int-conversion errors (see below). maybe -> may be > +In the example below, the type of s should be > +const char *, not int: > + > +

> +  write_string (fd, s)
> +  {
> +    write (1, s, strlen (s));
> +  }
> +
> + > +The corrected standard C source code might look like this (still > +disregarding error handling and short writes): > + > +
> +  void
> +  write_string (int fd, const char *s)
> +  {
> +    write (1, s, strlen (s));
> +  }
> +
> + > +

Implicit function declarations = (-Werror=3Dimplicit-function-declaration)

> + > +It is no longer possible to call a function that has not been > +declared. In general, the solution is to include a header file with > +an appropriate function prototype. Note that GCC will perform further > +type checks based on the function prototype, which can reveal further > +type errors that require additional changes. > + > +

> +For well-known functions declared in standard headers, GCC provides > +fix-it hints with the appropriate #include directives: > + > +

> +error: implicit declaration of function =E2=80=98strlen=E2=80=99 [-Wimpl=
icit-function-declaration]
> +    5 |   return strlen (s);
> +      |          ^~~~~~
> +note: include =E2=80=98<string.h>=E2=80=99 or provide a declaration o=
f =E2=80=98strlen=E2=80=99
> +  +++ |+#include <string.h>
> +    1 |
> +
> + > +

> +On GNU systems, headers described in standards (such as the C > +standard, or POSIX) may require the definition of certain > +macros at the start of the compilation before all required > +function declarations are made available. > +See Feature Test Macros > +in the GNU C Library manual for details. > + > +

> +Some programs are built with -std=3Dc11 or > +similar -std options that do not contain the > +string gnu, but these programs still use POSIX or other > +extensions in standard C headers such as <stdio.h>. > +The GNU C library automatically suppresses these extensions in > +standard C mode, which can result in implicit function declarations. > +To address this, the -std=3Dc11 option can be > +dropped, -std=3Dgnu11 can be used instead, > +or -std=3Dc11 -D_DEFAULT_SOURCE can be used re-enable > +common extensions. It's fine if you leave this out, but consider mentioning the common pitfall of autoconf projects not including config.h consistently before all inclues. We could also mention AC_USE_SYSTEM_EXTENSIONS. Both are weak suggestions and I don't mind if you don't apply them. > + > +

> +If undeclared functions from the same project are called and there is > +yet no suitable shared header file, you should add a declaration to a > +header file that is included by both the callers and the source file > +containing the function definition. This ensures that GCC checks that > +the prototype matches the function definition. GCC can perform type > +checks across translation units when building with options such as > +-flto -Werror=3Dlto-type-mismatch, which can help with > +adding appropriate prototypes. > + > +

> +In some rare cases, adding a prototype may change ABI in inappropriate > +ways. In these situations, it is necessary to declaration a function > +without prototype: > + > +

> +  void no_prototype ();
> +
> + > +However, this is an obsolete C feature that will change meaning in C23 > +(declaration a function with a prototype and accepting no arguments, > +similar to C++). Usually, a prototype with the default argument > +promotions applied can be used instead. > + > +

> +When building library code on GNU systems, it was possible to call > +undefined (not just undeclared) functions and still run other code in > +the library, particularly if ELF lazy binding was used. Only > +executing the undefined function call would result in a lazy binding > +error and program crash. Maybe explicitly refer to the bfd linker's relaxed behaviour so it sounds less mysterious. > + > +

Typos in function prototypes (-= Werror=3Ddeclaration-missing-parameter-type)

> + > +Incorrectly spelled type names in function declarations are treated as > +errors in more cases, under a > +new -Wdeclaration-missing-parameter-type warning. The > +second line in the following example is now treated as an error > +(previously this resulted in an unnamed warning): > + > +
> +  typedef int *int_array;
> +  int first_element (intarray);
> +
> + > +The fix is to correct the spelling mistake: > + > +
> +  typedef int *int_array;
> +  int first_element (int_array);
> +
> + > +GCC will type-check function arguments after that, potentially > +requiring further changes. (Previously, the function declaration was > +treated as not having no prototype.) > + > +

Incorrect uses of the return sta= tement (-Werror=3Dreturn-mismatch)

> + > +GCC no longer accepts return statements with expressions > +in functions which are declared to return void, or > +return statements without expressions for functions > +returning a nonvoid type. > + > +

> +To address this, remove the incorrect expression (or turn it into a > +statement expression immediately prior to the return > +statements if the expression has side effects), or add a dummy return > +value, as appropriate. If there is no suitable dummy return value, > +further changes may be needed to implement appropriate error handling. > + > +

> +Previously, these mismatches were diagnosed as > +a -Wreturn-type warning. This warning still exists, and > +is not treated as an error by default. It now covers remaining > +potential correctness issues, such as reaching the closing > +brace } of function that does not > +return void. > + > +

> +By default, GCC still accepts returning an expression of > +type void from within a function that itself > +returns void, as a GNU extension that matches C++ rules > +in this area. > + > +

Using pointers as integers and vice versa (-Werror=3Dint-conversion)

> + > +GCC no longer treats integer types and pointer types as equivalent in > +assignments (including implied assignments of function arguments and > +return values), and instead fails the compilation with a type error. > + > +

> +It makes sense to address missing int type, implicit > +function declarations, and incorrect return statement > +usage prior to tackling these int-conversion issues. > +Some of them will be caused by missing types resulting > +in int, and the default int return type of > +implicitly declared functions. > + > +

To fix the remaining int-conversions issues, add casts > +to an appropriate pointer or integer type. On GNU systems, the > +standard (but generally optional) types > +intptr_t and uintptr_t (defined > +in <stdint.h>) are always large enough to store all > +pointer values. If you need a generic pointer type, consider > +using void *. > + > +

Note that in some cases, it may be more appropriate to pass the > +address of an integer variable instead of a cast of the variable's > +value. > + > +

Type checking on pointer types (-Werror=3Dincompatible-pointer-types)

> + > +GCC no longer casts all pointer types to all other pointer types. > +This behavior is now restricted to the void * type and > +its qualified variations. > + > +

> +To fix the compilation errors resulting from that, you can add the > +appropriate casts, and maybe consider using code void * > +in more places (particularly for old programs that predate the > +introduction of void into the C language). > + > +

> +Programs that do not carefully track pointer types are likely to > +contain aliasing violations, so consider building > +with -fno-strict-aliasing as well. (Whether the casts > +are written manually or performed by GCC automatically does not make a > +difference in terms of strict aliasing violations.) > + Thanks for calling that out specifically. > +

> +A frequent source of incompatible function pointer types involves > +callback functions that have more specific argument types (or less > +specific return types) than the function pointer they are assigned to. > +For example, old code which attempts to sort an array of strings might > +look like this: > + > +

> +#include <stddef.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +int
> +compare (char **a, char **b)
> +{
> +  return strcmp (*a, *b);
> +}
> +
> +void
> +sort (char **array, size_t length)
> +{
> +  qsort (array, length, sizeof (*array), compare);
> +}
> +
> + > +To correct this, the callback function should be defined with the > +correct type, and the arguments should be cast as appropriate before > +they are used (as calling a function through a function pointer of an > +incorrect type is undefined): > + > +
> +int
> +compare (const void *a1, const void *b1)
> +{
> +  char *const *a =3D a1;
> +  char *const *b =3D b1;
> +  return strcmp (*a, *b);
> +}
> +
> + > +

> +A similar issue can arise with object pointer types. Consider a > +function that is declared with an argument of type > +void **, and you want to pass the address of a variable > +of type int *: > + > +

> +extern int *pointer;
> +extern void operate (int command, void **);
> +
> +operate (0, &pointer);
> +
> + > +In these cases, it may be appropriate to make a copy of the pointer > +with the correct void * type: > + > +
> +extern int *pointer;
> +extern void operate (int command, void **);
> +
> +void *pointer1 =3D pointer;
> +operate (0, &pointer1);
> +pointer =3D pointer1;
> +
> + > +As mentioned initially, adding the cast here would not eliminate any > +strict aliasing violation in the implementation of > +the operate function. Of course in general, introducing > +such additional copies may alter program behavior. > + > +

> +Some programming styles rely on implicit casts between related object > +pointer types to implement C++-style struct inheritance. > +It may be possible to avoid writing manual casts with > +the -fplan9-extensions options and unnamed > +initial struct fields for the base type in > +derived structs. > + > +

> +Some programs use a concrete function pointer type such as > +void (*) (void) as a generic function pointer type > +(similar to void * for object pointer types), and rely on > +implicit casts to and from this type. The reason for that is that C > +does not offer a generic function pointer type, and standard C > +disallows casts between function pointer types and object pointer > +types. On most targets, GCC supports implicit conversion > +between void * and function pointer types. However, for > +a portable solution, the concrete function pointer type needs to be > +used, together with explicit casts. > + > +

Impact on Autoconf and build environment probing in = general

> + > +Most Autoconf > +probes that check for build system features are written in such a way > +that they trigger a compiler error if a feature is missing. The new > +errors may cause GCC to fail compiling a probe when it worked before, > +unrelated to the actual objective of the probe. These failed probes > +tend to consistently disable program features and their tests, which > +means that an unexpected probe failure may result in silently dropping > +features. > + > +

> +In cases where this is a concern, generated config.log, > +config.h and other source code files can be compared > +using diff, > +to ensure there are no unexpected differences. > + > +

> +This phenomenon also impacts similar procedures part of CMake, Meson, > +and various build tools for C extension modules of scripting > +languages. > + > +

> +Autoconf has supported C99 compilers since at least version 2.69 in > +its generic, core probes. (Specific functionality probes may have > +issues addressed in more recent versions.) Versions before 2.69 may > +have generic probes (for example for standard C support) that rely on > +C features that were removed in 1999 and thus fail with GCC 14. > + > +

Turning errors back into warnings

> + > +

> +Sources that cannot be ported to standard C can be compiled > +with -fpermissive, -std=3Dgnu89, > +or -std=3Dc89. Despite their names, the latter two options > +turn on support for pre-standard C constructs, too. With the > +-fpermissive options, programs can use C99 inlining > +semantics and features that were removed from C99. Alternatively, > +individual warnings can be downgraded to warnings using > +the -Wno-error=3D=E2=80=A6 option, or disabled complete > +with -Wno-=E2=80=A6. For example, > +-Wno-error=3Dincompatible-pointer-types turns off most type > +checking for pointer assignments. > + > +

> +Some build systems do not pass the CFLAGS environment > +or make variable to all parts of the builds, and may > +require setting CC to something like gcc > +-fpermissive instead. If the build system does not support > +whitespace in the CC variable, a wrapper script like this > +may be required: > + > +

> +#!/bin/sh
> +exec /usr/bin/gcc -fpermissive "$@"
> +
> + > +

Accommodating C code generators

> + > +C code generators that cannot be updated to generate valid standard C > +can emit #pragma GCC diagnostic warning directives to > +turn these errors back into warnings: > + > +
> +#if defined __GNUC__ && __GNUC__ >=3D 14
> +#pragma GCC diagnostic warning "-Wimplicit-function-declaration"
> +#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
> +#pragma GCC diagnostic warning "-Wint-conversion"
> +#pragma GCC diagnostic warning "-Wreturn-mismatch"
> +#endif
> +
> + > +Not listed here are -Wimplicit-int > +and -Wdeclaration-missing-parameter-type because they > +should be straightforward to address in a code generator. > + > +

Future directions

> + > +This section concerns potential future changes related to language > +features from the C standard and other backwards compatibility > +hazards. These plans may change and are mentioned here only to give > +guidance which source-level changes to prioritize for future compiler > +compatibility. > + > +

> +It is unclear at which point GCC can enable the C23 bool > +keyword by default (making the bool type available > +without including #include <stdbool.h> explicitly). > +Many programs define their own bool types, sometimes with > +a different size of the already-available _Bool type. A > +further complication is that even if the sizes are the same, a custom > +bool typically does not have trap representations, > +while _Bool and the new bool type do. This > +means that there can be subtle compatibility issues, particularly when > +processing untrusted, not necessarily well-formed input data. > + > +

> +GCC is unlikely to warn about function declarations that are not > +prototypes by default. This means that there is no stringent reason > +to turn > + > +

> +void do_something ();
> +
> + > +into > + > +
> +void do_something (void);
> +
> + > +except for diagnosing extraneous ignored arguments as errors. A > +future version of GCC will likely warn about calls to functions > +without a prototype which specify such extraneous arguments > +(do_something (1), for example). Eventually, GCC will > +diagnose such calls as errors because they are constraint violations > +in C23. > + > +

> +GCC will probably continue to support old-style function definitions > +even once C23 is used as the default language dialect. > + >

C++ language issues

>=20=20 >

Header dependency changes

> > base-commit: 15056edbb60e24a6410d9b75f7386de28ea60bc1 --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iOUEARYKAI0WIQQlpruI3Zt2TGtVQcJzhAn1IN+RkAUCZcR+N18UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0MjVB NkJCODhERDlCNzY0QzZCNTU0MUMyNzM4NDA5RjUyMERGOTE5MA8cc2FtQGdlbnRv by5vcmcACgkQc4QJ9SDfkZCQnQEA2gLgQsBu9uJe8cAX8kVXyoncYdavzbO+I/5O hIDyvxcBANAGdyoitzDQWuAg5UMf7cMFvZOMogjEKr7umbQmHMME =+Np9 -----END PGP SIGNATURE----- --=-=-=--