public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr
@ 2023-07-10 18:39 fchelnokov at gmail dot com
  2023-07-10 18:43 ` [Bug c++/110619] " pinskia at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: fchelnokov at gmail dot com @ 2023-07-10 18:39 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

            Bug ID: 110619
           Summary: Dangling pointer returned from constexpr function
                    converts in nullptr
           Product: gcc
           Version: 13.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fchelnokov at gmail dot com
  Target Milestone: ---

The following function

constexpr auto f() {
    int i = 0;
    return &i;
};

returns dangling pointer on stack variable, but it is not nullptr. So next
assertion passes in Clang and MSVC:

static_assert( f() != nullptr );


But in GCC the assertion fails. Online demo:
https://gcc.godbolt.org/z/6E4rE963n

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
@ 2023-07-10 18:43 ` pinskia at gcc dot gnu.org
  2023-07-10 18:44 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-07-10 18:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |diagnostic

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I would have expected this to be undefined ...
So the static_assert could work or not.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
  2023-07-10 18:43 ` [Bug c++/110619] " pinskia at gcc dot gnu.org
@ 2023-07-10 18:44 ` pinskia at gcc dot gnu.org
  2023-07-10 19:04 ` fchelnokov at gmail dot com
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2023-07-10 18:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>but it is not nullptr.

Or is it just undefined so it could be considered a nullptr ...

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
  2023-07-10 18:43 ` [Bug c++/110619] " pinskia at gcc dot gnu.org
  2023-07-10 18:44 ` pinskia at gcc dot gnu.org
@ 2023-07-10 19:04 ` fchelnokov at gmail dot com
  2023-07-12  1:51 ` de34 at live dot cn
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: fchelnokov at gmail dot com @ 2023-07-10 19:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

--- Comment #3 from Fedor Chelnokov <fchelnokov at gmail dot com> ---
I think according to https://eel.is/c++draft/basic.stc#general-4 the function
shall return an "invalid pointer valued". And nullptr is not considered such.

And if one modifies the function slightly (see auto p appear):

constexpr auto g() {
    int i = 0;
    auto p = &i;
    return p;
};

Then static_assert passes: https://gcc.godbolt.org/z/5shcxfcxG

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
                   ` (2 preceding siblings ...)
  2023-07-10 19:04 ` fchelnokov at gmail dot com
@ 2023-07-12  1:51 ` de34 at live dot cn
  2023-07-13 19:02 ` ppalka at gcc dot gnu.org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: de34 at live dot cn @ 2023-07-12  1:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

Jiang An <de34 at live dot cn> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |de34 at live dot cn

--- Comment #4 from Jiang An <de34 at live dot cn> ---
(In reply to Andrew Pinski from comment #1)
> I would have expected this to be undefined ...
> So the static_assert could work or not.

If this were undefined (not true IIUC), static_assert would be required not to
work because the condition expression is not a constant expression
([expr.const]/5.8).

We should keep in mind that all kinds of core UB that may occur within
(tentative) constant evaluation (except for violation of [[assume]], currently)
are not totally undefined, since they must cause constant evaluation failure.
CWG issue should be submitted if such detection is unimplementable.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
                   ` (3 preceding siblings ...)
  2023-07-12  1:51 ` de34 at live dot cn
@ 2023-07-13 19:02 ` ppalka at gcc dot gnu.org
  2023-07-26  1:45 ` cvs-commit at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: ppalka at gcc dot gnu.org @ 2023-07-13 19:02 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |natattak at gmail dot com,
                   |                            |ppalka at gcc dot gnu.org

--- Comment #5 from Patrick Palka <ppalka at gcc dot gnu.org> ---
IIUC Nathaniel's patch at
https://gcc.gnu.org/pipermail/gcc-patches/2023-July/623377.html will fix this.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
                   ` (4 preceding siblings ...)
  2023-07-13 19:02 ` ppalka at gcc dot gnu.org
@ 2023-07-26  1:45 ` cvs-commit at gcc dot gnu.org
  2023-08-07  5:04 ` peter at cordes dot ca
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-07-26  1:45 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

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

commit r14-2772-gb8266af71c19a0bd7db4d08c8d2ee3c33214508c
Author: Nathaniel Shead <nathanieloshead@gmail.com>
Date:   Sun Jul 23 01:14:37 2023 +1000

    c++: Prevent dangling pointers from becoming nullptr in constexpr
[PR110619]

    Currently, when typeck discovers that a return statement will refer to a
    local variable it rewrites to return a null pointer. This causes the
    error messages for using the return value in a constant expression to be
    unhelpful, especially for reference return values, and is also a visible
    change to otherwise valid code (as in the linked PR).

    The transformation is nonetheless important, however, both as a safety
    guard against attackers being able to gain a handle to other data on the
    stack, and to prevent duplicate warnings from later null-dereference
    warning passes.

    As such, this patch just delays the transformation until cp_genericize,
    after constexpr function definitions have been generated.

            PR c++/110619

    gcc/cp/ChangeLog:

            * cp-gimplify.cc (cp_genericize_r): Transform RETURN_EXPRs to
            not return dangling pointers.
            * cp-tree.h (RETURN_EXPR_LOCAL_ADDR_P): New flag.
            (check_return_expr): Add a new parameter.
            * semantics.cc (finish_return_stmt): Set flag on RETURN_EXPR
            when referring to dangling pointer.
            * typeck.cc (check_return_expr): Disable transformation of
            dangling pointers, instead pass this information to caller.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp1y/constexpr-110619.C: New test.

    Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
                   ` (5 preceding siblings ...)
  2023-07-26  1:45 ` cvs-commit at gcc dot gnu.org
@ 2023-08-07  5:04 ` peter at cordes dot ca
  2023-08-07  7:41 ` fchelnokov at gmail dot com
  2023-08-07  9:12 ` redi at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: peter at cordes dot ca @ 2023-08-07  5:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

