Hi,
On 08/27/2014 04:19 PM, Jason Merrill wrote:
On 08/27/2014 04:41 AM, Paolo Carlini wrote:
.. two additional remarks (maybe obvious, I don't know):
- It also appears to work - for sure for all the tests in c++/52892 +
the tests in c++/52282 not involving data members (eg, the original one)
- simply unconditionally calling STRIP_NOPS right after the
cxx_eval_constant_expression at the beginning of
cxx_eval_call_expression (or calling it only when, after the fact, we
know it wraps a function pointer).
- Grepping in semantics.c reveals that in quite a few other places we
make sure to STRIP_NOPS before checking for ADDR_EXPR, it seems a
general issue.
True. OK, let's go ahead with your approach.
Thanks, let's give it a try at least, you know that I don't hesitate to
revert patches which give problems ;)
When testing completes again I mean to apply the below, the simplest
variant.
Thanks,
Paolo.
//////////////////////
/cp
2014-08-27 Paolo Carlini <paolo.carl...@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.carl...@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.
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 214576)
+++ cp/semantics.c (working copy)
@@ -8391,7 +8391,9 @@ cxx_eval_call_expression (const constexpr_call *ol
{
/* 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);
}
Index: testsuite/g++.dg/cpp0x/constexpr-52282-1.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-52282-1.C (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-52282-1.C (working copy)
@@ -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");
Index: testsuite/g++.dg/cpp0x/constexpr-52892-1.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-52892-1.C (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-52892-1.C (working copy)
@@ -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");
+}
Index: testsuite/g++.dg/cpp0x/constexpr-52892-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-52892-2.C (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-52892-2.C (working copy)
@@ -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");