public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/52892] New: Function pointer loses constexpr qualification
@ 2012-04-06 18:58 EricMCornelius at gmail dot com
  2012-04-07 13:16 ` [Bug c++/52892] " daniel.kruegler at googlemail dot com
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: EricMCornelius at gmail dot com @ 2012-04-06 18:58 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892

             Bug #: 52892
           Summary: Function pointer loses constexpr qualification
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: EricMCornelius@gmail.com


The following test case is failing:

#include <cstdio>

constexpr std::size_t fibonacci(std::size_t 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(int argc, char* argv[]) {
  constexpr auto deferred = make_deferred(&fibonacci);
  static_assert(deferred(25) == 75025, "Static fibonacci call failed");
}

src/main.cpp: In function 'int main(int, char**)':
src/main.cpp:151:3: error: non-constant condition for static assertion
src/main.cpp:151:28:   in constexpr expansion of
'deferred.Defer<Function>::operator()<{int}>((* &25))'
src/main.cpp:140:24: error: expression 'fibonacci' does not designate a
constexpr function
test.make:129: recipe for target `obj/Debug/main.o' failed
make[1]: *** [obj/Debug/main.o] Error 1
makefile:16: recipe for target `test' failed
make: *** [test] Error 2

Based on my reading of the standard, this should be allowed behavior, and works
as expected with clang 3.1 (152539).

Note that the following behavior also fails similarly:

int main(int argc, char* argv[]) {
  constexpr auto deferred = make_deferred(&fibonacci);
  constexpr auto func = deferred.func;
  constexpr auto val = func(25);
}

src/main.cpp: In function 'int main(int, char**)':
src/main.cpp:152:31: error: expression 'fibonacci' does not designate a
constexpr function

Whereas this succeeds:

int main(int argc, char* argv[]) {
  constexpr auto func = &fibonacci;
  static_assert(func(25) == 75025, "Static fibonacci call failed");
}


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/52892] Function pointer loses constexpr qualification
  2012-04-06 18:58 [Bug c++/52892] New: Function pointer loses constexpr qualification EricMCornelius at gmail dot com
@ 2012-04-07 13:16 ` daniel.kruegler at googlemail dot com
  2012-05-29  9:28 ` adrien at guinet dot me
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2012-04-07 13:16 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892

--- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> 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 
> 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 

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<class... Args>
  constexpr auto operator()(const Args&... args) -> decltype(func(args...))
  {
    return func(args...);
  }
};

template<class Function>
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-processor
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 example
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. Both
use cases should not invalidate the constexpr character.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/52892] Function pointer loses constexpr qualification
  2012-04-06 18:58 [Bug c++/52892] New: Function pointer loses constexpr qualification EricMCornelius at gmail dot com
  2012-04-07 13:16 ` [Bug c++/52892] " daniel.kruegler at googlemail dot com
@ 2012-05-29  9:28 ` adrien at guinet dot me
  2013-05-02 14:57 ` paolo.carlini at oracle dot com
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: adrien at guinet dot me @ 2012-05-29  9:28 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892

Adrien Guinet <adrien at guinet dot me> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |adrien at guinet dot me

--- Comment #2 from Adrien Guinet <adrien at guinet dot me> 2012-05-29 09:26:29 UTC ---
Hello everyone,

Im ay have an issue related to this issue, if that can help:

#include <iostream>

struct A
{
    void f(int i) { std::cout << "f " << i << " " << _i << std::endl; }
    void f2(int i) { std::cout << "f2 " << i << " " << _i << std::endl; }
    int _i; 
};

template <typename F, F f>
struct class_f
{
    typedef F f_type;
    static constexpr f_type f_value = f;
    static constexpr f_type get() { return f; }
};


int main()
{
    typedef class_f<decltype(&A::f), &A::f> ff_t;

    // This does not compile
    class_f<ff_t::f_type, ff_t::f_value> ff; 

    // This does not compile either
    class_f<ff_t::f_type, static_cast<ff_t::f_type>(&A::f)> ff2;

    // This does
    class_f<ff_t::f_type, &A::f> ff_works;
}

It looks like using a function pointer that has been "instantiated" as an
"f_type" makes the compilation fails. here is the output of g++-4.7 with the
first "failing" tests :

$ g++-4.7 -std=c++0x ftempl.cpp
ftempl.cpp: In function ‘int main()’:
ftempl.cpp:24:37: error: could not convert template argument ‘class_f<void
(A::*)(int), &A::f>::f_value’ to ‘void (A::*)(int)’
ftempl.cpp:24:41: error: invalid type in declaration before ‘;’ token


$ g++-4.7 --version
g++-4.7 (Debian 4.7.0-8) 4.7.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/52892] Function pointer loses constexpr qualification
  2012-04-06 18:58 [Bug c++/52892] New: Function pointer loses constexpr qualification EricMCornelius at gmail dot com
  2012-04-07 13:16 ` [Bug c++/52892] " daniel.kruegler at googlemail dot com
  2012-05-29  9:28 ` adrien at guinet dot me
@ 2013-05-02 14:57 ` paolo.carlini at oracle dot com
  2014-08-27 17:04 ` paolo at gcc dot gnu.org
  2014-08-27 17:05 ` paolo.carlini at oracle dot com
  4 siblings, 0 replies; 6+ messages in thread
From: paolo.carlini at oracle dot com @ 2013-05-02 14:57 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2013-05-02
             Blocks|                            |55004
     Ever Confirmed|0                           |1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/52892] Function pointer loses constexpr qualification
  2012-04-06 18:58 [Bug c++/52892] New: Function pointer loses constexpr qualification EricMCornelius at gmail dot com
                   ` (2 preceding siblings ...)
  2013-05-02 14:57 ` paolo.carlini at oracle dot com
@ 2014-08-27 17:04 ` paolo at gcc dot gnu.org
  2014-08-27 17:05 ` paolo.carlini at oracle dot com
  4 siblings, 0 replies; 6+ messages in thread
From: paolo at gcc dot gnu.org @ 2014-08-27 17:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892

--- Comment #3 from paolo at gcc dot gnu.org <paolo at gcc dot gnu.org> ---
Author: paolo
Date: Wed Aug 27 17:03:34 2014
New Revision: 214579

URL: https://gcc.gnu.org/viewcvs?rev=214579&root=gcc&view=rev
Log:
/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.


Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-52282-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-52892-2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/52892] Function pointer loses constexpr qualification
  2012-04-06 18:58 [Bug c++/52892] New: Function pointer loses constexpr qualification EricMCornelius at gmail dot com
                   ` (3 preceding siblings ...)
  2014-08-27 17:04 ` paolo at gcc dot gnu.org
@ 2014-08-27 17:05 ` paolo.carlini at oracle dot com
  4 siblings, 0 replies; 6+ messages in thread
From: paolo.carlini at oracle dot com @ 2014-08-27 17:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52892

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED
   Target Milestone|---                         |5.0

--- Comment #4 from Paolo Carlini <paolo.carlini at oracle dot com> ---
Fixed.


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-08-27 17:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-06 18:58 [Bug c++/52892] New: Function pointer loses constexpr qualification EricMCornelius at gmail dot com
2012-04-07 13:16 ` [Bug c++/52892] " daniel.kruegler at googlemail dot com
2012-05-29  9:28 ` adrien at guinet dot me
2013-05-02 14:57 ` paolo.carlini at oracle dot com
2014-08-27 17:04 ` paolo at gcc dot gnu.org
2014-08-27 17:05 ` paolo.carlini at oracle dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).