public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Sam James <sam@gentoo.org>
To: Florian Weimer <fweimer@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Gerald Pfeifer <gerald@pfeifer.com>
Subject: Re: [PATCH] Notes on the warnings-as-errors change in GCC 14
Date: Thu, 08 Feb 2024 07:04:13 +0000	[thread overview]
Message-ID: <87cyt7toso.fsf@gentoo.org> (raw)
In-Reply-To: <87v876ssxg.fsf@oldenburg.str.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 20989 bytes --]


Florian Weimer <fweimer@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 ‘&lt;string.h>’ or provide a declaration of ‘strlen’
> +  +++ |+#include &lt;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>&lt;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>&lt;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 &lt;stddef.h>
> +#include &lt;stdlib.h>
> +#include &lt;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, &amp;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, &amp;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 &lt;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


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 377 bytes --]

  parent reply	other threads:[~2024-02-08  7:09 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-02 16:59 Florian Weimer
2024-02-02 18:08 ` Jonathan Wakely
2024-02-15 15:57   ` Florian Weimer
2024-02-02 19:06 ` Jonathan Wakely
2024-02-08  7:04 ` Sam James [this message]
2024-02-15 16:07   ` Florian Weimer
2024-02-15 16:20     ` Sam James
2024-02-09 23:07 ` Gerald Pfeifer
2024-02-15 16:22   ` Florian Weimer
2024-02-15 22:58     ` Gerald Pfeifer
2024-02-15 16:49   ` Florian Weimer
2024-02-10 11:00 ` Gerald Pfeifer
2024-02-15 16:44   ` Florian Weimer
2024-02-16 21:23     ` Gerald Pfeifer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87cyt7toso.fsf@gentoo.org \
    --to=sam@gentoo.org \
    --cc=fweimer@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gerald@pfeifer.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).