diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2014-08-27 17:03:34 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2014-08-27 17:03:34 +0000 |
commit | d7afa673382e790f34aa8811c020f043580f9fa2 (patch) | |
tree | 01bedd2000e53feabec7995c08cdbca348ba5c27 /gcc | |
parent | 3d0b75dee41113c397caabd6b5690c6c39204d0d (diff) | |
download | gcc-d7afa673382e790f34aa8811c020f043580f9fa2.zip gcc-d7afa673382e790f34aa8811c020f043580f9fa2.tar.gz gcc-d7afa673382e790f34aa8811c020f043580f9fa2.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-52282-1.C | 32 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-52892-1.C | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-52892-2.C | 7 |
6 files changed, 83 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 388293a..2f7cc66 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +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> PR c++/58624 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9c9fc1c..168bde8 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 8835822..4b5def9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +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> 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 0000000..61797f0 --- /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 <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"); 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 0000000..8e6bc49 --- /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 <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"); +} 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 0000000..d2062ce --- /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"); |