Bug 49015

Summary: [C++0x] Non-defining constexpr function declarations require complete argument/return types
Product: gcc Reporter: Daniel Krügler <daniel.kruegler>
Component: c++Assignee: Jason Merrill <jason>
Status: RESOLVED FIXED    
Severity: normal CC: jason, jason
Priority: P3    
Version: 4.7.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Daniel Krügler 2011-05-16 21:26:18 UTC
After successful resolution of bug 48948 gcc 4.7.0 20110514 (experimental) in C++0x mode now rejects the following code at the lines marked with #L-4 until #L-13:

//---
class A;
class B;

constexpr B f(A); // #L-4

class B {
  friend constexpr B g(A); // #L-7
};

class A {};

constexpr B f(A) { return B(); } // #L-12
constexpr B g(A) { return B(); } // #L-13
//---

"4|error: invalid type for parameter 1 of constexpr function 'constexpr B f(A)'|
4|error: invalid return type 'B' of constexpr function 'constexpr B f(A)'|
7|error: invalid type for parameter 1 of constexpr function 'constexpr B g(A)'|
7|error: invalid type for parameter 1 of constexpr function 'constexpr B g(A)'|
|In function 'constexpr B f(A)':|
12|error: redeclaration 'constexpr B f(A)' differs in 'constexpr'|
4|error: from previous declaration 'B f(A)'|
|In function 'constexpr B g(A)':|
13|error: redeclaration 'constexpr B g(A)' differs in 'constexpr'|
7|error: from previous declaration 'B g(A)'|
||=== Build finished: 8 errors, 0 warnings ===|

The parts following line 8 have mainly be added to demonstrate the general usefulness of the non-defining declarations and the error described by #L-12 and #L-13 is possibly overlaid by bug 48945 as well, so the main aspect of this issue are the #L-4 and #L-7 rejections if interaction with bug 48945 is the cause of #L-12 and #L-13.

I don't think that the literal-type requirements as of 3.9 p. 10 impose the requirements of complete types for the non-defining declarations of these constexpr functions, IMO the requirement for the complete type is only required for the final definition of f and g, which also seems to be intended as described by the example of 7.1.5 p. 1. In principle these examples are also not much different from constexpr function templates, which must delay the evaluation until the concrete instantiation and usage (The last aspect becomes clear by the 7.1.5 p. 1 example and demonstrates that this is a general character of constexpr functions irrespective of templates).
Comment 1 Jason Merrill 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
Comment 2 Jason Merrill 2011-05-18 17:47:58 UTC
Fixed.