public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class
@ 2011-05-10 12:46 daniel.kruegler at googlemail dot com
  2011-05-10 14:53 ` [Bug c++/48948] " schaub.johannes at googlemail dot com
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-05-10 12:46 UTC (permalink / raw)
  To: gcc-bugs

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

           Summary: [C++0x] constexpr friend function cannot be defined
                    in-class
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: daniel.kruegler@googlemail.com
                CC: jason@redhat.com


gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
the line marked with #:

//---
struct B {
  friend constexpr int f(B) { return 0; } // #
};
//---

"error: invalid type for parameter 1 of constexpr function 'constexpr int
f(B)'"

This code should be accepted. 

The same problem occurs with friend operators, like this case

      friend constexpr int operator+(B) { return 0; }

within B resulting in:

"error: invalid type for parameter 1 of constexpr function 'constexpr int
operator+(B)'"

It seems to me that this defect is *not* a dup of bug 48945, where the compiler
incorrectly attempts to add a const-qualifier to a static member function. I
can only assume that the compiler considers the argument as incomplete and thus
not being a valid literal type, because other non-friend constexpr functions
don't cause such problems, but I'm not sure.

Finally, the problem does not occur, if the friend function is defined
out-of-class, like so:

    class C {
      friend constexpr int g(C);
    };

    constexpr int g(C) { return 0; }


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
@ 2011-05-10 14:53 ` schaub.johannes at googlemail dot com
  2011-05-10 16:41 ` daniel.kruegler at googlemail dot com
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-05-10 14:53 UTC (permalink / raw)
  To: gcc-bugs

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

Johannes Schaub <schaub.johannes at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schaub.johannes at
                   |                            |googlemail dot com

--- Comment #1 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-05-10 14:49:18 UTC ---
(In reply to comment #0)
> gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
> the line marked with #:
> 
> //---
> struct B {
>   friend constexpr int f(B) { return 0; } // #
> };
> //---
> 
> "error: invalid type for parameter 1 of constexpr function 'constexpr int
> f(B)'"
> 
> This code should be accepted. 
> 
> The same problem occurs with friend operators, like this case
> 
>       friend constexpr int operator+(B) { return 0; }
> 
> within B resulting in:
> 
> "error: invalid type for parameter 1 of constexpr function 'constexpr int
> operator+(B)'"
> 

Well, class "B" is incomplete in the parameter type list of f. The spec allows
B to be incomplete for that parameter type (8.3.5p9), but it doesn't say
anything what that means for determining whether or not the parameter has
literal class type (several of the bullets of 3.9p10 require a complete class
type to be checked). I don't know whether an implementation is supposed to
reject the code, or supposed to wait until B is complete. Same would apply for
non-static member functions.

Any hints?


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
  2011-05-10 14:53 ` [Bug c++/48948] " schaub.johannes at googlemail dot com
