public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation
@ 2021-07-26 18:46 fsb4000 at yandex dot ru
  2021-07-26 20:45 ` [Bug c++/101631] " redi at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: fsb4000 at yandex dot ru @ 2021-07-26 18:46 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 101631
           Summary: gcc permits object reference to object outside of its
                    lifetime during constant evaluation
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fsb4000 at yandex dot ru
  Target Milestone: ---

Hi.

The bug has come up during the implementation of SSO for constexpr std::string
which can be found here:
https://github.com/microsoft/STL/pull/1735#discussion_r674285711

The issue stems from an obscure
rule(https://eel.is/c++draft/class.union.general#6) that allows switching the
active member of a union by assigning to an element of the array member.
(Obligatory godbolt: https://godbolt.org/z/6qG7v9eYx)

While the usage on line 12 is indeed correct, for std::string we need to go
through char_traits which is imitated by perform_assignment. However, the
lifetime of the subobject buf[5] only starts right before the assignment inside
of perform_assignment, so on line 25 we form an object reference to an object
outside of its lifetime which is ill formed.

gcc should emit an appropriate diagnostic.

Found by: Michael Schellenberger Costa

I hope it helps.

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

* [Bug c++/101631] gcc permits object reference to object outside of its lifetime during constant evaluation
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
@ 2021-07-26 20:45 ` redi at gcc dot gnu.org
  2021-07-27  2:32 ` fsb4000 at yandex dot ru
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-26 20:45 UTC (permalink / raw)
  To: gcc-bugs

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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |WAITING
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2021-07-26

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to fsb4000 from comment #0)
> (Obligatory godbolt: https://godbolt.org/z/6qG7v9eYx)

Godbolt links are not obligatory, but a testcase is. See
https://gcc.gnu.org/bugs

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

* [Bug c++/101631] gcc permits object reference to object outside of its lifetime during constant evaluation
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
  2021-07-26 20:45 ` [Bug c++/101631] " redi at gcc dot gnu.org
@ 2021-07-27  2:32 ` fsb4000 at yandex dot ru
  2021-07-27 11:06 ` rguenth at gcc dot gnu.org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: fsb4000 at yandex dot ru @ 2021-07-27  2:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from fsb4000 at yandex dot ru ---
Sure.

$ g++ -c -std=c++20 -save-temps main.cpp

$ g++ -v
Using built-in specs.
COLLECT_GCC=C:\tools\msys64\mingw64\bin\g++.exe
COLLECT_LTO_WRAPPER=C:/tools/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-10.3.0/configure --prefix=/mingw64
--with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32
--host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32
--with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include
--libexecdir=/mingw64/lib --enable-bootstrap --enable-checking=release
--with-arch=x86-64 --with-tune=generic
--enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit --enable-shared
--enable-static --enable-libatomic --enable-threads=posix --enable-graphite
--enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes
--enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug
--enable-lto --enable-libgomp --disable-multilib --disable-rpath
--disable-win32-registry --disable-nls --disable-werror --disable-symvers
--with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64
--with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev5, Built by MSYS2
project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues
--with-gnu-as --with-gnu-ld --with-boot-ldflags='-pipe
-Wl,--dynamicbase,--high-entropy-va,--nxcompat,--default-image-base-high
-Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc'
'LDFLAGS_FOR_TARGET=-pipe
-Wl,--dynamicbase,--high-entropy-va,--nxcompat,--default-image-base-high'
--enable-linker-plugin-flags='LDFLAGS=-static-libstdc++\ -static-libgcc\ -pipe\
-Wl,--dynamicbase,--high-entropy-va,--nxcompat,--default-image-base-high\
-Wl,--stack,12582912'
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Rev5, Built by MSYS2 project)

$ cat main.ii
# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.cpp"
struct sso {
    union {
        int buf[10];
        int* alloc;
    };
};

constexpr bool test_switch() noexcept {
    sso val;
    val.alloc = nullptr;
    val.buf[5] = 42;
    return true;
}
static_assert(test_switch());

constexpr void perform_assignment(int& left, int right) noexcept {
    left = right;
}

