Commit d7afa673 by Paolo Carlini Committed by Paolo Carlini

re PR c++/52892 (Function pointer loses constexpr qualification)

/cp
2014-08-27  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52892
	* semantics.c (cxx_eval_call_expression): Use STRIP_NOPS on the
	result of cxx_eval_constant_expression.

/testsuite
2014-08-27  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/52892
	* g++.dg/cpp0x/constexpr-52892-1.C: New.
	* g++.dg/cpp0x/constexpr-52892-2.C: Likewise.
	* g++.dg/cpp0x/constexpr-52282-1.C: Likewise.

From-SVN: r214579
parent 3d0b75de
2014-08-27 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/52892
* semantics.c (cxx_eval_call_expression): Use STRIP_NOPS on the
result of cxx_eval_constant_expression.
2014-08-26 Jason Merrill <jason@redhat.com> 2014-08-26 Jason Merrill <jason@redhat.com>
PR c++/58624 PR c++/58624
......
...@@ -8391,7 +8391,9 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, ...@@ -8391,7 +8391,9 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t,
{ {
/* Might be a constexpr function pointer. */ /* Might be a constexpr function pointer. */
fun = cxx_eval_constant_expression (old_call, fun, allow_non_constant, fun = cxx_eval_constant_expression (old_call, fun, allow_non_constant,
/*addr*/false, non_constant_p, overflow_p); /*addr*/false, non_constant_p,
overflow_p);
STRIP_NOPS (fun);
if (TREE_CODE (fun) == ADDR_EXPR) if (TREE_CODE (fun) == ADDR_EXPR)
fun = TREE_OPERAND (fun, 0); fun = TREE_OPERAND (fun, 0);
} }
......
2014-08-27 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/52892
* g++.dg/cpp0x/constexpr-52892-1.C: New.
* g++.dg/cpp0x/constexpr-52892-2.C: Likewise.
* g++.dg/cpp0x/constexpr-52282-1.C: Likewise.
2014-08-27 Guozhi Wei <carrot@google.com> 2014-08-27 Guozhi Wei <carrot@google.com>
PR target/62262 PR target/62262
......
// PR c++/52282
// { dg-do compile { target c++11 } }
template <typename T, T V>
struct A
{
static constexpr T a() { return V; }
};
template <typename T, T V>
struct B
{
typedef T type;
static constexpr type b() { return V; }
};
template <typename T, T V>
struct C
{
static constexpr decltype(V) c() { return V; }
};
static_assert(A<int, 10>::a() == 10, "oops");
static_assert(B<int, 10>::b() == 10, "oops");
static_assert(C<int, 10>::c() == 10, "oops");
struct D
{
static constexpr int d() { return 10; }
};
static_assert((A<int(*)(), &D::d>::a())() == 10, "oops");
static_assert((B<int(*)(), &D::d>::b())() == 10, "oops");
static_assert((C<int(*)(), &D::d>::c())() == 10, "oops");
// PR c++/52892
// { dg-do compile { target c++11 } }
constexpr __SIZE_TYPE__ fibonacci(__SIZE_TYPE__ val) {
return (val <= 2) ? 1 : fibonacci(val - 1) + fibonacci(val - 2);
}
template <typename Function>
struct Defer {
constexpr Defer(const Function func_) : func(func_) { }
const Function func;
template <typename... Args>
constexpr auto operator () (const Args&... args) -> decltype(func(args...)) {
return func(args...);
}
};
template <typename Function>
constexpr Defer<Function> make_deferred(const Function f) {
return Defer<Function>(f);
}
int main() {
constexpr auto deferred = make_deferred(&fibonacci);
static_assert(deferred(25) == 75025, "Static fibonacci call failed");
}
// PR c++/52892
// { dg-do compile { target c++11 } }
constexpr bool is_negative(int x) { return x < 0; }
typedef bool (*Function)(int);
constexpr bool check(int x, Function p) { return p(x); }
static_assert(check(-2, is_negative), "Error");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment