Re: Patch for constexpr variable templates

2014-08-13 Thread Andrew Sutton
 Oohh... I can commit to trunk?

 Yes, you're on the write-after-approval list in MAINTAINERS. :)

True, but it's my first commit to trunk :) Incidentally, that's committed now.

Andrew


Re: Patch for constexpr variable templates

2014-08-12 Thread Andrew Sutton
  * pt.c (lookup_template_variable): Make the type unspecified if
  any template arguments are dependent.


 This hunk is OK.

Hi Jason, did you apply this hunk of the patch, or should I just
resend this by itself?

Andrew


Re: Patch for constexpr variable templates

2014-08-12 Thread Jason Merrill

On 08/12/2014 04:21 PM, Andrew Sutton wrote:

  * pt.c (lookup_template_variable): Make the type unspecified if
  any template arguments are dependent.



This hunk is OK.


Hi Jason, did you apply this hunk of the patch, or should I just
resend this by itself?


I thought you would apply it, but I can if you'd rather.

Jason



Re: Patch for constexpr variable templates

2014-08-12 Thread Andrew Sutton
Oohh... I can commit to trunk? I can do it tomorrow morning.

Andrew Sutton


On Tue, Aug 12, 2014 at 4:59 PM, Jason Merrill ja...@redhat.com wrote:
 On 08/12/2014 04:21 PM, Andrew Sutton wrote:

   * pt.c (lookup_template_variable): Make the type unspecified
 if
   any template arguments are dependent.



 This hunk is OK.


 Hi Jason, did you apply this hunk of the patch, or should I just
 resend this by itself?


 I thought you would apply it, but I can if you'd rather.

 Jason



Re: Patch for constexpr variable templates

2014-08-12 Thread Jason Merrill

On 08/12/2014 05:17 PM, Andrew Sutton wrote:

Oohh... I can commit to trunk?


Yes, you're on the write-after-approval list in MAINTAINERS. :)

Jason



Re: Patch for constexpr variable templates

2014-08-07 Thread Jason Merrill

On 08/07/2014 09:22 AM, Andrew Sutton wrote:

 * pt.c (lookup_template_variable): Make the type unspecified if
 any template arguments are dependent.


This hunk is OK.


 * decl.c (cp_finish_decl): Don't check the initializer if it is
 value-dependent.


Why is this needed?

Jason



Re: Patch for constexpr variable templates

2014-08-07 Thread Andrew Sutton
  * decl.c (cp_finish_decl): Don't check the initializer if it is
  value-dependent.


 Why is this needed?

I thought that check_initializer was evaluating the constant
expression, and was resulting in errors because a template-id
referring to a variable template with a concrete type wasn't being
marked as dependent.

Taking a second look, this change doesn't appear to be needed. The
change to lookup_template_variable seems to do enough. I just reran
the tests and it seems to behave correctly without it.

Andrew


Re: Patch for constexpr variable templates

2014-08-06 Thread Paolo Carlini

Hi,

On 08/06/2014 06:41 AM, Braden Obrzut wrote:
I can confirm that this is caused by a change to pt.c that happened, I 
think, the day before my last patch.


This can be fixed by first checking that the template is a function 
template at that line in pt.c.  Since variable templates can't be 
friends, it might also be suitable to skip that entire block if it is 
a function template.

Patch looks simple, then.

Should I submit that as a patch?

I suppose Jason would be glad to review and apply it!

Thanks,
Paolo.


Re: Patch for constexpr variable templates

2014-08-06 Thread Braden Obrzut

Here's a patch for the more conservative option.

- Braden Obrzut

2014-08-06  Braden Obrzut  ad...@maniacsvault.net

