Florian Weimer <fwei...@redhat.com> 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 identify > common issues > and provide solutions. Let us know if you have suggestions for improvements! > </p> > > +<h2 id="c">C language issues</h2> > + > +<h3 id="warnings-as-errors">Certain warnings are now errors</h3> > + > +<blockquote > cite="https://archive.org/details/PC-Mag-1988-09-13/page/n115/mode/2up"> > + 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. > + <footer> > + <cite>Standard C: The ANSI Draft Grows Up. > + PC Magazine, September 13, 1988, page 117.</cite> > + </footer> > +</blockquote> > + > +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. > + > +<p> > +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 <a href="https://www.gnu.org/software/gnulib/">gnulib</a> or > +<a href="https://www.gnu.org/software/autoconf-archive/">autoconf-archive</a> > +may need to update these sources files from their upstream versions. > + > +<p> > +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. > + > +<h4 id="implicit-int">Implicit <code>int</code> types > (<code>-Werror=implicit-int</code>)</h4> > + > +In most cases, simply adding the missing <code>int</code> keyword > +addresses the error. For example, a flag like > + > +<pre> > + static initialized; > +</pre> > + > +might turn into: > + > +<pre> > + static <ins>int</ins> initialized; > +</pre> > + > +<p>If the return type of a function is omitted, the correct type to > +add could be <code>int</code> or <code>void</code>, depending on > +whether the function returns a value or not. > + > +<p>In some cases, the previously implied <code>int</code> 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 <code>s</code> should be > +<code>const char *</code>, not <code>int</code>: > + > +<pre> > + write_string (fd, s) > + { > + write (1, s, strlen (s)); > + } > +</pre> > + > +The corrected standard C source code might look like this (still > +disregarding error handling and short writes): > + > +<pre> > + <ins>void</ins> > + write_string (<ins>int</ins> fd, const char *s) > + { > + write (1, s, strlen (s)); > + } > +</pre> > + > +<h4 id="implicit-function-declaration">Implicit function declarations > (<code>-Werror=implicit-function-declaration</code>)</h4> > + > +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. > + > +<p> > +For well-known functions declared in standard headers, GCC provides > +fix-it hints with the appropriate <code>#include</code> directives: > + > +<pre> > +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 | > +</pre> > + > +<p> > +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 <a > href="https://sourceware.org/glibc/manual/html_node/Feature-Test-Macros.html">Feature > Test Macros</a> > +in the GNU C Library manual for details. > + > +<p> > +Some programs are built with <code>-std=c11</code> or > +similar <code>-std</code> options that do not contain the > +string <code>gnu</code>, but these programs still use POSIX or other > +extensions in standard C headers such as <code><stdio.h></code>. > +The GNU C library automatically suppresses these extensions in > +standard C mode, which can result in implicit function declarations. > +To address this, the <code>-std=c11</code> option can be > +dropped, <code>-std=gnu11</code> can be used instead, > +or <code>-std=c11 -D_DEFAULT_SOURCE</code> 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. > + > +<p> > +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 > +<code>-flto -Werror=lto-type-mismatch</code>, which can help with > +adding appropriate prototypes. > + > +<p> > +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: > + > +<pre> > + void no_prototype (); > +</pre> > + > +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. > + > +<p> > +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. > + > +<h4 id="missing-parameter-types">Typos in function prototypes > (<code>-Werror=declaration-missing-parameter-type</code>)</h4> > + > +Incorrectly spelled type names in function declarations are treated as > +errors in more cases, under a > +new <code>-Wdeclaration-missing-parameter-type</code> warning. The > +second line in the following example is now treated as an error > +(previously this resulted in an unnamed warning): > + > +<pre> > + typedef int *int_array; > + int first_element (intarray); > +</pre> > + > +The fix is to correct the spelling mistake: > + > +<pre> > + typedef int *int_array; > + int first_element (<ins>int_array</ins>); > +</pre> > + > +GCC will type-check function arguments after that, potentially > +requiring further changes. (Previously, the function declaration was > +treated as not having no prototype.) > + > +<h4 id="return-mismatch">Incorrect uses of the <code>return</code> statement > (<code>-Werror=return-mismatch</code>)</h4> > + > +GCC no longer accepts <code>return</code> statements with expressions > +in functions which are declared to return <code>void</code>, or > +<code>return</code> statements without expressions for functions > +returning a non<code>void</code> type. > + > +<p> > +To address this, remove the incorrect expression (or turn it into a > +statement expression immediately prior to the <code>return</code> > +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. > + > +<p> > +Previously, these mismatches were diagnosed as > +a <code>-Wreturn-type</code> 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 <code>}</code> of function that does not > +return <code>void</code>. > + > +<p> > +By default, GCC still accepts returning an expression of > +type <code>void</code> from within a function that itself > +returns <code>void</code>, as a GNU extension that matches C++ rules > +in this area. > + > +<h4 id="int-conversion">Using pointers as integers and vice versa > (<code>-Werror=int-conversion</code>)</h4> > + > +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. > + > +<p> > +It makes sense to address missing <code>int</code> type, implicit > +function declarations, and incorrect <code>return</code> statement > +usage prior to tackling these <code>int</code>-conversion issues. > +Some of them will be caused by missing types resulting > +in <code>int</code>, and the default <code>int</code> return type of > +implicitly declared functions. > + > +<p>To fix the remaining <code>int</code>-conversions issues, add casts > +to an appropriate pointer or integer type. On GNU systems, the > +standard (but generally optional) types > +<code>intptr_t</code> and <code>uintptr_t</code> (defined > +in <code><stdint.h></code>) are always large enough to store all > +pointer values. If you need a generic pointer type, consider > +using <code>void *</code>. > + > +<p> 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. > + > +<h4 id="incompatible-pointer-types">Type checking on pointer types > (<code>-Werror=incompatible-pointer-types</code>)</h4> > + > +GCC no longer casts all pointer types to all other pointer types. > +This behavior is now restricted to the <code>void *</code> type and > +its qualified variations. > + > +<p> > +To fix the compilation errors resulting from that, you can add the > +appropriate casts, and maybe consider using code <code>void *</code> > +in more places (particularly for old programs that predate the > +introduction of <code>void</code> into the C language). > + > +<p> > +Programs that do not carefully track pointer types are likely to > +contain aliasing violations, so consider building > +with <code>-fno-strict-aliasing</code> 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. > +<p> > +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: > + > +<pre> > +#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); > +} > +</pre> > + > +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): > + > +<pre> > +int > +compare (<ins>const void *a1</ins>, <ins>const void *b1</ins>) > +{ > + <ins>char *const *a = a1;</ins> > + <ins>char *const *b = b1;</ins> > + return strcmp (*a, *b); > +} > +</pre> > + > +<p> > +A similar issue can arise with object pointer types. Consider a > +function that is declared with an argument of type > +<code>void **</code>, and you want to pass the address of a variable > +of type <code>int *</code>: > + > +<pre> > +extern int *pointer; > +extern void operate (int command, void **); > + > +operate (0, &pointer); > +</pre> > + > +In these cases, it may be appropriate to make a copy of the pointer > +with the correct <code>void *</code> type: > + > +<pre> > +extern int *pointer; > +extern void operate (int command, void **); > + > +<ins>void *pointer1 = pointer;</ins> > +operate (0, &pointer<ins>1</ins>); > +<ins>pointer = pointer1;</ins> > +</pre> > + > +As mentioned initially, adding the cast here would not eliminate any > +strict aliasing violation in the implementation of > +the <code>operate</code> function. Of course in general, introducing > +such additional copies may alter program behavior. > + > +<p> > +Some programming styles rely on implicit casts between related object > +pointer types to implement C++-style <code>struct</code> inheritance. > +It may be possible to avoid writing manual casts with > +the <code>-fplan9-extensions</code> options and unnamed > +initial <code>struct</code> fields for the base type in > +derived <code>struct</code>s. > + > +<p> > +Some programs use a concrete function pointer type such as > +<code>void (*) (void)</code> as a generic function pointer type > +(similar to <code>void *</code> 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 <code>void *</code> and function pointer types. However, for > +a portable solution, the concrete function pointer type needs to be > +used, together with explicit casts. > + > +<h4 id="autoconf">Impact on Autoconf and build environment probing in > general</h4> > + > +Most <a href="https://www.gnu.org/software/autoconf/">Autoconf</a> > +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. > + > +<p> > +In cases where this is a concern, generated <code>config.log</code>, > +<code>config.h</code> and other source code files can be compared > +using <a href="https://www.gnu.org/software/diffutils/">diff</a>, > +to ensure there are no unexpected differences. > + > +<p> > +This phenomenon also impacts similar procedures part of CMake, Meson, > +and various build tools for C extension modules of scripting > +languages. > + > +<p> > +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. > + > +<h4 id="errors-as-warnings">Turning errors back into warnings</h4> > + > +<p> > +Sources that cannot be ported to standard C can be compiled > +with <code>-fpermissive</code>, <code>-std=gnu89</code>, > +or <code>-std=c89</code>. Despite their names, the latter two options > +turn on support for pre-standard C constructs, too. With the > +<code>-fpermissive</code> options, programs can use C99 inlining > +semantics and features that were removed from C99. Alternatively, > +individual warnings can be downgraded to warnings using > +the <code>-Wno-error=…</code> option, or disabled complete > +with <code>-Wno-…</code>. For example, > +<code>-Wno-error=incompatible-pointer-types</code> turns off most type > +checking for pointer assignments. > + > +<p> > +Some build systems do not pass the <code>CFLAGS</code> environment > +or <code>make</code> variable to all parts of the builds, and may > +require setting <code>CC</code> to something like <code>gcc > +-fpermissive</code> instead. If the build system does not support > +whitespace in the <code>CC</code> variable, a wrapper script like this > +may be required: > + > +<pre> > +#!/bin/sh > +exec /usr/bin/gcc -fpermissive "$@" > +</pre> > + > +<h4 id="c-code-generators">Accommodating C code generators</h4> > + > +C code generators that cannot be updated to generate valid standard C > +can emit <code>#pragma GCC diagnostic warning</code> directives to > +turn these errors back into warnings: > + > +<pre> > +#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 > +</pre> > + > +Not listed here are <code>-Wimplicit-int</code> > +and <code>-Wdeclaration-missing-parameter-type</code> because they > +should be straightforward to address in a code generator. > + > +<h4 id="warnings-as-errors-future-directions">Future directions</h4> > + > +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. > + > +<p> > +It is unclear at which point GCC can enable the C23 <code>bool</code> > +keyword by default (making the <code>bool</code> type available > +without including <code>#include <stdbool.h></code> explicitly). > +Many programs define their own <code>bool</code> types, sometimes with > +a different size of the already-available <code>_Bool</code> type. A > +further complication is that even if the sizes are the same, a custom > +<code>bool</code> typically does not have trap representations, > +while <code>_Bool</code> and the new <code>bool</code> type do. This > +means that there can be subtle compatibility issues, particularly when > +processing untrusted, not necessarily well-formed input data. > + > +<p> > +GCC is unlikely to warn about function declarations that are not > +prototypes by default. This means that there is no stringent reason > +to turn > + > +<pre> > +void do_something (); > +</pre> > + > +into > + > +<pre> > +void do_something (void); > +</pre> > + > +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 > +(<code>do_something (1)</code>, for example). Eventually, GCC will > +diagnose such calls as errors because they are constraint violations > +in C23. > + > +<p> > +GCC will probably continue to support old-style function definitions > +even once C23 is used as the default language dialect. > + > <h2 id="cxx">C++ language issues</h2> > > <h3 id="header-dep-changes">Header dependency changes</h3> > > base-commit: 15056edbb60e24a6410d9b75f7386de28ea60bc1
signature.asc
Description: PGP signature