constexpr bool test_switch_with_indirection() noexcept {
    sso val;
    val.alloc = nullptr;
    perform_assignment(val.buf[5], 42);
    return true;
}
static_assert(test_switch_with_indirection());


Expected: 

static_assert(test_switch_with_indirection());

should fail.

Sceenshot(just in case ): https://imgur.com/a/DXYYq1y

My OS: Windows 10 Pro 64 bit, 21H1


I'm confused with "What we do not want: Bugs in releases or snapshots of GCC
not issued by the GNU Project. Report them to whoever provided you with the
release".
What should I do? I can check at godbolt.org or locally using gcc from msys2.
But it's stupid to report gcc bugs to people working on godbolt.org or msys2.
They are not gcc developers. 

BTW the bug report in the first comment is almost identical to bug report we
sent to Visual C++ developers:
https://developercommunity.visualstudio.com/t/cl-permits-object-reference-to-object-outside-of-i/1487178
(just cl instead of gcc)

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

* [Bug c++/101631] gcc permits object reference to object outside of its lifetime during constant evaluation
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
  2021-07-26 20:45 ` [Bug c++/101631] " redi at gcc dot gnu.org
  2021-07-27  2:32 ` fsb4000 at yandex dot ru
@ 2021-07-27 11:06 ` rguenth at gcc dot gnu.org
  2021-07-27 14:57 ` redi at gcc dot gnu.org
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-07-27 11:06 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|1                           |0
             Status|WAITING                     |UNCONFIRMED
           Keywords|                            |accepts-invalid

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

* [Bug c++/101631] gcc permits object reference to object outside of its lifetime during constant evaluation
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
                   ` (2 preceding siblings ...)
  2021-07-27 11:06 ` rguenth at gcc dot gnu.org
