From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15561 invoked by alias); 7 Apr 2012 13:16:07 -0000 Received: (qmail 15551 invoked by uid 22791); 7 Apr 2012 13:16:06 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,KHOP_THREADED X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 07 Apr 2012 13:15:54 +0000 From: "daniel.kruegler at googlemail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/52892] Function pointer loses constexpr qualification Date: Sat, 07 Apr 2012 13:16:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: daniel.kruegler at googlemail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-04/txt/msg00473.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D52892 --- Comment #1 from Daniel Kr=C3=BCgler 2012-04-07 13:15:13 UTC --- (In reply to comment #0) [..] > Based on my reading of the standard, this should be allowed behavior, and= =20 > works as expected with clang 3.1 (152539). I agree that this should work, this was the clear intention for the core language defect http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1193=20 I tried to break down the example to understand what's going wrong and here= is one simpler example: //--------------- constexpr bool is_negative(int x) { return x < 0; } struct Defer { #if 0 typedef bool (*Function)(int); Function func; constexpr Defer(Function func) : func(func) {} #else bool (*func)(int); constexpr Defer(bool (* func)(int)) : func(func) {} #endif template constexpr auto operator()(const Args&... args) -> decltype(func(args...)) { return func(args...); } }; template constexpr Defer make_deferred(Function func) { return Defer(func); } int main() { constexpr Defer deferred(make_deferred(is_negative)); static_assert(deferred(-2), "Error"); } //--------------- As written, this example is well-formed. But once we change the pre-process= or directive "#if 0" to "#if 1", we have a similar error. It seems that after introduction of the typedef for the function pointer type gcc no longer attempts to consider the track the constness. It is possible to construct an even simpler example. Consider the code exam= ple from CWG defect 1193 again: constexpr bool is_negative(int x) { return x < 0; } constexpr bool check(int x, bool (*p)(int)) { return p(x); } static_assert(check(-2, is_negative), "Error"); gcc accepts it as it should. Now lets introduce a typedef for the function pointer used in check: 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"); Now we get a similar error as in your example: "4|error: non-constant condition for static assertion| 4| in constexpr expansion of 'check(-2, is_negative)'| 3|error: expression 'is_negative' does not designate a constexpr function" The template parameter in your example has similar effects as a typedef. Bo= th use cases should not invalidate the constexpr character.