From: Paolo Carlini Date: Wed, 27 Aug 2014 17:03:34 +0000 (+0000) Subject: re PR c++/52892 (Function pointer loses constexpr qualification) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d7afa673382e790f34aa8811c020f043580f9fa2;p=gcc.git re PR c++/52892 (Function pointer loses constexpr qualification) /cp 2014-08-27 Paolo Carlini 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 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 388293a806b..2f7cc664f3d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-08-27 Paolo Carlini + + 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 PR c++/58624 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9c9fc1c0882..168bde8fc7c 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8391,7 +8391,9 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, { /* Might be a constexpr function pointer. */ 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) fun = TREE_OPERAND (fun, 0); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 883582291b4..4b5def9c633 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-08-27 Paolo Carlini + + 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 PR target/62262 diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52282-1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52282-1.C new file mode 100644 index 00000000000..61797f046d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52282-1.C @@ -0,0 +1,32 @@ +// PR c++/52282 +// { dg-do compile { target c++11 } } + +template +struct A + { + static constexpr T a() { return V; } + }; + +template +struct B + { + typedef T type; + static constexpr type b() { return V; } + }; + +template +struct C + { + static constexpr decltype(V) c() { return V; } + }; +static_assert(A::a() == 10, "oops"); +static_assert(B::b() == 10, "oops"); +static_assert(C::c() == 10, "oops"); + +struct D + { + static constexpr int d() { return 10; } + }; +static_assert((A::a())() == 10, "oops"); +static_assert((B::b())() == 10, "oops"); +static_assert((C::c())() == 10, "oops"); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-1.C new file mode 100644 index 00000000000..8e6bc49b632 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-1.C @@ -0,0 +1,28 @@ +// 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 +struct Defer { + constexpr Defer(const Function func_) : func(func_) { } + + const Function func; + + template + constexpr auto operator () (const Args&... args) -> decltype(func(args...)) { + return func(args...); + } +}; + +template +constexpr Defer make_deferred(const Function f) { + return Defer(f); +} + +int main() { + constexpr auto deferred = make_deferred(&fibonacci); + static_assert(deferred(25) == 75025, "Static fibonacci call failed"); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-2.C new file mode 100644 index 00000000000..d2062cee842 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-2.C @@ -0,0 +1,7 @@ +// 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");