Bug 114780 - Using C23 nullptr as sentinel gives missing sentinel warning
Summary: Using C23 nullptr as sentinel gives missing sentinel warning
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 13.2.0
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2024-04-19 09:58 UTC by Marko Lindqvist
Modified: 2024-04-23 06:42 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-04-19 00:00:00


Attachments
Minimum testcase (87 bytes, text/plain)
2024-04-19 09:58 UTC, Marko Lindqvist
Details
gcc14-pr114780.patch (742 bytes, patch)
2024-04-19 11:10 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Marko Lindqvist 2024-04-19 09:58:24 UTC
Created attachment 57988 [details]
Minimum testcase

Compiling attached code with "gcc -std=c2x -Wformat -c nullptrsentinel.c" produces warning:

nullptrsentinel.c: In function ‘caller’:
nullptrsentinel.c:5:3: warning: missing sentinel in function call [-Wformat=]
    5 |   sentinental(nullptr);
Comment 1 Jakub Jelinek 2024-04-19 11:10:19 UTC
Created attachment 57989 [details]
gcc14-pr114780.patch

Untested fix.
Comment 2 GCC Commits 2024-04-19 22:13:22 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:2afdecccbaf5c5b1c7a235509b37092540906c02

commit r14-10046-g2afdecccbaf5c5b1c7a235509b37092540906c02
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Apr 20 00:12:36 2024 +0200

    c-family: Allow arguments with NULLPTR_TYPE as sentinels [PR114780]
    
    While in C++ the ellipsis argument conversions include
    "An argument that has type cv std::nullptr_t is converted to type void*"
    in C23 a nullptr_t argument is not promoted in any way, but va_arg
    description says:
    "the type of the next argument is nullptr_t and type is a pointer type that has the same
    representation and alignment requirements as a pointer to a character type."
    So, while in C++ check_function_sentinel will never see NULLPTR_TYPE, for
    C23 it can see that and currently we incorrectly warn about those.
    
    The only question is whether we should warn on any argument with
    nullptr_t type or just about nullptr (nullptr_t argument with integer_zerop
    value).  Through undefined behavior guess one could pass non-NULL pointer
    that way, say by union { void *p; nullptr_t q; } u; u.p = &whatever;
    and pass u.q to ..., but valid code should always pass something that will
    read as (char *) 0 when read using va_arg (ap, char *), so I think it is
    better not to warn rather than warn in those cases.
    
    Note, clang seems to pass (void *)0 rather than expression of nullptr_t
    type to ellipsis in C23 mode as if it did the C++ ellipsis argument
    conversions, in that case guess not warning about that would be even safer,
    but what GCC does I think follows the spec more closely, even when in a
    valid program one shouldn't be able to observe the difference.
    
    2024-04-20  Jakub Jelinek  <jakub@redhat.com>
    
            PR c/114780
            * c-common.cc (check_function_sentinel): Allow as sentinel any
            argument of NULLPTR_TYPE.
    
            * gcc.dg/format/sentinel-2.c: New test.
Comment 3 Jakub Jelinek 2024-04-19 22:25:27 UTC
Fixed for 14.1 so far.
Comment 4 GCC Commits 2024-04-21 04:09:50 UTC
The releases/gcc-13 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:e802786436851b1f5efca21a14d4f41c83c83f4f

commit r13-8637-ge802786436851b1f5efca21a14d4f41c83c83f4f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Apr 20 00:12:36 2024 +0200

    c-family: Allow arguments with NULLPTR_TYPE as sentinels [PR114780]
    
    While in C++ the ellipsis argument conversions include
    "An argument that has type cv std::nullptr_t is converted to type void*"
    in C23 a nullptr_t argument is not promoted in any way, but va_arg
    description says:
    "the type of the next argument is nullptr_t and type is a pointer type that has the same
    representation and alignment requirements as a pointer to a character type."
    So, while in C++ check_function_sentinel will never see NULLPTR_TYPE, for
    C23 it can see that and currently we incorrectly warn about those.
    
    The only question is whether we should warn on any argument with
    nullptr_t type or just about nullptr (nullptr_t argument with integer_zerop
    value).  Through undefined behavior guess one could pass non-NULL pointer
    that way, say by union { void *p; nullptr_t q; } u; u.p = &whatever;
    and pass u.q to ..., but valid code should always pass something that will
    read as (char *) 0 when read using va_arg (ap, char *), so I think it is
    better not to warn rather than warn in those cases.
    
    Note, clang seems to pass (void *)0 rather than expression of nullptr_t
    type to ellipsis in C23 mode as if it did the C++ ellipsis argument
    conversions, in that case guess not warning about that would be even safer,
    but what GCC does I think follows the spec more closely, even when in a
    valid program one shouldn't be able to observe the difference.
    
    2024-04-20  Jakub Jelinek  <jakub@redhat.com>
    
            PR c/114780
            * c-common.cc (check_function_sentinel): Allow as sentinel any
            argument of NULLPTR_TYPE.
    
            * gcc.dg/format/sentinel-2.c: New test.
    
    (cherry picked from commit 2afdecccbaf5c5b1c7a235509b37092540906c02)
Comment 5 Jakub Jelinek 2024-04-23 06:42:55 UTC
Fixed for 13.3 too.