* pt.c (check_explicit_specialization): Ensure tmpl is a function
template before checking if it is inline for COMDAT.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 57e7216..3bc3961 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2817,7 +2817,7 @@ check_explicit_specialization (tree declarator,
 	   It's just the name of an instantiation.  But, it's not
 	   a request for an instantiation, either.  */
 	SET_DECL_IMPLICIT_INSTANTIATION (decl);
-	  else
+	  else if (DECL_FUNCTION_TEMPLATE_P (tmpl))
 	/* A specialization is not necessarily COMDAT.  */
 	DECL_COMDAT (decl) = DECL_DECLARED_INLINE_P (decl);
 


Re: Patch for constexpr variable templates

2014-08-06 Thread Jason Merrill

On 08/05/2014 04:06 PM, Paolo Carlini wrote:

Great. I will double check but var-templ4.C fails for me with an ICE.


Hunh, I wonder how I missed that.

Here's what I'm checking in; we want to unset DECL_COMDAT for variable 
templates, too.



commit b79ecb5928b875ba38b78a3fadb0dd70d6262513
Author: Jason Merrill ja...@redhat.com
Date:   Wed Aug 6 11:14:55 2014 -0400

	* pt.c (check_explicit_specialization): Don't test
	DECL_DECLARED_INLINE_P for a variable template.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 57e7216..998ace2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2817,9 +2817,11 @@ check_explicit_specialization (tree declarator,
 	   It's just the name of an instantiation.  But, it's not
 	   a request for an instantiation, either.  */
 	SET_DECL_IMPLICIT_INSTANTIATION (decl);
-	  else
+	  else if (TREE_CODE (decl) == FUNCTION_DECL)
 	/* A specialization is not necessarily COMDAT.  */
 	DECL_COMDAT (decl) = DECL_DECLARED_INLINE_P (decl);
+	  else if (TREE_CODE (decl) == VAR_DECL)
+	DECL_COMDAT (decl) = false;
 
 	  /* Register this specialization so that we can find it
 	 again.  */


Re: Patch for constexpr variable templates

2014-08-05 Thread Jason Merrill

Applied with a few formatting/comment tweaks, thanks!

Jason


Re: Patch for constexpr variable templates

2014-08-05 Thread Paolo Carlini

Hi,

On 08/05/2014 08:26 PM, Jason Merrill wrote:

Applied with a few formatting/comment tweaks, thanks!
Great. I will double check but var-templ4.C fails for me with an ICE. 
Can anybody reproduce?


Thanks!
Paolo.



/.../gcc/testsuite/g++.dg/cpp1y/var-templ4.C:8:17: internal compiler 
error: tree check: expected function_decl, have var_decl in 
check_explicit_specialization, at cp/pt.c:2822
0xde05a4 tree_check_failed(tree_node const*, char const*, int, char 
const*, ...)

../../trunk/gcc/tree.c:9174
0x5f9dd9 tree_check(tree_node*, char const*, int, char const*, tree_code)
../../trunk/gcc/tree.h:2729
0x5f9dd9 check_explicit_specialization(tree_node*, tree_node*, int, int)
../../trunk/gcc/cp/pt.c:2822
0x5af6e1 grokvardecl
../../trunk/gcc/cp/decl.c:8079
0x5af6e1 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*, 
decl_context, int, tree_node**)

../../trunk/gcc/cp/decl.c:10918
0x5b24b4 start_decl(cp_declarator const*, cp_decl_specifier_seq*, int, 
tree_node*, tree_node*, tree_node**)

../../trunk/gcc/cp/decl.c:4572
0x68ff5f cp_parser_init_declarator
../../trunk/gcc/cp/parser.c:16920
0x690b0a cp_parser_single_declaration
../../trunk/gcc/cp/parser.c:23494
0x69160d cp_parser_explicit_specialization
../../trunk/gcc/cp/parser.c:14418
0x69bfaf cp_parser_declaration
../../trunk/gcc/cp/parser.c:11152
0x69ab18 cp_parser_declaration_seq_opt
../../trunk/gcc/cp/parser.c:11085
0x69c3b3 cp_parser_translation_unit
../../trunk/gcc/cp/parser.c:4061
0x69c3b3 c_parse_file()
../../trunk/gcc/cp/parser.c:31954
0x7c0712 c_common_parse_file()
../../trunk/gcc/c-family/c-opts.c:1115


Re: Patch for constexpr variable templates

2014-08-05 Thread Braden Obrzut
I can confirm that this is caused by a change to pt.c that happened, I 
think, the day before my last patch.


This can be fixed by first checking that the template is a function 
template at that line in pt.c.  Since variable templates can't be 
friends, it might also be suitable to skip that entire block if it is a 
function template.


Should I submit that as a patch?

- Braden Obrzut

On 08/05/2014 04:06 PM, Paolo Carlini wrote:

Hi,

On 08/05/2014 08:26 PM, Jason Merrill wrote:

Applied with a few formatting/comment tweaks, thanks!
Great. I will double check but var-templ4.C fails for me with an ICE. 
Can anybody reproduce?


Thanks!
Paolo.



/.../gcc/testsuite/g++.dg/cpp1y/var-templ4.C:8:17: internal compiler 
error: tree check: expected function_decl, have var_decl in 
check_explicit_specialization, at cp/pt.c:2822
0xde05a4 tree_check_failed(tree_node const*, char const*, int, char 
const*, ...)

../../trunk/gcc/tree.c:9174
0x5f9dd9 tree_check(tree_node*, char const*, int, char const*, tree_code)
../../trunk/gcc/tree.h:2729
0x5f9dd9 check_explicit_specialization(tree_node*, tree_node*, int, int)
../../trunk/gcc/cp/pt.c:2822
0x5af6e1 grokvardecl
../../trunk/gcc/cp/decl.c:8079
0x5af6e1 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*, 
decl_context, int, tree_node**)

../../trunk/gcc/cp/decl.c:10918
0x5b24b4 start_decl(cp_declarator const*, cp_decl_specifier_seq*, int, 
tree_node*, tree_node*, tree_node**)

../../trunk/gcc/cp/decl.c:4572
0x68ff5f cp_parser_init_declarator
../../trunk/gcc/cp/parser.c:16920
0x690b0a cp_parser_single_declaration
../../trunk/gcc/cp/parser.c:23494
0x69160d cp_parser_explicit_specialization
../../trunk/gcc/cp/parser.c:14418
0x69bfaf cp_parser_declaration
../../trunk/gcc/cp/parser.c:11152
0x69ab18 cp_parser_declaration_seq_opt
../../trunk/gcc/cp/parser.c:11085
0x69c3b3 cp_parser_translation_unit
../../trunk/gcc/cp/parser.c:4061
0x69c3b3 c_parse_file()
../../trunk/gcc/cp/parser.c:31954
0x7c0712 c_common_parse_file()
../../trunk/gcc/c-family/c-opts.c:1115




Re: Patch for constexpr variable templates

2014-08-01 Thread Braden Obrzut

On 07/31/2014 08:53 AM, Jason Merrill wrote:
In the original mail you mentioned doing it in cp_parser_template_id; 
I agree that we probably don't want to do it there because of the 
complications you are seeing.  I was thinking about doing it when we 
normally resolve an id-expression that refers to a variable, once we 
know we're looking at an expression and not a declarator-id.  But I 
think my suggestion of cp_parser_id_expression was wrong, and it would 
be better in finish_id_expression.


Jason

Ahh sorry, I misread the function name you gave. finish_id_expression 
works just fine and doesn't require any extra work.  How does this patch 
look?


- Braden Obrzut

2014-08-01  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions and NULL_TREE
return from grokvardecl.
* decl2.c (check_member_template): Allow declaration of template member
variables.
* parser.c (cp_parser_template_id): Build a TEMPLATE_ID_EXPR for
variable templates.
* pt.c (determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count and
change non static data member error to variable template warning.
(check_explicit_specialization): Handle and check for malformed
variable template specializations.
(lookup_template_variable): New.
(tsubst_decl): Handle variable template specializations.
(do_decl_instantiation): Handle template variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.
(finish_id_expression): Instantiate variable templates.

2014-08-01  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/cpp1y/var-templ1.C: New.
* g++.dg/cpp1y/var-templ2.C: New.
* g++.dg/cpp1y/var-templ3.C: New.
* g++.dg/cpp1y/var-templ4.C: New.
* g++.dg/cpp1y/var-templ5.C: New.
* g++.dg/cpp1y/pr59638.C: Marked xfail for template variables as
function pointers taking auto are considered templates at the moment.
* g++.dg/parse/error50.C: Malformed statements look like variable 
templ.

* g++.dg/template/crash71.C: Looks like variable templ.
* g++.old-deja/g++.oliva/template10.C: Looks like variable templ.
* g++.old-deja/g++.pt/var1.C: Non-constexpr variable templ.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..2ac0472 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, int);
-static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
-			 int, int, tree);
+static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
+			 int, int, int, tree);
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 

Re: Patch for constexpr variable templates

2014-07-31 Thread Braden Obrzut
Here's an updated patch with cp_parser_id_expression instantiating the 
variable templates if this is indeed what we want to do.


The previous implementation did seem to make the distinction between 
static template class member variables and variable templates a bit more 
obvious.  See the first change to check_explicit_specialization.  
Related to that, grokvardecl might be using build_lang_decl more often 
than it did previously.  I might be able to narrow that down a little, 
but I'm not sure.


- Braden Obrzut

2014-07-31  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions and NULL_TREE
return from grokvardecl.
* decl2.c (check_member_template): Allow declaration of template member
variables.
* parser.c (make_id_declarator): Accept VAR_DECL for variable 
templates.

(cp_parser_template_id): Handle variable templates and return a
VAR_DECL.
(cp_parser_lookup_name): May now be passed a VAR_DECL which is already
resolved.
* pt.c (determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count and
change non static data member error to variable template warning.
(check_explicit_specialization): Handle variable templates.
(lookup_template_variable): New.
(tsubst_decl): Handle variable template specializations.
(do_decl_instantiation): Handle template variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.

2014-07-31  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/cpp1y/var-templ1.C: New.
* g++.dg/cpp1y/var-templ2.C: New.
* g++.dg/cpp1y/var-templ3.C: New.
* g++.dg/cpp1y/var-templ4.C: New.
* g++.dg/cpp1y/var-templ5.C: New.
* g++.dg/cpp1y/pr59638.C: Marked xfail for template variables as
function pointers taking auto are considered templates at the moment.
* g++.dg/parse/error50.C: Malformed statements look like variable
templ.
* g++.dg/template/crash71.C: Looks like variable templ.
* g++.old-deja/g++.oliva/template10.C: Looks like variable templ.
* g++.old-deja/g++.pt/var1.C: Non-constexpr variable templ.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..c9c36d8 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, int);
-static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
-			 int, int, tree);
+static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
+			 int, int, int, tree);
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
@@ -7943,9 +7943,11 @@ 

Re: Patch for constexpr variable templates

2014-07-31 Thread Jason Merrill

On 07/30/2014 05:33 PM, Braden Obrzut wrote:

On 07/30/2014 04:44 PM, Jason Merrill wrote:

Why not do this in cp_parser_id_expression?



I did mention this in the original mail, is this definitely the way it
should be done?


In the original mail you mentioned doing it in cp_parser_template_id; I 
agree that we probably don't want to do it there because of the 
complications you are seeing.  I was thinking about doing it when we 
normally resolve an id-expression that refers to a variable, once we 
know we're looking at an expression and not a declarator-id.  But I 
think my suggestion of cp_parser_id_expression was wrong, and it would 
be better in finish_id_expression.


Jason



Re: Patch for constexpr variable templates

2014-07-30 Thread Jason Merrill

On 07/29/2014 07:56 AM, Braden Obrzut wrote:

@@ -6289,6 +6289,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool 
address_p, bool cast_p,
  break;

default:
+ /* Convert variable template into VAR_DECL. */
+ if (TREE_CODE (postfix_expression) == TEMPLATE_ID_EXPR
+  variable_template_p (TREE_OPERAND (postfix_expression, 0)))
+   {
+ postfix_expression = finish_template_variable 
(postfix_expression);
+   }


Why not do this in cp_parser_id_expression?


+ if (DECL_FUNCTION_TEMPLATE_P (tmpl)
+  DECL_STATIC_FUNCTION_P (tmpl)


Indentation mismatch.

Jason



Re: Patch for constexpr variable templates

2014-07-30 Thread Braden Obrzut

On 07/30/2014 04:44 PM, Jason Merrill wrote:

Why not do this in cp_parser_id_expression?

I did mention this in the original mail, is this definitely the way it 
should be done?  Andrew pointed this out to me before sending in the 
patch, my initial investigation into doing so seemed to show it would 
require more changes than doing it later since that would mean that 
cp_parser_id_expression has another possible return type (to be fair, I 
didn't carry out a full implementation).  What I'm doing is equivalent 
to the point where function templates are instantiated so it could go 
either way, but from what I understand the only reason function 
templates are handled like that is because of overload resolution?  My 
implementation strategy thus far has been to mirror function templates 
as long as possible.


- Braden Obrzut


Re: Patch for constexpr variable templates

2014-07-29 Thread Braden Obrzut

This version of the patch should pass the entire test suite.

g++.dg/parse/error50.C noted that wasn't handling the case of empty 
template parameters properly (accepted silently).  As a result, 
grokvardecl now calls check_explicit_specialization more liberally and 
may return NULL_TREE.


The other changes to test cases are a result of this change causing 
additional errors on certain, variable template like constructs to be 
thrown.


- Braden Obrzut

2014-07-29  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions and NULL_TREE
return from grokvardecl.
* decl2.c (check_member_template): Allow declaration of template member
variables.
* parser.c (cp_parser_postfix_expression): Resolve VAR_DECLs from
TEMPLATE_ID_EXPRs.
(cp_parser_template_id): Build a TEMPLATE_ID_EXPR for variable
templates.
* pt.c (register_specialization): Accept variable templates.
(determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count and
change non static data member error to variable template warning.
(lookup_template_variable): New.
(do_decl_instantiation): Handle template variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.

2014-07-29  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/cpp1y/var-templ1.C: New.
* g++.dg/cpp1y/var-templ2.C: New.
* g++.dg/cpp1y/var-templ3.C: New.
* g++.dg/cpp1y/var-templ4.C: New.
* g++.dg/cpp1y/var-templ5.C: New.
* g++.dg/cpp1y/pr59638.C: Marked xfail for template variables as 
function

pointers taking auto are considered templates at the moment.
* g++.dg/parse/error50.C: Malformed statements look like variable 
templ.

* g++.dg/template/crash71.C: Looks like variable templ.
* g++.old-deja/g++.oliva/template10.C: Looks like variable templ.
* g++.old-deja/g++.pt/var1.C: Non-constexpr variable templ.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..2ac0472 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, int);
-static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
-			 int, int, tree);
+static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
+			 int, int, int, tree);
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
@@ -7943,9 +7943,11 @@ set_linkage_for_static_data_member (tree decl)
 static tree
 grokvardecl (tree type,
 	 tree name,
+	 tree orig_declarator,
 	 const cp_decl_specifier_seq *declspecs,
 	 int initialized,
 	 int constp,
+	 int 

Re: Patch for constexpr variable templates

2014-07-28 Thread Adam Butcher

On 2014-07-28 3:06, Braden Obrzut wrote:

So given this, should I leave the test cases that fail for this
reason alone or should I still change them to dg-message?


I'm not sure what GCC's policy is here, Jason will.


It sounds like GCC's behavior with auto in function parameters
needs to be changed, but that definitely sounds like a separate
patch to me.


I think so.  It's definitely a different patch.  I've been
thinking about a simple way for your patch to add to the
constraints for 'auto_is_implicit_function_template_parm_p' in
'cp_parser_parameter_declaration_clause' but this is happening
incrementally at parse time and I can't see how to distinguish
between the following 'auto' parameters:

 1)  auto f(auto);// generic function 'f'; transformed into 