@ 2021-07-27 14:57 ` redi at gcc dot gnu.org
  2023-10-20  3:26 ` [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference cvs-commit at gcc dot gnu.org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: redi at gcc dot gnu.org @ 2021-07-27 14:57 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to fsb4000 from comment #2)
> I'm confused with "What we do not want: Bugs in releases or snapshots of GCC
> not issued by the GNU Project. Report them to whoever provided you with the
> release".

10.3.0 is an official release. 10.3.1 or some heavily patched GCC would not be.

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

* [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
                   ` (3 preceding siblings ...)
  2021-07-27 14:57 ` redi at gcc dot gnu.org
@ 2023-10-20  3:26 ` cvs-commit at gcc dot gnu.org
  2023-10-25  6:04 ` sjames at gcc dot gnu.org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-10-20  3:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 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:1d260ab0e39ea63644e3af3ab2e0db946026b5a6

commit r14-4771-g1d260ab0e39ea63644e3af3ab2e0db946026b5a6
Author: Nathaniel Shead <nathanieloshead@gmail.com>
Date:   Thu Oct 12 19:53:55 2023 +1100

    c++: indirect change of active union member in constexpr
[PR101631,PR102286]

    This patch adds checks for attempting to change the active member of a
    union by methods other than a member access expression.

    To be able to properly distinguish `*(&u.a) = ` from `u.a = `, this
    patch redoes the solution for c++/59950 to avoid extranneous *&; it
    seems that the only case that needed the workaround was when copying
    empty classes.

    This patch also ensures that constructors for a union field mark that
    field as the active member before entering the call itself; this ensures
    that modifications of the field within the constructor's body don't
    cause false positives (as these will not appear to be member access
    expressions). This means that we no longer need to start the lifetime of
    empty union members after the constructor body completes.

    As a drive-by fix, this patch also ensures that value-initialised unions
    are considered to have activated their initial member for the purpose of
    checking stores and accesses, which catches some additional mistakes
    pre-C++20.

            PR c++/101631
            PR c++/102286

    gcc/cp/ChangeLog:

            * call.cc (build_over_call): Fold more indirect refs for trivial
            assignment op.
            * class.cc (type_has_non_deleted_trivial_default_ctor): Create.
            * constexpr.cc (cxx_eval_call_expression): Start lifetime of
            union member before entering constructor.
            (cxx_eval_component_reference): Check against first member of
            value-initialised union.
            (cxx_eval_store_expression): Activate member for
            value-initialised union. Check for accessing inactive union
            member indirectly.
            * cp-tree.h (type_has_non_deleted_trivial_default_ctor):
            Forward declare.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp1y/constexpr-89336-3.C: Fix union initialisation.
            * g++.dg/cpp1y/constexpr-union6.C: New test.
            * g++.dg/cpp1y/constexpr-union7.C: New test.
            * g++.dg/cpp2a/constexpr-union2.C: New test.
            * g++.dg/cpp2a/constexpr-union3.C: New test.
            * g++.dg/cpp2a/constexpr-union4.C: New test.
            * g++.dg/cpp2a/constexpr-union5.C: New test.
            * g++.dg/cpp2a/constexpr-union6.C: New test.

    Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
    Reviewed-by: Jason Merrill <jason@redhat.com>

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

* [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
                   ` (4 preceding siblings ...)
  2023-10-20  3:26 ` [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference cvs-commit at gcc dot gnu.org
@ 2023-10-25  6:04 ` sjames at gcc dot gnu.org
  2023-10-26  0:19 ` nathanieloshead at gmail dot com
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: sjames at gcc dot gnu.org @ 2023-10-25  6:04 UTC (permalink / raw)
  To: gcc-bugs

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

Sam James <sjames at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org,
                   |                            |nathanieloshead at gmail dot com,
                   |                            |sjames at gcc dot gnu.org

--- Comment #5 from Sam James <sjames at gcc dot gnu.org> ---
Fixed for 14 then by the drive-by bit or is there something left?

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

* [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
                   ` (5 preceding siblings ...)
  2023-10-25  6:04 ` sjames at gcc dot gnu.org
@ 2023-10-26  0:19 ` nathanieloshead at gmail dot com
  2023-10-26 14:58 ` ppalka at gcc dot gnu.org
  2023-12-12 18:45 ` ppalka at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: nathanieloshead at gmail dot com @ 2023-10-26  0:19 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Nathaniel Shead <nathanieloshead at gmail dot com> ---
(In reply to Sam James from comment #5)
> Fixed for 14 then by the drive-by bit or is there something left?
It should be fixed now. The example in comment #2 is
g++.dg/cpp2a/constexpr-union2.C.

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

* [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
                   ` (6 preceding siblings ...)
  2023-10-26  0:19 ` nathanieloshead at gmail dot com
@ 2023-10-26 14:58 ` ppalka at gcc dot gnu.org
  2023-12-12 18:45 ` ppalka at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: ppalka at gcc dot gnu.org @ 2023-10-26 14:58 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
                 CC|                            |ppalka at gcc dot gnu.org
             Status|UNCONFIRMED                 |RESOLVED
   Target Milestone|---                         |14.0

--- Comment #7 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Marking this fixed for GCC 14 then, thanks!

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

* [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference
  2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
                   ` (7 preceding siblings ...)
  2023-10-26 14:58 ` ppalka at gcc dot gnu.org
@ 2023-12-12 18:45 ` ppalka at gcc dot gnu.org
  8 siblings, 0 replies; 10+ messages in thread
From: ppalka at gcc dot gnu.org @ 2023-12-12 18:45 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |m.cencora at gmail dot com

--- Comment #8 from Patrick Palka <ppalka at gcc dot gnu.org> ---
*** Bug 98637 has been marked as a duplicate of this bug. ***

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

end of thread, other threads:[~2023-12-12 18:45 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-26 18:46 [Bug c++/101631] New: gcc permits object reference to object outside of its lifetime during constant evaluation fsb4000 at yandex dot ru
2021-07-26 20:45 ` [Bug c++/101631] " redi at gcc dot gnu.org
2021-07-27  2:32 ` fsb4000 at yandex dot ru
2021-07-27 11:06 ` rguenth at gcc dot gnu.org
2021-07-27 14:57 ` redi at gcc dot gnu.org
2023-10-20  3:26 ` [Bug c++/101631] gcc allows for the changing of an union active member to be changed via a reference cvs-commit at gcc dot gnu.org
2023-10-25  6:04 ` sjames at gcc dot gnu.org
2023-10-26  0:19 ` nathanieloshead at gmail dot com
2023-10-26 14:58 ` ppalka at gcc dot gnu.org
2023-12-12 18:45 ` ppalka 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).