Patchwork [C++,RFH/Patch] PR 52892 (and others)

login
register
mail settings
Submitter Paolo Carlini
Date Aug. 27, 2014, 3:16 p.m.
Message ID <53FDF666.2070103@oracle.com>
Download mbox | patch
Permalink /patch/383476/
State New
Headers show

Comments

Paolo Carlini - Aug. 27, 2014, 3:16 p.m.
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.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.

Patch

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");