template by 'auto' in parameter list.
 2)  auto (*f) (auto);// plain variable 'f' (should have an 
initializer for deduction of 'auto's.
 3)  auto (*f (auto)) (auto); // generic function 'f' constrained to 
returning a unary function pointer deduced from the return expression.


Ultimately, the last two would require the generalized 'auto'
type deduction behavior.  The difficulty is that there doesn't
appear to be any existing means for determining, at parse time
of the first (auto, whether we're forming a function or
variable declaration.  Maybe such state would fall out of a
generalized 'auto' solution.

Ever since generic functions were implemented, (2) has always
been seen as an attempt to declare a variable template.
Previously we've thrown these out.  As your patch now allows
them, it seems like something should be done here prior to a
final solution of fixing the behavior.  Maybe marking as
expected failures would be OK for now then raising a new
issue to address this properly.  Jason, what do you think?

Adam


Re: Patch for constexpr variable templates

2014-07-28 Thread Andrew Sutton
 It sounds like GCC's behavior with auto in function parameters
 needs to be changed, but that definitely sounds like a separate
 patch to me.

 I think so.  It's definitely a different patch.

Agreed.

 I've been
 thinking about a simple way for your patch to add to the
 constraints for 'auto_is_implicit_function_template_parm_p' in
 'cp_parser_parameter_declaration_clause' but this is happening
 incrementally at parse time and I can't see how to distinguish
 between the following 'auto' parameters:

  1)  auto f(auto);// generic function 'f'; transformed into
 template by 'auto' in parameter list.
  2)  auto (*f) (auto);// plain variable 'f' (should have an
 initializer for deduction of 'auto's.

  3)  auto (*f (auto)) (auto); // generic function 'f' constrained to
 returning a unary function pointer deduced from the return expression.

Really? I've read the comment and I'm still not sure how to read this
declaration.

 Ultimately, the last two would require the generalized 'auto'
 type deduction behavior.  The difficulty is that there doesn't
 appear to be any existing means for determining, at parse time
 of the first (auto, whether we're forming a function or
 variable declaration.  Maybe such state would fall out of a
 generalized 'auto' solution.

I was wondering about this on the drive to work this morning. Maybe
trying to pin down semantics at parse time isn't the right approach.
That is, always parse declarations like variables, and then build up
template parameters as needed during grorkdecl or grokfndecl. Or maybe
that's too late. I don't know.

Whatever the solution for auto, it will be the same for concepts.
We'll just add constraints to the auto-type whenever we find a
constrained-type-specifier.

Andrew


Re: Patch for constexpr variable templates

2014-07-28 Thread Jason Merrill

On 07/27/2014 10:06 PM, Braden Obrzut wrote:

So given this, should I leave the test cases that fail for this reason
alone or should I still change them to dg-message?  It sounds like GCC's
behavior with auto in function parameters needs to be changed, but that
definitely sounds like a separate patch to me.


I think let's leave them as dg-error, remove the expected error text, 
and mark them as xfail, i.e.


// { dg-error   { xfail *-*-* } }

Then a patch to treat these as variables with deduced type can fill in 
the appropriate error text.


Jason



Re: Patch for constexpr variable templates

2014-07-28 Thread Adam Butcher

On 2014-07-28 13:09, Andrew Sutton wrote:

 3)  auto (*f (auto)) (auto); // generic function 'f' constrained to
returning a unary function pointer deduced from the return 
expression.


Really? I've read the comment and I'm still not sure how to read this
declaration.

The first and last 'auto' in the line would be resolved by return type 
deduction, the second, in the parameter list, would be a synthesized 
template argument.


E.g. If the function were defined as

  auto (*crazy (auto f)) (auto)
  {
return f;
  }

then it is only well formed if instantiated with an 'f' that is 
convertible to some ptr-to-function type of the form R (*) (A).  At 
which point return type deduction would subst 'R' for the first 'auto' 
and 'A' for the last.


If it were passed a pointer to the following function

  int F(float);

then it should be instantiated as

  int (*crazy (int (*f) (float))) (float)
  {
return f;
  }

My point with case (3) is that it contains two function parameter lists 
that contain 'auto' but they need to be dealt with differently for 
generic function template argument synthesis and for return type 
deduction.



