re PR c++/52892 (Function pointer loses constexpr qualification)
authorPaolo Carlini <paolo.carlini@oracle.com>
Wed, 27 Aug 2014 17:03:34 +0000 (17:03 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 27 Aug 2014 17:03:34 +0000 (17:03 +0000)
/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

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/constexpr-52282-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/constexpr-52892-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/constexpr-52892-2.C [new file with mode: 0644]

index 388293a806b89de1f01fa29cd4f7eb1881cc543d..2f7cc664f3d06c092d33b80e9d1d07fa5637aa02 100644 (file)
@@ -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
index 9c9fc1c08826ecd4cdd04adbe629c5143217711d..168bde8fc7cafad3f95ca4495db08b8c40b85444 100644 (file)
@@ -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);
     }
index 883582291b414453481b097a5e2c5aff854db886..4b5def9c633e53e65507124aad822362450bc55a 100644 (file)
@@ -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 (file)
index 0000000..61797f0
--- /dev/null
@@ -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 (file)
index 0000000..8e6bc49
--- /dev/null
@@ -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 (file)
index 0000000..d2062ce
--- /dev/null
@@ -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");