Peter Cordes <peter at cordes dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |peter at cordes dot ca

--- Comment #7 from Peter Cordes <peter at cordes dot ca> ---
(In reply to Andrew Pinski from comment #2)
> >but it is not nullptr.
> 
> Or is it just undefined so it could be considered a nullptr ...


Implementation-defined behaviour, according to answers on
https://stackoverflow.com/questions/76843246/why-does-the-address-of-an-out-of-scope-variable-equal-zero-with-constexpr


https://eel.is/c++draft/basic.compound#def:value,invalid_pointer

https://eel.is/c++draft/basic.stc.general#4

>  Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior.
> **Any other use of an invalid pointer value has implementation-defined behavior.**

So this wasn't a bug, but the new behaviour is also allowed.

This commit could be reverted or kept, depending on maintainability and/or
quality-of-life for users of GCC.  Having it pick the other
implementation-defined behaviour from clang (GCC's previous behaviour) is maybe
a *good* thing, to help programmers catch dependence on an invalid pointer
being either null or non-null if they try their code with both compilers.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
                   ` (6 preceding siblings ...)
  2023-08-07  5:04 ` peter at cordes dot ca
@ 2023-08-07  7:41 ` fchelnokov at gmail dot com
  2023-08-07  9:12 ` redi at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: fchelnokov at gmail dot com @ 2023-08-07  7:41 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

--- Comment #8 from Fedor Chelnokov <fchelnokov at gmail dot com> ---
Please note that GCC 13 also accepts invalid program (because dangling pointers
were converted in nullptr):

constexpr auto f(int a) {
    return &a;
}

constexpr auto g(int b) {
    return &b;
}

static_assert(f(1) <= g(2));

This program must be rejected because of relational comparison of unrelated
pointers as Clang and MSVC do, online demo: https://gcc.godbolt.org/z/q5z3Gvehe
And your patch fixes it as well, thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug c++/110619] Dangling pointer returned from constexpr function converts in nullptr
  2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
                   ` (7 preceding siblings ...)
  2023-08-07  7:41 ` fchelnokov at gmail dot com
@ 2023-08-07  9:12 ` redi at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2023-08-07  9:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110619

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Fedor Chelnokov from comment #8)
> This program must be rejected because of relational comparison of unrelated
> pointers

I disagree. If GCC were to define the behaviour of returning invalid pointers
during constant evaluation as converting them to null pointers, then those
wouldn't be unrelated pointers. They'd be null pointers. And the comparison
would be well defined.

But I don't think that conversion was ever intended as the defined behaviour,
just an unintended consequence. If it was intended, it should have been
documented at
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Implementation.html

The fact that we _don't_ do any such conversion should also be documented
there, of course. We should say that other uses of invalid pointers do not
modify the pointer values, so copying them preserves the invalid value (without
trapping, except on Itanium?) and pointer comparisons and pointer arithmetic
are undefined because they don't point to an object.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-08-07  9:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-10 18:39 [Bug c++/110619] New: Dangling pointer returned from constexpr function converts in nullptr fchelnokov at gmail dot com
2023-07-10 18:43 ` [Bug c++/110619] " pinskia at gcc dot gnu.org
2023-07-10 18:44 ` pinskia at gcc dot gnu.org
2023-07-10 19:04 ` fchelnokov at gmail dot com
2023-07-12  1:51 ` de34 at live dot cn
2023-07-13 19:02 ` ppalka at gcc dot gnu.org
2023-07-26  1:45 ` cvs-commit at gcc dot gnu.org
2023-08-07  5:04 ` peter at cordes dot ca
2023-08-07  7:41 ` fchelnokov at gmail dot com
2023-08-07  9:12 ` redi at gcc dot gnu.org

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).