Ultimately, the last two would require the generalized 'auto'
type deduction behavior.  The difficulty is that there doesn't
appear to be any existing means for determining, at parse time
of the first (auto, whether we're forming a function or
variable declaration.  Maybe such state would fall out of a
generalized 'auto' solution.


I was wondering about this on the drive to work this morning. Maybe
trying to pin down semantics at parse time isn't the right approach.


I have a feeling you may be right.


That is, always parse declarations like variables, and then build up
template parameters as needed during grorkdecl or grokfndecl. Or 
maybe

that's too late. I don't know.

My thinking was going the other way other initially (assuming a 
function until you know it isn't).  But I think deduced return types 
would cause problems with this so I'm thinking the assume variable 
route might be better.  We'd have to generate some form of parametric 
type tree for the variable type before deduction from the initializer 
anyway and it may be that such a tree could be transformed into the 
function type should the decl turn out to be a function.


I recall my initial experience of implementing generic functions: I 
tried to work in the grok*decl space, but found that so many cases had 
to be handled explicitly and types rebuilt afterwards potentially after 
errors about 'auto' had already been issued (which needed additional 
cases to avoid).  I remember it being nasty.  But it was my first hack 
on the GCC code base; so that was probably a factor (still is!).  
Switching to the parsing route allowed to transform the code on the fly 
as if it had been written with the full template header from the start; 
making all the existing code happy.  I would like to eliminate the 
possibility of making the during parsing route work before diving back 
in to a post-parse solution.



Whatever the solution for auto, it will be the same for concepts.
We'll just add constraints to the auto-type whenever we find a
constrained-type-specifier.


Agreed.

Adam



Re: Patch for constexpr variable templates

2014-07-27 Thread Adam Butcher

On 2014-07-26 17:14, Jason Merrill wrote:

On 07/26/2014 12:11 PM, Jason Merrill wrote:

On 07/26/2014 03:04 AM, Braden Obrzut wrote:

On 07/25/2014 05:24 PM, Jason Merrill wrote:


Fair enough, but in that case let's use 'sorry' rather then 
'error' to

be clear that it's a missing feature.


Tests like g++.dg/cpp1y/pr59638.C produce extra failures if this is
changed.  Is there something I'm supposed to do to account for 
that?


Changing dg-error to dg-message should cover it.


Actually, we shouldn't be treating that testcase as declaring
variable templates at all.  Adam, any thoughts?


In the 59638 case, the declarations

  void (*a)(auto);
  void (*b)(auto) = 0;

are shorthand for

  template typename T void (*a)(T);
  template typename T void (*b)(T) = 0;

which, unless there's some constraint with variable templates that I'm 
not aware of, ought to define two variable templates 'a' and 'b' to be 
ptr-to-function-taking-T.  So I think it's correct that the variable 
template stuff should be triggering here.


Prefixing the two decls with constexpr does allow them to compile 
(albeit with an uninitialized const 'a' permerror in the first case).


The issue with 59638 was that the errors were not correctly unwinding 
the template scope so declarations further down the file were considered 
templates when the weren't.


There may be similar recovery issues with not supporting non-constexpr 
variable templates defined with 'auto' (if that's permitted at all).


Cheers,
Adam


Re: Patch for constexpr variable templates

2014-07-27 Thread Andrew Sutton
 In the 59638 case, the declarations

   void (*a)(auto);
   void (*b)(auto) = 0;

 are shorthand for

   template typename T void (*a)(T);
   template typename T void (*b)(T) = 0;

 which, unless there's some constraint with variable templates that I'm not
 aware of, ought to define two variable templates 'a' and 'b' to be
 ptr-to-function-taking-T.  So I think it's correct that the variable
 template stuff should be triggering here.

There isn't, but this interpretation isn't consistent with the use of
auto in variable declarations. For example, this:

  const auto x = 0;

does not mean:

  templatetypename T const T x = 0;

So I would be surprised if any of:

  void (*p1)(auto);
  auto (*p2)(int);
  vectorauto x;

did mean create a template instead of deduce the type of x.

Also, if we did have this interpretation of auto for some (but not
all?) variable declarations, we would have to know to write those as
template-ids:

  void (*p)(auto);
  pint = some_f;

since one cannot refer to a template specialization without arguments.

I'm much, much happier if, for variable templates, we always deduce
the type from the initializer.. Besides, that wording (or some
approximation thereof) is already in the TS for concepts. A question
came up during the CWG review as to whether we could declare function
parameters as void (*p)(auto), and EWG said, sure, go for it. We
also have the ability to declare function parameters as, e.g.,
vectorauto or pairconst auto, auto*. I applied that to variable
templates as well, since it would have been a bit inconsistent,
otherwise.

Andrew


Re: Patch for constexpr variable templates

2014-07-27 Thread Adam Butcher

On 2014-07-27 19:01, Andrew Sutton wrote:

In the 59638 case, the declarations

  void (*a)(auto);
  void (*b)(auto) = 0;

are shorthand for

  template typename T void (*a)(T);
  template typename T void (*b)(T) = 0;

which, unless there's some constraint with variable templates that 
I'm not

aware of, ought to define two variable templates 'a' and 'b' to be
ptr-to-function-taking-T.  So I think it's correct that the variable
template stuff should be triggering here.


There isn't, but this interpretation isn't consistent with the use of
auto in variable declarations.

True.  It's just what GCC currently does when it see's 'auto' in a 
function parameter list.  Sounds like it needs to be prevented from 
doing that in [at least] this case.



For example, this:

  const auto x = 0;

does not mean:

  templatetypename T const T x = 0;

So I would be surprised if any of:

  void (*p1)(auto);
  auto (*p2)(int);
  vectorauto x;

did mean create a template instead of deduce the type of x.

Indeed.  I accept the argument.  The only reason GCC does this is that 
it has a general implementation that introduces a template parameter 
list to the primary declaration whenever it sees 'auto' in a function 
parameter list; including a function parameter list in a function type.


If we know that we are not declaring a function (or know that we are 
declaring a variable), then we can prevent 'auto' from having the 
currently implemented meaning.  That would be an alternative resolution 
to 59638 (and friends) too.



Also, if we did have this interpretation of auto for some (but not
all?) variable declarations, we would have to know to write those as
template-ids:

  void (*p)(auto);
  pint = some_f;

since one cannot refer to a template specialization without 
arguments.


Agreed.  That's not pleasant.  And I question whether there's a 
motivating use case for variable templates that are function pointers 
(but I confess I haven't thought much about it).



I'm much, much happier if, for variable templates, we always deduce
the type from the initializer.. Besides, that wording (or some
approximation thereof) is already in the TS for concepts. A question
came up during the CWG review as to whether we could declare function
parameters as void (*p)(auto), and EWG said, sure, go for it. We
also have the ability to declare function parameters as, e.g.,
vectorauto or pairconst auto, auto*. I applied that to variable
templates as well, since it would have been a bit inconsistent,
otherwise.

Sounds good.  For function parameters this is implemented in GCC by 
introducing a template declaration; i.e. making the function in question 
a function template.  For variables we want a different solution that 
relies on doing some sort of tsubst of an initializer expression into 
the 'auto'-expressed variable type; effectively generalizing the 
handling of 'auto x = ...'.  We could probably leverage the current 
behavior to get the generalized (generic) type including template 
parameters, then do a substitution using the initializer expression to 
determine what they are (and error if no initializer is given).


Adam



Re: Patch for constexpr variable templates

2014-07-27 Thread Braden Obrzut
So given this, should I leave the test cases that fail for this reason 
alone or should I still change them to dg-message?  It sounds like GCC's 
behavior with auto in function parameters needs to be changed, but that 
definitely sounds like a separate patch to me.


- Braden Obrzut


Re: Patch for constexpr variable templates

2014-07-26 Thread Braden Obrzut
Ed, I looked into partial specializations and it looks like, while not 
trivial, it would be easy enough for me to do them.  However, it is not 
required for concepts (which can not be specialized), so should I fix 
them for this patch or as a separate patch later?


On 07/25/2014 05:24 PM, Jason Merrill wrote:


Fair enough, but in that case let's use 'sorry' rather then 'error' to 
be clear that it's a missing feature.


Tests like g++.dg/cpp1y/pr59638.C produce extra failures if this is 
changed.  Is there something I'm supposed to do to account for that?


- Braden Obrzut


Re: Patch for constexpr variable templates

2014-07-26 Thread Jason Merrill

On 07/26/2014 03:04 AM, Braden Obrzut wrote:

On 07/25/2014 05:24 PM, Jason Merrill wrote:


Fair enough, but in that case let's use 'sorry' rather then 'error' to
be clear that it's a missing feature.


Tests like g++.dg/cpp1y/pr59638.C produce extra failures if this is
changed.  Is there something I'm supposed to do to account for that?


Changing dg-error to dg-message should cover it.

Jason




Re: Patch for constexpr variable templates

2014-07-26 Thread Jason Merrill

On 07/26/2014 12:11 PM, Jason Merrill wrote:

On 07/26/2014 03:04 AM, Braden Obrzut wrote:

On 07/25/2014 05:24 PM, Jason Merrill wrote:


Fair enough, but in that case let's use 'sorry' rather then 'error' to
be clear that it's a missing feature.


Tests like g++.dg/cpp1y/pr59638.C produce extra failures if this is
changed.  Is there something I'm supposed to do to account for that?


Changing dg-error to dg-message should cover it.


Actually, we shouldn't be treating that testcase as declaring variable 
templates at all.  Adam, any thoughts?


Jason



Re: Patch for constexpr variable templates

2014-07-26 Thread Ed Smith-Rowland

On 07/26/2014 03:04 AM, Braden Obrzut wrote:
Ed, I looked into partial specializations and it looks like, while not 
trivial, it would be easy enough for me to do them.  However, it is 
not required for concepts (which can not be specialized), so should I 
fix them for this patch or as a separate patch later?
I see no reason why we can't add features in stages.  I just wondered if 
you had already given it a look.  Certainly constexpr variable templates 
are useful on their own.

On 07/25/2014 05:24 PM, Jason Merrill wrote:


Fair enough, but in that case let's use 'sorry' rather then 'error' 
to be clear that it's a missing feature.


Tests like g++.dg/cpp1y/pr59638.C produce extra failures if this is 
changed.  Is there something I'm supposed to do to account for that?


- Braden Obrzut





Re: Patch for constexpr variable templates

2014-07-25 Thread Braden Obrzut

On 07/24/2014 04:56 PM, Jason Merrill wrote:



+  /* Variable templates will need to have the class context.  */
+  if (VAR_P (value))
+DECL_CONTEXT (value) = current_class_type;


Why isn't this covered by grokvardecl?
Oops, as the changelog indicated, this was to satisfy the old version of 
variable_template_p which checked the scope.  I forgot to apply Gaby's 
second patch initially.  It's no longer needed so I've removed it.



+  else if (VAR_P (decl))
+{
+  if (!DECL_DECLARED_CONSTEXPR_P (decl))
+error (template declaration of non-constexpr variable 
%qD, decl);

+}


As Ed and Andrew pointed out, non-constexpr variable templates are fine.

This patch only covers constexpr variable templates, so it makes sense 
to produce an error for now.  Otherwise more confusing linker errors 
will be thrown regarding duplicate or missing symbols.  I do not believe 
it would be too difficult to extend this patch to do non-constexpr 
variables since it looks like the issue is assigning names, but it's 
outside of the scope of what is required for concepts which is what I'm 
assigned to for GSoC.


Other than that, the other issues you mentioned should be fixed.

- Braden Obrzut

2014-07-25  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions.
* decl2.c (check_member_template): Allow declaration of template member
variables.
* parser.c (cp_parser_postfix_expression): Resolve VAR_DECLs from
TEMPLATE_ID_EXPRs.
(cp_parser_template_id): Build a TEMPLATE_ID_EXPR for variable
templates.
* pt.c (register_specialization): Accept variable templates.
(determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count and
change non static data member error to variable template warning.
(lookup_template_variable): New.
(do_decl_instantiation): Handle template variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.

2014-07-25  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/cpp1y/var-templ1.C: New.
* g++.dg/cpp1y/var-templ2.C: New.
* g++.dg/cpp1y/var-templ3.C: New.
* g++.dg/cpp1y/var-templ4.C: New.
* g++.dg/cpp1y/var-templ5.C: New.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..eea2775 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, int);
-static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
-			 int, int, tree);
+static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
+			 int, int, int, tree);
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type

Re: Patch for constexpr variable templates

2014-07-25 Thread Ed Smith-Rowland

How difficult would it be to make partial specializations work:

// Write n*pi once for every possible type
templatetypename Tp, std::size_t N
  constexpr Tp npi = N * Tp(3.1415926535897932385L);

// Partial specialization for int type.
templatestd::size_t N
  constexpr double npiint, N = N * double(3.1415926535897932385L);



Re: Patch for constexpr variable templates

2014-07-25 Thread Jason Merrill

On 07/25/2014 07:43 AM, Braden Obrzut wrote:

This patch only covers constexpr variable templates, so it makes sense
to produce an error for now.


Fair enough, but in that case let's use 'sorry' rather then 'error' to 
be clear that it's a missing feature.


I ran the testsuite with your patch applied and got a bunch of failures. 
 For instance,


+FAIL: g++.old-deja/g++.other/anon2.C  -std=c++11 (internal compiler error)

is crashing here:


+ || TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR))


