Re: [c++-concepts] constrained friends redux

2013-10-04 Thread Andrew Sutton
 +  // Do not permit the declaration of constrained friend
 +  // function declarations. They cannot be instantiated since
 +  // the resulting declaration would never match the definition,
 +  // which must be a non-template and cannot be constrained.


 You're in the template-id code here, so must be a non-template is
 confusing:

 template class T void f();

 struct A {
   friend void fint(); // matches a template
 };

 Perhaps you mean that it must match a fully-instantiated function, so any
 constraints on the templates were considered during
 determine_specialization.

This seems like a simple comment fix, but there's a longer explanation
of what I want (see below). Would this be more appropriate?

  // Do not allow constrained friend template specializations.

The intent is stronger than to say it must match something. I don't
want to allow any declarations of the form

templatetypename T
struct X {
  friend void f(T x) requires CT; // Error.
};

This should never even get to determine_specialization since the
original declaration is never actually pushed.

We could use those constraints to match the specialization to one of
several constrained overloads, as you mentioned earlier, but I'd
rather avoid that for now. Solving that problem in general would
require that we allow constrained (explicit) specializations and
define a method of matching instantiated constraints to dependent
constraints, and that we do so as an alternative to the usual
constraint checking during template argument deduction.

Maybe it's a useful feature, but it's really hard to gauge how much
use it would actually get. We can always revisit that in the future.
Somebody else can write that paper :)

Andrew


Re: [c++-concepts] constrained friends redux

2013-10-04 Thread Jason Merrill

On 10/04/2013 09:20 AM, Andrew Sutton wrote:

Perhaps you mean that it must match a fully-instantiated function, so any
constraints on the templates were considered during
determine_specialization.



This seems like a simple comment fix, but there's a longer explanation
of what I want (see below). Would this be more appropriate?

   // Do not allow constrained friend template specializations.

The intent is stronger than to say it must match something.


By must I meant that whatever it matches could only be a 
fully-instantiated function.


But I guess the main reason for disallowing constraints here is the same 
as for explicit specializations and non-template functions; 
non-dependent constraints don't really make any sense.


Jason



Re: [c++-concepts] constrained friends redux

2013-10-04 Thread Andrew Sutton
 Perhaps you mean that it must match a fully-instantiated function, so
  any
 constraints on the templates were considered during
 determine_specialization.


 This seems like a simple comment fix, but there's a longer explanation
 of what I want (see below). Would this be more appropriate?

// Do not allow constrained friend template specializations.

 The intent is stronger than to say it must match something.


 By must I meant that whatever it matches could only be a
 fully-instantiated function.


I see what you mean. I was caught up in the wrong part of the
sentence.. But yes, that's right.

 But I guess the main reason for disallowing constraints here is the same as
 for explicit specializations and non-template functions; non-dependent
 constraints don't really make any sense.

That's the intent.

Okay to commit?

Andrew


friends-3.patch
Description: Binary data


Re: [c++-concepts] constrained friends redux

2013-10-04 Thread Jason Merrill

OK.

Jason


Re: [c++-concepts] constrained friends redux

2013-10-04 Thread Paolo Carlini

Hi Andrew,

On 10/04/2013 07:36 PM, Andrew Sutton wrote:

+  if (!check_template_constraints (tmpl, args))
+{
+  location_t loc = DECL_SOURCE_LOCATION (function);
+  error (%qD is not a viable candidate, function);
+  diagnose_constraints (input_location, tmpl, args);
+  return error_mark_node;
+}

Nit: loc seems unused.

Thanks,
Paolo.


[c++-concepts] constrained friends redux

2013-10-02 Thread Andrew Sutton
This patch implements constrained friends and disallows declarations
of constrained friend template specialization.

There was a previous question about whether I was doing the right
thing in determine_specialization. I'm looking at that issue
separately.

2013-10-01  Andrew Sutton  andrew.n.sut...@gmail.com
* gcc/cp/parser.c (cp_parser_member_declaration): Check that
a constrained friend definition is valid.
* gcc/cp/decl.c (grokfndecl): Disallow constrained friend template
specializations.
* gcc/cp/constraints.cc (check_constrained_friend): New.
* gcc/cp/typeck.c (cp_build_function_call_vec): Diagnose constraints
in the presence of the failure of a single candidate.
* gcc/cp/cp-tree.h (check_constrained_friend): New.
* gcc/cp/call.c (is_non_template_member_fn): Make inline.
(is_non_template_friend), (is_constrainable_non_template_fn): New.
(add_function_candidate): Predicate check on
is_constrainable_non_template_fn.

Andrew Sutton


friends-2.patch
Description: Binary data


Re: [c++-concepts] constrained friends redux

2013-10-02 Thread Jason Merrill

On 10/02/2013 09:05 AM, Andrew Sutton wrote:

+  // Do not permit the declaration of constrained friend
+  // function declarations. They cannot be instantiated since
+  // the resulting declaration would never match the definition,
+  // which must be a non-template and cannot be constrained.


You're in the template-id code here, so must be a non-template is 
confusing:


template class T void f();

struct A {
  friend void fint(); // matches a template
};

Perhaps you mean that it must match a fully-instantiated function, so 
any constraints on the templates were considered during 
determine_specialization.



+  error(constrained friend does not depend on template parameters);


Space before (.


+// Returns true if FN is a non-template member function.
+static inline bool
 is_non_template_member_fn (tree fn)
 {
   return DECL_FUNCTION_MEMBER_P (fn) 
@@ -1829,6 +1829,21 @@ is_non_template_member_fn (tree fn)
  !DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn));
 }

+// Returns true if FN is a non-template friend definition.
+static inline bool
+is_non_template_friend (tree fn)


These names/comments fail to make it clear that they return true only 
for non-template members/friends *of class template specializations*. 
So my preference would be to open-code them into 
is_constrainable_non_template_fn.


Jason