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.

Reply via email to