because orig_declarator is null.  Please fix this and the other failures.


+ Variable templates only available with 


Diagnostics aren't capitalized.


  gcc_assert (decl == error_mark_node
+ || variable_template_p (tmpl)
  || !(DECL_CONSTRUCTOR_P (decl)


Indentation mismatch.


   DECL_EXTERNAL (d) = 0;

-  /* Enter the scope of D so that access-checking works correctly.  */
-  push_nested_class (DECL_CONTEXT (d));
+ /* Enter the scope of D so that access-checking works correctly.  */
+ bool enter_context = DECL_CLASS_SCOPE_P (d);


Indentation mismatch.

Jason



Re: Patch for constexpr variable templates

2014-07-24 Thread Jason Merrill

First of all, thanks a lot for taking this on!  A few nitpicks:

On 07/21/2014 11:06 PM, Braden Obrzut wrote:

 grokvardecl (tree type,
 tree name,
+tree orig_declarator,
 const cp_decl_specifier_seq *declspecs,
 int initialized,
 int constp,
+int template_count,


Indentation mismatch.


+  if (orig_declarator  (processing_template_decl
+  || TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR))


The indentation is wrong, since the || is part of the inner 
parenthesized expression.



+  /* Variable templates will need to have the class context.  */
+  if (VAR_P (value))
+DECL_CONTEXT (value) = current_class_type;


Why isn't this covered by grokvardecl?


-  if (!is_overloaded_fn (fns))
+  bool var_templ = variable_template_p (fns);
+  if (!is_overloaded_fn (fns)  !var_templ)
 {
   error (%qD is not a function template, fns);


I think here we should check whether 'fns' and 'decl' are both variables 
or both functions so that we can give a better diagnostic.



+  if (cxx_dialect  cxx1y)
+permerror (DECL_SOURCE_LOCATION (decl),
+   %qD is not a static data member of a class template, 
decl);


It's customary to use pedwarn and mention the relevant -std= flag.


+  if ((specialization || member_specialization)
+ /* Variable templates don't apply.  */
+  (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE
+ || TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE))


Indentation mismatch.


+  // Namespace scope variable templates should have a template header.


Namespace-scope


+ if (!variable_template_p (tmpl)
+  DECL_STATIC_FUNCTION_P (tmpl)

...

+ if (!variable_template_p (tmpl))
+   copy_default_args_to_explicit_spec (decl);


I'd prefer to check for a function template here rather than not a 
variable template.



+  else if (VAR_P (decl))
+{
+  if (!DECL_DECLARED_CONSTEXPR_P (decl))
+error (template declaration of non-constexpr variable %qD, decl);
+}


As Ed and Andrew pointed out, non-constexpr variable templates are fine.


+  bool var_templ = DECL_TEMPLATE_INFO (decl)
+variable_template_p (DECL_TI_TEMPLATE (decl));


An expression on multiple lines should be parenthesized to preserve 
indentation.



+ bool enter_context = CLASS_TYPE_P (DECL_CONTEXT (d));


You can use DECL_CLASS_SCOPE_P.


+  return instantiate_template (TREE_OPERAND (var, 0), TREE_OPERAND (var, 1), 
tf_error);


Line too long.

Jason



Re: Patch for constexpr variable templates

2014-07-23 Thread Ed Smith-Rowland

Braden,

Great work on this.  In addition to helping with constraints there is at 
least one new library feature that depends on constexpr variable templates.


For my two cents it would be good to get just the constexpr variable 
templates, aka n3651, in now as a first stage - it's quite usable.


But someday we'll want non-constexpr too. I have only seen a sentence 
somewhere stating that non-constexpr variable templates are allowed but 
have seen no paper or wording anywhere.  Does anyone know where such exists?


Ed



Re: Patch for constexpr variable templates

2014-07-23 Thread Andrew Sutton
 But someday we'll want non-constexpr too. I have only seen a sentence
 somewhere stating that non-constexpr variable templates are allowed but have
 seen no paper or wording anywhere.  Does anyone know where such exists?

When variable templates were proposed, EWG decided they wanted
non-constexpr variable templates also. I think that the current draft
reflects that, since I can't find anything that says variable
templates shall be declared constexpr.

There's also an implied requirement for partial specialization of
variable templates (14.3.3p2), but no elaboration of that. Core issue
1711 specifically addresses this. A quick search shows that Clang
already implements it.

Andrew


Re: Patch for constexpr variable templates

2014-07-21 Thread Ed Smith-Rowland

Braden,

I've played with this and it seems to work nicely.
Only one comment:  Could you put the test cases in the C++14 subdirectory?

g++.dg/template/cpp1y/var-templ1.C

^
We should CC Jason on all this.

Also, do you have your FSF paperwork in place?

Thanks,

Ed



Re: Patch for constexpr variable templates

2014-07-21 Thread Braden Obrzut

Sure, test cases moved.

My FSF paperwork is in place.  I don't have write access to the 
repository though of course.


- Braden Obrzut

2014-07-21  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions.
* decl2.c (check_member_template): Allow declaration of template member
variables.
(grokfield): Assign class context to template member variables in order
that variable_template_p to detect them properly.
* parser.c (cp_parser_postfix_expression): Resolve VAR_DECLs from
TEMPLATE_ID_EXPRs.
(cp_parser_template_id): Build a TEMPLATE_ID_EXPR for variable 
templates.

* pt.c (register_specialization): Accept variable templates.
(determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count.
(lookup_template_variable): New.
(do_decl_instantiation): Handle templat variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.

2014-07-21  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/cpp1y/var-templ1.C: New.
* g++.dg/cpp1y/var-templ2.C: New.
* g++.dg/cpp1y/var-templ3.C: New.
* g++.dg/cpp1y/var-templ4.C: New.
* g++.dg/cpp1y/var-templ5.C: New.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.

On 07/21/2014 07:39 AM, Ed Smith-Rowland wrote:

Braden,

I've played with this and it seems to work nicely.
Only one comment:  Could you put the test cases in the C++14 
subdirectory?


g++.dg/template/cpp1y/var-templ1.C

^
We should CC Jason on all this.

Also, do you have your FSF paperwork in place?

Thanks,

Ed



diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..0b6fa54 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, int);
-static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
-			 int, int, tree);
+static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
+			 int, int, int, tree);
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
@@ -7943,9 +7943,11 @@ set_linkage_for_static_data_member (tree decl)
 static tree
 grokvardecl (tree type,
 	 tree name,
+		 tree orig_declarator,
 	 const cp_decl_specifier_seq *declspecs,
 	 int initialized,
 	 int constp,
+		 int template_count,
 	 tree scope)
 {
   tree decl;
@@ -7975,7 +7977,9 @@ grokvardecl (tree type,
 	  || (TREE_CODE (scope) == NAMESPACE_DECL
 	   current_lang_name != lang_name_cplusplus)
 	  /* Similarly for static data members.  */
-	  || TYPE_P (scope)))
+	  || TYPE_P (scope)
+	  /* Similarly for explicit specializations.  */
+	  || TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR))

Re: Patch for constexpr variable templates

2014-07-19 Thread Braden Obrzut
While working on variable concepts, I noticed that one of the added 
blocks of code was no longer needed due to a previous simplification and 
caused problems.  Also included a new test case which triggered the 
problem, and fixed a minor formatting issue.


As before, if the plan is to revive the existing variable template 
branch, I can redo the patch without Gabriel's changes.


2014-07-19  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions.
* decl2.c (check_member_template): Allow declaration of template member
variables.
(grokfield): Assign class context to template member variables in order
that variable_template_p to detect them properly.
* parser.c (cp_parser_postfix_expression): Resolve VAR_DECLs from
TEMPLATE_ID_EXPRs.
(cp_parser_template_id): Build a TEMPLATE_ID_EXPR for variable 
templates.

* pt.c (register_specialization): Accept variable templates.
(determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count.
(lookup_template_variable): New.
(do_decl_instantiation): Handle templat variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.

2014-07-19  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/template/var-templ1.C: New.
* g++.dg/template/var-templ2.C: New.
* g++.dg/template/var-templ3.C: New.
* g++.dg/template/var-templ4.C: New.
* g++.dg/template/var-templ5.C: New.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..0b6fa54 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);
 static tree grok_reference_init (tree, tree, tree, int);
-static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
-			 int, int, tree);
+static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
+			 int, int, int, tree);
 static int check_static_variable_definition (tree, tree);
 static void record_unknown_type (tree, const char *);
 static tree builtin_function_1 (tree, tree, bool);
