diff options
author | Joseph Myers <josmyers@redhat.com> | 2024-11-21 21:46:00 +0000 |
---|---|---|
committer | Joseph Myers <josmyers@redhat.com> | 2024-11-21 21:46:00 +0000 |
commit | 338d687e2a32f4e152d26c02319db1cb00401c3f (patch) | |
tree | 323a923525596c9a4e76d1928c4184f67c11930b /gcc/c | |
parent | 4574f15bb305204fb615756148da8f214156c787 (diff) | |
download | gcc-338d687e2a32f4e152d26c02319db1cb00401c3f.zip gcc-338d687e2a32f4e152d26c02319db1cb00401c3f.tar.gz gcc-338d687e2a32f4e152d26c02319db1cb00401c3f.tar.bz2 |
c: Give errors more consistently for void parameters [PR114816]
Cases of void parameters, other than a parameter list of (void) (or
equivalent with a typedef for void) in its entirety, have been made a
constraint violation in C2Y (N3344 alternative 1 was adopted), as part
of a series of changes to eliminate unnecessary undefined behavior by
turning it into constraint violations, implementation-defined behavior
or something else with stricter bounds on what behavior is allowed.
Previously, these were implicitly undefined behavior (see DR#295),
with only some cases listed in Annex J as undefined (but even those
cases not having wording in the normative text to make them explicitly
undefined).
As discussed in bug 114816, GCC is not entirely consistent about
diagnosing such usages; unnamed void parameters get errors when not
the entire parameter list, while qualified and register void (the
cases listed in Annex J) get errors as a single unnamed parameter, but
named void parameters are accepted with a warning (in a declaration
that's not a definition; it's not possible to define a function with
incomplete parameter types).
Following C2Y, make all these cases into errors. The errors are not
conditional on the standard version, given that this was previously
implicit undefined behavior. Since it wasn't possible anyway to
define such functions, only declare them without defining them (or
otherwise use such parameters in function type names that can't
correspond to any defined function), hopefully the risks of
compatibility issues are small.
Bootstrapped with no regressions for x86-64-pc-linux-gnu.
PR c/114816
gcc/c/
* c-decl.cc (grokparms): Do not warn for void parameter type here.
(get_parm_info): Give errors for void parameters even when named.
gcc/testsuite/
* gcc.dg/c2y-void-parm-1.c: New test.
* gcc.dg/noncompile/920616-2.c, gcc.dg/noncompile/921116-1.c,
gcc.dg/parm-incomplete-1.c: Update expected diagnostics.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-decl.cc | 23 |
1 files changed, 7 insertions, 16 deletions
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index c58ff4a..a84b35e 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -8480,8 +8480,8 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) or definition of the function. In the case where the tag was first declared within the parameter list, a warning has already been given. If a parameter has void type, then - however the function cannot be defined or called, so - warn. */ + this has already received an error (constraint violation in C2Y, + previously implicitly undefined behavior). */ for (parm = arg_info->parms, typelt = arg_types, parmno = 1; parm; @@ -8508,17 +8508,6 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag) TREE_TYPE (parm) = error_mark_node; arg_types = NULL_TREE; } - else if (VOID_TYPE_P (type)) - { - if (DECL_NAME (parm)) - warning_at (input_location, 0, - "parameter %u (%q+D) has void type", - parmno, parm); - else - warning_at (DECL_SOURCE_LOCATION (parm), 0, - "parameter %u has void type", - parmno); - } } if (DECL_NAME (parm) && TREE_USED (parm)) @@ -8627,12 +8616,14 @@ get_parm_info (bool ellipsis, tree expr) if (TREE_ASM_WRITTEN (decl)) error_at (b->locus, "parameter %q+D has just a forward declaration", decl); - /* Check for (..., void, ...) and issue an error. */ - else if (VOID_TYPE_P (type) && !DECL_NAME (decl)) + /* Check for (..., void, ...) and named void parameters and issue an + error. */ + else if (VOID_TYPE_P (type)) { if (!gave_void_only_once_err) { - error_at (b->locus, "%<void%> must be the only parameter"); + error_at (b->locus, + "%<void%> must be the only parameter and unnamed"); gave_void_only_once_err = true; } } |