From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 539A93858403 for ; Fri, 2 Feb 2024 17:00:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 539A93858403 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 539A93858403 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706893209; cv=none; b=h8/16ObtbNPb9R9GDGhLEOA5G1/g7V9NGI/wes/yRYCo5odC45ZkhGAa2jajfpah//sFzHlh0wAFyrSoFp0qf+9YVdkK1GnApBKAhCXwwaAG113FfHcl7/OvFvo3rlTfuypunXDTm1Rurmf6usfOORC5uLHOjxdeDmTZdecHUos= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706893209; c=relaxed/simple; bh=tl/gnEMp1VTIPDD9uORHRwk3f1j7atYwdltKfMHpF0c=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=KtfynkQKC4MAU6qDzyp4XcEPitw0qgoOsC0eB5YVayzL8U1Typ7+EfIeGF2OnsxaaIi3djx8S0slfTF7QCoi4UDeYAeXnwLwjbbwEam6QOVCI/AgJXiV1MMECvfNpfPZnFkq5jCfJE5zD8zfgDRAzcwSbJ2RXliirwQS7+zIHnI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706893205; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=hsezlPDKhQqJ+bAZF1pYmqK1yoE5a5R7vfhPxQ6LtGM=; b=AVbiw1KGYKPmPOPzaVWRaaqYesOVgYhJLpa9I4d6viX+5SrJsrnXFakroxQDPUR1BjO2RR TH2IZeyZ7Gdo8/sxnhOMbCM35UwtaixkmdQyUxJkiE8Jkk8W/C5t3//S+d6Ihi52sCXuYG Ba7hk3hS6FA8MJ92pAueB92F2LOw54o= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-52-6Cr5atHjNZOJLM5_kDjKvA-1; Fri, 02 Feb 2024 12:00:03 -0500 X-MC-Unique: 6Cr5atHjNZOJLM5_kDjKvA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D6AF93C0C4AE for ; Fri, 2 Feb 2024 17:00:02 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.39.192.27]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C62BE1121306 for ; Fri, 2 Feb 2024 17:00:01 +0000 (UTC) From: Florian Weimer To: gcc-patches@gcc.gnu.org Subject: [PATCH] Notes on the warnings-as-errors change in GCC 14 Date: Fri, 02 Feb 2024 17:59:55 +0100 Message-ID: <87v876ssxg.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.3 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_NUMSUBJECT,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,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: --- htdocs/gcc-14/porting_to.html | 465 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 465 insertions(+) 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 identi= fy common issues and provide solutions. Let us know if you have suggestions for improvement= s!

=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-archiv= e +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=3Di= mplicit-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). +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 (<= code>-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 [-Wimplic=
it-function-declaration]
+    5 |   return strlen (s);
+      |          ^~~~~~
+note: include =E2=80=98<string.h>=E2=80=99 or provide a declaration of =
=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. + +

+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. + +

Typos in function prototypes (-We= rror=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 state= ment (-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.) + +

+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 ge= neral

+ +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

Header dependency changes

base-commit: 15056edbb60e24a6410d9b75f7386de28ea60bc1