@@ -7943,9 +7943,11 @@ set_linkage_for_static_data_member (tree decl)
 static tree
 grokvardecl (tree type,
 	 tree name,
+		 tree orig_declarator,
 	 const cp_decl_specifier_seq *declspecs,
 	 int initialized,
 	 int constp,
+		 int template_count,
 	 tree scope)
 {
   tree decl;
@@ -7975,7 +7977,9 @@ grokvardecl (tree type,
 	  || (TREE_CODE (scope) == NAMESPACE_DECL
 	   current_lang_name != lang_name_cplusplus)
 	  /* Similarly for static data members.  */
-	  || TYPE_P (scope)))
+	  || TYPE_P (scope)
+	  /* Similarly for explicit specializations.  */
+	  || TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR))
 decl = build_lang_decl (VAR_DECL, name, type);
   else
 decl = 

Patch for constexpr variable templates

2014-07-12 Thread Braden Obrzut
Here is a patch that expands on Gabriel Dos Reis's initial var-template 
patch ( https://gcc.gnu.org/ml/gcc-patches/2013-03/msg01295.html ).  I 
just noticed now that those patches were committed to a branch, so if 
need be I can resubmit the patch with Gaby's changes not included.


The purpose of the patch is to implement the subset of variable 
templates that is a prerequisite for concept variables in the 
c++-concepts branch.  With that said, only constexpr variables are 
supported (both in namespace and class scopes).  There is no handling 
for generating symbols for these variables so they are only supported in 
contexts where they can be evaluated at compile time (I believe that 
would be only as an rvalue).  On that note, explicit instantiations of 
variable templates do work, but will generate duplicate symbol errors if 
more than one exists in the file.  Other than those issues, the should 
work as expected.


I would like to call attention to the changes in parser.c.  Andrew 
pointed out to me that it may be a good idea to have 
cp_parser_template_id return the instantiated VAR_DECL directly instead 
of deferring it to cp_parser_postfix_expression like function 
templates.  Since this would produce a new possible return type for the 
function, I've found that would require more widespread changes 
(although I can't accurately say by how much).  By deferring the 
instantiation, some code can be shared between function templates and 
variable templates.


2014-07-12  Braden Obrzut  ad...@maniacsvault.net

* decl.c (grokvardecl): Handle specializations of variable templates.
(grokdeclarator): Handle variable template id expressions.
* decl2.c (check_member_template): Allow declaration of template member
variables.
(grokfield): Assign class context to template member variables in order
that variable_template_p to detect them properly.
* parser.c (cp_parser_postfix_expression): Resolve VAR_DECLs from
TEMPLATE_ID_EXPRs.
(cp_parser_template_id): Build a TEMPLATE_ID_EXPR for variable 
templates.

* pt.c (register_specialization): Accept variable templates.
(determine_specialization): Accept variable templates.
(check_template_variable): Fixed wanted template header count.
(lookup_template_variable): New.
(instantiate_template_1): Evaluate initializer for variable templates.
(do_decl_instantiation): Handle templat variables.
(instantiate_decl): Handle template variables.
* semantics.c (finish_template_variable): New.

2014-07-12  Braden Obrzut  ad...@maniacsvault.net

* g++.dg/template/var-templ1.C: New.
* g++.dg/template/var-templ2.C: New.
* g++.dg/template/var-templ3.C: New.
* g++.dg/template/var-templ4.C: New.

2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): Do not check scope.
* pt.c (check_template_variable): Fix thinko from previous change.
(push_template_decl_real): Fix formatting.


2013-03-29  Gabriel Dos Reis  g...@integrable-solutions.net

* cp-tree.h (variable_template_p): New.
* pt.c (check_template_variable): Accept variable temploids at
non-class scope.
(push_template_decl_real): The current instantiation of a template
can be a VAR_DECL.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4a5cb98..c6c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5027,6 +5027,17 @@ class_of_this_parm (const_tree fntype)
   return TREE_TYPE (type_of_this_parm (fntype));
 }
 
