c++: ICE with operator new[] in constexpr [PR118775]
Here we ICE since r11-7740 because we no longer say that (long)&a (where a is a global var) is non_constant_p. So VERIFY_CONSTANT does not return and we crash on tree_to_uhwi. We should check tree_fits_uhwi_p before calling tree_to_uhwi. PR c++/118775 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_call_expression): Check tree_fits_uhwi_p. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-new24.C: New test. * g++.dg/cpp2a/constexpr-new25.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
parent
c781da2c10
commit
aa55a6a30b
3 changed files with 63 additions and 0 deletions
|
@ -2928,6 +2928,17 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
|
|||
gcc_assert (arg0);
|
||||
if (new_op_p)
|
||||
{
|
||||
/* FIXME: We should not get here; the VERIFY_CONSTANT above
|
||||
should have already caught it. But currently a conversion
|
||||
from pointer type to arithmetic type is only considered
|
||||
non-constant for CONVERT_EXPRs, not NOP_EXPRs. */
|
||||
if (!tree_fits_uhwi_p (arg0))
|
||||
{
|
||||
if (!ctx->quiet)
|
||||
error_at (loc, "cannot allocate array: size not constant");
|
||||
*non_constant_p = true;
|
||||
return t;
|
||||
}
|
||||
tree type = build_array_type_nelts (char_type_node,
|
||||
tree_to_uhwi (arg0));
|
||||
tree var = build_decl (loc, VAR_DECL,
|
||||
|
|
25
gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
Normal file
25
gcc/testsuite/g++.dg/cpp2a/constexpr-new24.C
Normal file
|
@ -0,0 +1,25 @@
|
|||
// PR c++/118775
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
int a;
|
||||
|
||||
constexpr char *
|
||||
f1 ()
|
||||
{
|
||||
constexpr auto p = new char[(long int) &a]; // { dg-error "size not constant" }
|
||||
return p;
|
||||
}
|
||||
|
||||
constexpr char *
|
||||
f2 ()
|
||||
{
|
||||
auto p = new char[(long int) &a]; // { dg-error "size not constant" }
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
g ()
|
||||
{
|
||||
auto r1 = f2 ();
|
||||
constexpr auto r2 = f2 (); // { dg-message "in .constexpr. expansion" }
|
||||
}
|
27
gcc/testsuite/g++.dg/cpp2a/constexpr-new25.C
Normal file
27
gcc/testsuite/g++.dg/cpp2a/constexpr-new25.C
Normal file
|
@ -0,0 +1,27 @@
|
|||
// PR c++/118775
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
namespace std {
|
||||
struct __uniq_ptr_impl {
|
||||
constexpr __uniq_ptr_impl(char *) {}
|
||||
};
|
||||
template <typename> struct unique_ptr {
|
||||
__uniq_ptr_impl _M_t;
|
||||
constexpr ~unique_ptr() {}
|
||||
};
|
||||
template <typename> struct _MakeUniq;
|
||||
template <typename _Tp> struct _MakeUniq<_Tp[]> {
|
||||
typedef unique_ptr<_Tp[]> __array;
|
||||
};
|
||||
template <typename _Tp> using __unique_ptr_array_t = _MakeUniq<_Tp>::__array;
|
||||
constexpr __unique_ptr_array_t<char[]> make_unique(long __num) {
|
||||
return unique_ptr<char[]>(new char[__num]);
|
||||
}
|
||||
} // namespace std
|
||||
int a;
|
||||
int
|
||||
main ()
|
||||
{
|
||||
std::unique_ptr p = std::make_unique((long)&a);
|
||||
constexpr std::unique_ptr p2 = std::make_unique((long)&a); // { dg-error "conversion" }
|
||||
}
|
Loading…
Add table
Reference in a new issue