public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used
@ 2021-04-06 11:33 redi at gcc dot gnu.org
  2021-04-06 12:41 ` [Bug c++/99934] " jakub at gcc dot gnu.org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2021-04-06 11:33 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 99934
           Summary: bad_array_new_length thrown when non-throwing
                    allocation function would have been used
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

Reduced from Bug 99845 comment 11:

namespace std {
  using size_t = decltype(sizeof(0));
}

extern "C" void abort();
extern "C" int puts(const char*);

struct X
{
  void* operator new[](std::size_t) noexcept {
    puts("should not be here");
    abort();
    return nullptr;
  }

  int data;
};

int main()
{
  int n = -1;
  auto p = new X[n];
  if (p)
    abort();
}

This terminates with:

terminate called after throwing an instance of 'std::bad_array_new_length'
  what():  std::bad_array_new_length
Aborted (core dumped)

The new-expression is erroneous (it has non-class type and its value before
converting to std::size_t is less than zero), the allocation function that
would be called is non-throwing, therefore the value of the new-expression
should be (X*)nullptr instead of throwing bad_array_new_length. This was
changed by https://wg21.link/cwg1992

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

* [Bug c++/99934] bad_array_new_length thrown when non-throwing allocation function would have been used
  2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
@ 2021-04-06 12:41 ` jakub at gcc dot gnu.org
  2022-03-28  9:17 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-04-06 12:41 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
For the non-global replaceable operator new call, we put the outer_nelts_check
already into the size argument before we actually look up the call:
      tree errval = TYPE_MAX_VALUE (sizetype);
      if (cxx_dialect >= cxx11 && flag_exceptions)
        errval = throw_bad_array_new_length ();
      if (outer_nelts_check != NULL_TREE)
        size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
                            size, errval);
...
          alloc_call
            = build_new_method_call (dummy, fns, &align_args,
                                     /*conversion_path=*/NULL_TREE,
                                     LOOKUP_NORMAL, &alloc_fn, tf_none);
...
        alloc_call = build_new_method_call (dummy, fns, placement,
                                            /*conversion_path=*/NULL_TREE,
                                            LOOKUP_NORMAL,
                                            &alloc_fn, complain);
So I guess either we should after alloc_call is built look whether it is
noexcept/throw() and if so, wrap it into another COND_EXPR with unshare_expr of
outer_nelts_check and alloc_call, build_zero_cst (TREE_TYPE (alloc_call)),
or perhaps that + at that point try to simplify the size argument of the call.
But I think any kind of CSE in GIMPLE or RTL optimizations should optimize that
already and so the FE doesn't need to duplicate such optimization.

Plus verify what happens with the global replaceable operators.

And another thing is constant expression evaluation,
http://eel.is/c++draft/expr.new#9.5 says we should reject it during constant
expression evaluation, but if we represent it as
COND_EXPR something, operator new (...), nullptr
then I'm afraid constant expression evaluation would accept it and evaluate to
nullptr.

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

* [Bug c++/99934] bad_array_new_length thrown when non-throwing allocation function would have been used
  2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
  2021-04-06 12:41 ` [Bug c++/99934] " jakub at gcc dot gnu.org
@ 2022-03-28  9:17 ` redi at gcc dot gnu.org
  2023-03-20  9:52 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2022-03-28  9:17 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2022-03-28
             Status|UNCONFIRMED                 |NEW

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

* [Bug c++/99934] bad_array_new_length thrown when non-throwing allocation function would have been used
  2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
  2021-04-06 12:41 ` [Bug c++/99934] " jakub at gcc dot gnu.org
  2022-03-28  9:17 ` redi at gcc dot gnu.org
@ 2023-03-20  9:52 ` redi at gcc dot gnu.org
  2023-03-20 10:08 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2023-03-20  9:52 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |barry.revzin at gmail dot com

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
*** Bug 93016 has been marked as a duplicate of this bug. ***

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

* [Bug c++/99934] bad_array_new_length thrown when non-throwing allocation function would have been used
  2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2023-03-20  9:52 ` redi at gcc dot gnu.org
@ 2023-03-20 10:08 ` redi at gcc dot gnu.org
  2023-03-20 10:23 ` redi at gcc dot gnu.org
  2024-04-22 16:14 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2023-03-20 10:08 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=102514
                 CC|                            |xmh970252187 at gmail dot com

--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
*** Bug 102514 has been marked as a duplicate of this bug. ***

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

* [Bug c++/99934] bad_array_new_length thrown when non-throwing allocation function would have been used
  2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2023-03-20 10:08 ` redi at gcc dot gnu.org
@ 2023-03-20 10:23 ` redi at gcc dot gnu.org
  2024-04-22 16:14 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2023-03-20 10:23 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2022-03-28 00:00:00         |2023-3-20

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Another case from Bug 102514:

namespace std {
  using size_t = decltype(sizeof(0));
}

extern "C" void abort();
extern "C" int puts(const char*);

int main()
{
  int n = -1;
  struct C {
    void* operator new[](std::size_t n) noexcept(false) {
      puts("C::operator new[] called");
      abort();
    }
  };
  C* ptr = new C[n];
}

C::operator new[] called
Aborted (core dumped)


I guess we don't throw bad_array_new_length here because sizeof(C) * size_t(-1)
fits in size_t. But it's still larger than the maximum possible object size,
and in any case, the expression n is less than zero so is erroneous so operator
new should never be called. The compiler should throw bad_array_new_length.

Similarly for this one with a non-throwing operator new[]:

namespace std {
  using size_t = decltype(sizeof(0));
}

extern "C" void abort();
extern "C" int puts(const char*);

int main()
{
  int n = -1;
  struct C2 {
    void* operator new[](std::size_t n) noexcept(true) {
      puts("C2::operator new[] called");
      abort();
    }
  };
  C2* ptr = new C2[n];
}

The sizeof(C2) * size_t(-1) result fits in size_t, so G++ calls the operator
new[]. But the expression is still erroneous, and so the compiler should just
produce a null pointer without calling C2::operator new[].

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

* [Bug c++/99934] bad_array_new_length thrown when non-throwing allocation function would have been used
  2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2023-03-20 10:23 ` redi at gcc dot gnu.org
@ 2024-04-22 16:14 ` redi at gcc dot gnu.org
  5 siblings, 0 replies; 7+ messages in thread
From: redi at gcc dot gnu.org @ 2024-04-22 16:14 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pshevchuk at pshevchuk dot com

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
*** Bug 114806 has been marked as a duplicate of this bug. ***

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

end of thread, other threads:[~2024-04-22 16:14 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-06 11:33 [Bug c++/99934] New: bad_array_new_length thrown when non-throwing allocation function would have been used redi at gcc dot gnu.org
2021-04-06 12:41 ` [Bug c++/99934] " jakub at gcc dot gnu.org
2022-03-28  9:17 ` redi at gcc dot gnu.org
2023-03-20  9:52 ` redi at gcc dot gnu.org
2023-03-20 10:08 ` redi at gcc dot gnu.org
2023-03-20 10:23 ` redi at gcc dot gnu.org
2024-04-22 16:14 ` 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).