+/* True if T designates a variable template declaration.  */
+inline bool
+variable_template_p (tree t)
+{
+  if (TREE_CODE (t) != TEMPLATE_DECL)
+return false;
+  if (tree r = DECL_TEMPLATE_RESULT (t))
+return VAR_P (r);
+  return false;
+}
+
 /* A parameter list indicating for a function with no parameters,
e.g  int f(void).  */
 extern cp_parameter_declarator *no_parameters;
@@ -5554,6 +5565,7 @@ extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 		 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
+extern tree lookup_template_variable		(tree, tree);
 extern int uses_template_parms			(tree);
 extern int uses_template_parms_level		(tree, int);
 extern bool in_template_function		(void);
@@ -5816,6 +5828,7 @@ extern tree perform_koenig_lookup		(tree, vectree, va_gc *,
 		 tsubst_flags_t);
 extern tree finish_call_expr			(tree, vectree, va_gc **, bool,
 		 bool, tsubst_flags_t);
+extern tree finish_template_variable	(tree);
 extern tree finish_increment_expr		(tree, enum tree_code);
 extern tree finish_this_expr			(void);
 extern tree finish_pseudo_destructor_expr   (tree, tree, tree, location_t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dae85c2..62cc256 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -80,8 +80,8 @@ static int ambi_op_p (enum tree_code);
 static int unary_op_p (enum tree_code);
 static void push_local_name (tree);