public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jonathan Wakely <jwakely@redhat.com>
To: Florian Weimer <fweimer@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] Notes on the warnings-as-errors change in GCC 14
Date: Fri, 2 Feb 2024 19:06:19 +0000	[thread overview]
Message-ID: <Zb09K0EojEaeKthh@zen.kayari.org> (raw)
In-Reply-To: <87v876ssxg.fsf@oldenburg.str.redhat.com>

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!
> </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).
>+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.
>+
>+<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.
>+
>+<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.)
>+
>+<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,

s/part of/that are part of/ ?


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

s/options/option/

>+semantics and features that were removed from C99.  Alternatively,
>+individual warnings can be downgraded to warnings using

s/individual warnings/individual errors/ ?

>+the <code>-Wno-error=…</code> option, or disabled complete

s/the/the relevant/ ?

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

You could link this text to
https://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html

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


  parent reply	other threads:[~2024-02-02 19:06 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 [this message]
2024-02-08  7:04 ` Sam James
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=Zb09K0EojEaeKthh@zen.kayari.org \
    --to=jwakely@redhat.com \
    --cc=fweimer@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /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).