diff options
-rw-r--r-- | gcc/cp/constexpr.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/constexpr-new14.C | 73 |
2 files changed, 75 insertions, 1 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index dacce58..a118f8a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2342,9 +2342,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, tree arg = CALL_EXPR_ARG (t, i); arg = cxx_eval_constant_expression (ctx, arg, false, non_constant_p, overflow_p); - VERIFY_CONSTANT (arg); if (i == 1) arg1 = arg; + else + VERIFY_CONSTANT (arg); } gcc_assert (arg1); return arg1; diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new14.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new14.C new file mode 100644 index 0000000..fd6f607 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new14.C @@ -0,0 +1,73 @@ +// PR c++/97195 +// { dg-do compile { target c++20 } } + +namespace std +{ + typedef __SIZE_TYPE__ size_t; + + template <typename T> + struct allocator + { + constexpr allocator () noexcept {} + + constexpr T *allocate (size_t n) + { return static_cast<T *> (::operator new (n * sizeof(T))); } + + constexpr void + deallocate (T *p, size_t n) + { ::operator delete (p); } + }; + + template <typename T, typename U = T &&> + U __declval (int); + template <typename T> + T __declval (long); + template <typename T> + auto declval () noexcept -> decltype (__declval<T> (0)); + + template <typename T> + struct remove_reference + { typedef T type; }; + template <typename T> + struct remove_reference<T &> + { typedef T type; }; + template <typename T> + struct remove_reference<T &&> + { typedef T type; }; + + template <typename T> + constexpr T && + forward (typename std::remove_reference<T>::type &t) noexcept + { return static_cast<T&&> (t); } + + template<typename T> + constexpr T && + forward (typename std::remove_reference<T>::type &&t) noexcept + { return static_cast<T&&> (t); } + + template <typename T, typename... A> + constexpr auto + construct_at (T *l, A &&... a) + noexcept (noexcept (::new ((void *) 0) T (std::declval<A> ()...))) + -> decltype (::new ((void *) 0) T (std::declval<A> ()...)) + { return ::new ((void *) l) T (std::forward<A> (a)...); } + + template <typename T> + constexpr inline void + destroy_at (T *l) + { l->~T (); } +} + +inline void *operator new (std::size_t, void *p) noexcept +{ return p; } + +constexpr bool +foo () +{ + int a = 5; + int *p = std::construct_at (&a, -1); + if (p[0] != -1) + throw 1; + return true; +} +constexpr bool b = foo (); |