aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/constexpr.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/constexpr-new14.C73
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 ();