@ 2011-05-10 16:41 ` daniel.kruegler at googlemail dot com
  2011-05-10 16:56 ` schaub.johannes at googlemail dot com
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.kruegler at googlemail dot com @ 2011-05-10 16:41 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-05-10 16:33:39 UTC ---
(In reply to comment #1)

I don't think that this is intended, but I would like to await feedback from
the developer group before submitting a corresponding core issue. IMO there are
some core wordings in regard to type completeness that are not intended to be
read strictly, e.g. 3.2 p.4

"— a function with a return type or argument type of type T is defined (3.1)
[..]"

can be read to disallow any of the following function definitions:

struct A {
  A f(A a) { return a; }
  friend A g(A a) { return a; }
};

I haven't seen a compiler who rejects this code, because they all contribute
more weight to 9.2 p.2. In regard to constexpr functions the clear intention is
that these can be forward-declared and are only required to be completely
defined, if used in a manner that requires a constant expression. The example
in 7.1.5 with the constexpr function "small" and it's usage in the constexpr
constructor of pixel make this intention very clear. Now to me, the 3.2 p.4
requirement was always supposed to be interpreted as "complete as it would be
required to be complete within the function body" for both function parameters
and function return types within this function definition, so I don't see any
reason why the compiler needs to validate the constraints on literal types at
the point where the class type is still incomplete and *does* not need to be
complete.

If the gcc developer feedback indeed points to an intended conservative reading
of 3.2 p.4 for constexpr functions as in this example I will surely require to
open a core issue for this situation, because this severely constraints
constexpr function definitions within classes. In this case a simple workaround
is to replace the "by-value" parameter by "by-reference", but the need for such
a change looks like an artifact to me. It seems to me that both functions f()
and g() defined in class A above could be constexpr functions.


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
  2011-05-10 14:53 ` [Bug c++/48948] " schaub.johannes at googlemail dot com
  2011-05-10 16:41 ` daniel.kruegler at googlemail dot com
@ 2011-05-10 16:56 ` schaub.johannes at googlemail dot com
  2011-05-10 17:14 ` schaub.johannes at googlemail dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-05-10 16:56 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-05-10 16:46:18 UTC ---
(In reply to comment #2)
> (In reply to comment #1)
> 
> I don't think that this is intended, but I would like to await feedback from
> the developer group before submitting a corresponding core issue. IMO there are
> some core wordings in regard to type completeness that are not intended to be
> read strictly, e.g. 3.2 p.4
> 
> "— a function with a return type or argument type of type T is defined (3.1)
> [..]"
> 
> can be read to disallow any of the following function definitions:
> 
> struct A {
>   A f(A a) { return a; }
>   friend A g(A a) { return a; }
> };
> 
> I haven't seen a compiler who rejects this code, because they all contribute
> more weight to 9.2 p.2. 

Within "A a" (the parameters) and within "A f" / "A g" (the return types), the
class A is incomplete. Only within the function bodies, the class A is complete
by 9.2p2. 

The compilers accept that code because of 8.3.5p9. 3.2 p4 is a non-normative
big note, which can impossibly achieve the precision of covering every detail.
It only provides a rough description.


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (2 preceding siblings ...)
  2011-05-10 16:56 ` schaub.johannes at googlemail dot com
@ 2011-05-10 17:14 ` schaub.johannes at googlemail dot com
  2011-05-10 17:20 ` schaub.johannes at googlemail dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-05-10 17:14 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-05-10 16:59:50 UTC ---
(In reply to comment #0)
> gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
> the line marked with #:
> 
> //---
> struct B {
>   friend constexpr int f(B) { return 0; } // #
> };
> //---
> 
> "error: invalid type for parameter 1 of constexpr function 'constexpr int
> f(B)'"
> 
> This code should be accepted. 
> 

I remember that Gaby (I hope I remember correctly, hehe) argued that the body
of "f" is late-parsed. Hence, the argument, until after the end of definition
of "B", "f" is only considered declared but not defined.

I don't share that view though. That view is an implementation detail. In the
language, the function marked by "#" is defined as soon as its body has been
completely seen. If something else is intended, the specification needs to be
explicit about this. Unless I've missed the text, it is not explicit about
that.


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (3 preceding siblings ...)
  2011-05-10 17:14 ` schaub.johannes at googlemail dot com
@ 2011-05-10 17:20 ` schaub.johannes at googlemail dot com
  2011-05-10 17:32 ` schaub.johannes at googlemail dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-05-10 17:20 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-05-10 17:07:30 UTC ---
(In reply to comment #4)
> (In reply to comment #0)
> > gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
> > the line marked with #:
> > 
> > //---
> > struct B {
> >   friend constexpr int f(B) { return 0; } // #
> > };
> > //---
> > 
> > "error: invalid type for parameter 1 of constexpr function 'constexpr int
> > f(B)'"
> > 
> > This code should be accepted. 
> > 
> 
> I remember that Gaby (I hope I remember correctly, hehe) argued that the body
> of "f" is late-parsed. Hence, the argument, until after the end of definition
> of "B", "f" is only considered declared but not defined.
> 

Consider also this, which I think demonstrates that position:

struct A {
  struct B;
  void f(B) { }
  struct B { };
};

I think this is ill-formed by the spec, because "B" is incomplete in f's
parameter and f is defined at that point. And this is not one of the contexts
that B is allowed to be incomplete by 8.3.5p9.

However, clang, gcc and comeau online all accept this. Apparently, they
consider "f" only declared and not defined.

I would be glad if someone points me to the rule that says that "f" is only
considered defined at the closing "}" of A though.


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (4 preceding siblings ...)
  2011-05-10 17:20 ` schaub.johannes at googlemail dot com
@ 2011-05-10 17:32 ` schaub.johannes at googlemail dot com
  2011-05-11 21:37 ` jason at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-05-10 17:32 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #6 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-05-10 17:20:31 UTC ---
(In reply to comment #4)
> (In reply to comment #0)
> > gcc 4.7.0 20110507 (experimental) in C++0x mode rejects the following code at
> > the line marked with #:
> > 
> > //---
> > struct B {
> >   friend constexpr int f(B) { return 0; } // #
> > };
> > //---
> > 
> > "error: invalid type for parameter 1 of constexpr function 'constexpr int
> > f(B)'"
> > 
> > This code should be accepted. 
> > 
> 
> I remember that Gaby (I hope I remember correctly, hehe) argued that the body
> of "f" is late-parsed. Hence, the argument, until after the end of definition
> of "B", "f" is only considered declared but not defined.
> 
> I don't share that view though. That view is an implementation detail. In the
> language, the function marked by "#" is defined as soon as its body has been
> completely seen. If something else is intended, the specification needs to be
> explicit about this. Unless I've missed the text, it is not explicit about
> that.

But I can live with that. Having remembered the intent as described, I see that
the friend function you already showed is valid, because when the body is late
parsed, and the function is then considered defined only when the enclosing
class is complete, it makes sense. I wouldn't intuitively get to this result
though, but I think it's an interpretation I can live with!

I'm sorry for that load of nonsense in the comment boxes. I promise this is the
last comment in this row of this PR! :)


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (5 preceding siblings ...)
  2011-05-10 17:32 ` schaub.johannes at googlemail dot com
@ 2011-05-11 21:37 ` jason at gcc dot gnu.org
  2011-05-12  1:48 ` jason at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: jason at gcc dot gnu.org @ 2011-05-11 21:37 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #7 from Jason Merrill <jason at gcc dot gnu.org> 2011-05-11 21:30:23 UTC ---
Author: jason
Date: Wed May 11 21:30:18 2011
New Revision: 173683

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=173683
Log:
    PR c++/48948
    * semantics.c (validate_constexpr_fundecl): Defer checking if
    an argument type is being defined.
    (is_valid_constexpr_fn): Add defer_ok parm.
    (cxx_eval_call_expression): Adjust.
    (check_deferred_constexpr_decls): New.
    (literal_type_p): Make sure type isn't being defined.
    (ensure_literal_type_for_constexpr_object): Handle type being defined.
    * cp-tree.h: Declare check_deferred_constexpr_decls.
    * decl.c (grokfndecl): Call validate_constexpr_fundecl here.
    (start_preparsed_function, cp_finish_decl): Not here.
    * class.c (finalize_literal_type_property): Don't call
    validate_constexpr_fundecl.
    (finish_struct): Call check_deferred_constexpr_decls.
    * pt.c (tsubst_decl): Call validate_constexpr_fundecl.
    (instantiate_class_template): Call check_deferred_constexpr_decls.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/class.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (6 preceding siblings ...)
  2011-05-11 21:37 ` jason at gcc dot gnu.org
@ 2011-05-12  1:48 ` jason at gcc dot gnu.org
  2011-05-18 17:46 ` jason at gcc dot gnu.org
  2011-05-20 19:40 ` jason at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: jason at gcc dot gnu.org @ 2011-05-12  1:48 UTC (permalink / raw)
  To: gcc-bugs

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

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |jason at gcc dot gnu.org
         Resolution|                            |FIXED
         AssignedTo|unassigned at gcc dot       |jason at gcc dot gnu.org
                   |gnu.org                     |
   Target Milestone|---                         |4.7.0

--- Comment #8 from Jason Merrill <jason at gcc dot gnu.org> 2011-05-12 01:40:30 UTC ---
Fixed.


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (7 preceding siblings ...)
  2011-05-12  1:48 ` jason at gcc dot gnu.org
@ 2011-05-18 17:46 ` jason at gcc dot gnu.org
  2011-05-20 19:40 ` jason at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: jason at gcc dot gnu.org @ 2011-05-18 17:46 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from Jason Merrill <jason at gcc dot gnu.org> 2011-05-18 17:19:19 UTC ---
Author: jason
Date: Wed May 18 17:19:15 2011
New Revision: 173869

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=173869
Log:
    PR c++/48948
    PR c++/49015
    * class.c (finalize_literal_type_property): Do check
    for constexpr member functions of non-literal class.
    (finish_struct): Don't call check_deferred_constexpr_decls.
    * cp-tree.h: Don't declare it.
    (DECL_DEFERRED_CONSTEXPR_CHECK): Remove.
    * decl.c (grok_special_member_properties): Don't check it
    (grokfnedcl): Don't call validate_constexpr_fundecl.
    (start_preparsed_function): Do call it.
    * pt.c (tsubst_decl): Don't call it.
    (instantiate_class_template_1): Don't call
    check_deferred_constexpr_decls.
    * semantics.c (literal_type_p): Check for any incompleteness.
    (ensure_literal_type_for_constexpr_object): Likewise.
    (is_valid_constexpr_fn): Revert deferral changes.
    (validate_constexpr_fundecl): Likewise.
    (register_constexpr_fundef): Likewise.
    (check_deferred_constexpr_decls): Remove.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/class.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C


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

* [Bug c++/48948] [C++0x] constexpr friend function cannot be defined in-class
  2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
                   ` (8 preceding siblings ...)
  2011-05-18 17:46 ` jason at gcc dot gnu.org
@ 2011-05-20 19:40 ` jason at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: jason at gcc dot gnu.org @ 2011-05-20 19:40 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #10 from Jason Merrill <jason at gcc dot gnu.org> 2011-05-20 19:02:46 UTC ---
Author: jason
Date: Fri May 20 19:02:42 2011
New Revision: 173975

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=173975
Log:
    PR c++/48948
    * class.c (finalize_literal_type_property): Only check
    for constexpr member functions of non-literal class.
    * decl.c (cp_finish_decl): Don't call validate_constexpr_fundecl.
    * semantics.c (literal_type_p): Call complete_type.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-friend.C
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete1.C
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete2.C
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-incomplete3.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/class.c
    branches/gcc-4_6-branch/gcc/cp/decl.c
    branches/gcc-4_6-branch/gcc/cp/semantics.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-memfn1.C


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

end of thread, other threads:[~2011-05-20 19:39 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-10 12:46 [Bug c++/48948] New: [C++0x] constexpr friend function cannot be defined in-class daniel.kruegler at googlemail dot com
2011-05-10 14:53 ` [Bug c++/48948] " schaub.johannes at googlemail dot com
2011-05-10 16:41 ` daniel.kruegler at googlemail dot com
2011-05-10 16:56 ` schaub.johannes at googlemail dot com
2011-05-10 17:14 ` schaub.johannes at googlemail dot com
2011-05-10 17:20 ` schaub.johannes at googlemail dot com
2011-05-10 17:32 ` schaub.johannes at googlemail dot com
2011-05-11 21:37 ` jason at gcc dot gnu.org
2011-05-12  1:48 ` jason at gcc dot gnu.org
2011-05-18 17:46 ` jason at gcc dot gnu.org
2011-05-20 19:40 ` jason at gcc dot gnu.org

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).