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 E3A733858C33 for ; Fri, 2 Feb 2024 18:08:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E3A733858C33 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 E3A733858C33 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=1706897291; cv=none; b=NjbxLZmASoE3xwHwS/qmLfF/ZAGh1HGjxDj8Y6+ATSZb3zbeg8WOiGC/jC80GuuB1JID5gmNFgY19LMIe2DeVvuCe/5ak04bnmlpw39KXYs794PbVjg5saFjJYcthKeKGHpJqb5QVcFzGCZVfhiU2tW1mtiDECuwre6IqmYNnAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706897291; c=relaxed/simple; bh=evkp5ob5Og4Ym4RWh/MJHO2s49MOUCpIqD2LCbZajnY=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=iUzW+mTK4o3vTcQEXUEjVjQrq2Iuvk/v315rVQM8HoaOS0G6P4Z8tG1lnojPsc9/rXA0IHuALQGPn4Tzp65Bhygh/LyNeIynqCKqTy03FEbBWGSTO4ZpOxDmoJqb9cn7tCH8VLvT1tI8hwpWQdrJirJFpvtEOKQvt/1EVOiDmxo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1706897287; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TYbUUwH0zX7hqlGvk+j7mx3MQ3aJT4KXTqT04DI1GOw=; b=gnN4ztWrMDX0oPTjebsjMUxMz7Fba0p6WNIfApMQwe69yvEqU8+hBrk2O1xKYbJqK4zsih 0BZqg5gvBIFrfS871lri/m5z1YXle51TsY3jgPlMXAOs6br4zsG4CdXHgOVhLvxCUf2lI4 VPmOuLfd8Jugi+We4CvVuRRfmaKYhlc= 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-596-66glaZnEMwu1abfYGL4yLA-1; Fri, 02 Feb 2024 13:08:06 -0500 X-MC-Unique: 66glaZnEMwu1abfYGL4yLA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (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 02CCB2812FEA for ; Fri, 2 Feb 2024 18:08:06 +0000 (UTC) Received: from localhost (unknown [10.42.28.13]) by smtp.corp.redhat.com (Postfix) with ESMTP id A8C36111FA; Fri, 2 Feb 2024 18:08:05 +0000 (UTC) Date: Fri, 2 Feb 2024 18:08:01 +0000 From: Jonathan Wakely To: Florian Weimer Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Notes on the warnings-as-errors change in GCC 14 Message-ID: References: <87v876ssxg.fsf@oldenburg.str.redhat.com> MIME-Version: 1.0 In-Reply-To: <87v876ssxg.fsf@oldenburg.str.redhat.com> X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8; format=flowed Content-Disposition: inline Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-13.0 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: On 02/02/24 17:59 +0100, Florian Weimer wrote: >--- > htdocs/gcc-14/porting_to.html | 465 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 465 insertions(+) > > >base-commit: 15056edbb60e24a6410d9b75f7386de28ea60bc1 > >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 identify common issues > and provide solutions. Let us know if you have suggestions for improvements! >

> >+

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-archive >+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=implicit-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). s/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=implicit-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 ‘strlen’ [-Wimplicit-function-declaration]
>+    5 |   return strlen (s);
>+      |          ^~~~~~
>+note: include ‘<string.h>’ or provide a declaration of ‘strlen’
>+  +++ |+#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=c11 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=c11 option can be >+dropped, -std=gnu11 can be used instead, >+or -std=c11 -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 I think "no suitable shared header file yet" reads a bit better to me. >+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=lto-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 s/declaration/declare/ >+without prototype: without a 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, s/declaration/declaring/ ? >+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 (-Werror=declaration-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.) s/no prototype/a prototype/ ? >+ >+

Incorrect uses of the return statement (-Werror=return-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. Hyphen after "non"? >+ >+

>+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=int-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 I know what you mean here, but I'm not sure the parenthesis adds clarity for anybody who doesn't already know that those types are optional for conformance. I think they're supported for all targets that GCC supports, so maybe just omit the parenthesis. >+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=incompatible-pointer-types)

>+ >+GCC no longer casts all pointer types to all other pointer types. s/casts/allows implicitly casting/ ? >+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 * s/using code/using/ ? >+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 = a1;
>+  char *const *b = 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 = pointer;
>+operate (0, &pointer1);
>+pointer = 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=gnu89, >+or -std=c89. 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=… option, or disabled complete >+with -Wno-…. For example, >+-Wno-error=incompatible-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__ >= 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

> >

Header dependency changes