Re: [C++ Patch / RFC] PR 53211

2013-06-18 Thread Jason Merrill

On 06/17/2013 08:21 PM, Paolo Carlini wrote:

I see... There is a little difficulty in that 56794 involves a non-type
variadic parameter and in that case type_dependent_expression_p returns
false. If I use value_dependent_expression_p things work, but I'm not
sure it's 100% correct.


I don't think we need to consider whether the initializer is dependent 
here; if the array has no length and has an initializer, it must be that 
we couldn't determine its length in cp_complete_array_type because it is 
dependent.



Eventually, we'll have to decide where we want to commit this: 56794 is
fixed in 4.7 and 4.8 too, but it's true that the issue with the specific
testcase attached by Jon isn't a regression.


I think apply it to 4.8 as well.

Jason



Re: [C++ Patch / RFC] PR 53211

2013-06-18 Thread Paolo Carlini

Hi,

On 06/18/2013 04:15 PM, Jason Merrill wrote:

On 06/17/2013 08:21 PM, Paolo Carlini wrote:

I see... There is a little difficulty in that 56794 involves a non-type
variadic parameter and in that case type_dependent_expression_p returns
false. If I use value_dependent_expression_p things work, but I'm not
sure it's 100% correct.


I don't think we need to consider whether the initializer is dependent 
here; if the array has no length and has an initializer, it must be 
that we couldn't determine its length in cp_complete_array_type 
because it is dependent.
Ah, fantastic. I really hoped we could say something like that but 
seemed too easy ;) I'm finishing testing the below then.

Eventually, we'll have to decide where we want to commit this: 56794 is
fixed in 4.7 and 4.8 too, but it's true that the issue with the specific
testcase attached by Jon isn't a regression.

I think apply it to 4.8 as well.

Agreed.

Paolo.


Index: cp/parser.c
===
--- cp/parser.c (revision 200169)
+++ cp/parser.c (working copy)
@@ -9750,10 +9750,7 @@ cp_parser_range_for (cp_parser *parser, tree scope
range_expr = error_mark_node;
   stmt = begin_range_for_stmt (scope, init);
   finish_range_for_decl (stmt, range_decl, range_expr);
-  if (range_expr != error_mark_node
-  !type_dependent_expression_p (range_expr)
- /* The length of an array might be dependent.  */
-  COMPLETE_TYPE_P (complete_type (TREE_TYPE (range_expr)))
+  if (!type_dependent_expression_p (range_expr)
  /* do_auto_deduction doesn't mess with template init-lists.  */
   !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
do_range_for_auto_deduction (range_decl, range_expr);
Index: cp/pt.c
===
--- cp/pt.c (revision 200169)
+++ cp/pt.c (working copy)
@@ -20079,6 +20079,29 @@ type_dependent_expression_p (tree expression)
VAR_HAD_UNKNOWN_BOUND (expression))
 return true;
 
+  /* An array of unknown bound depending on a variadic parameter, eg:
+
+ templatetypename... Args
+   void foo (Args... args)
+   {
+ int arr[] = { args... };
+   }
+
+ templateint... vals
+   void bar ()
+   {
+ int arr[] = { vals... };
+   }
+
+ If the array has no length and has an initializer, it must be that
+ we couldn't determine its length in cp_complete_array_type because
+ it is dependent.  */
+  if (VAR_P (expression)
+   TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE
+   !TYPE_DOMAIN (TREE_TYPE (expression))
+   DECL_INITIAL (expression))
+   return true;
+
   if (TREE_TYPE (expression) == unknown_type_node)
 {
   if (TREE_CODE (expression) == ADDR_EXPR)
Index: testsuite/g++.dg/cpp0x/decltype55.C
===
--- testsuite/g++.dg/cpp0x/decltype55.C (revision 0)
+++ testsuite/g++.dg/cpp0x/decltype55.C (working copy)
@@ -0,0 +1,20 @@
+// PR c++/53211
+// { dg-do compile { target c++11 } }
+
+templatetypename A, typename B
+  struct is_same { static const bool value = false; };
+
+templatetypename A
+  struct is_sameA, A { static const bool value = true; };
+
+templatetypename... Args
+void func(Args... args)
+{
+  int arr[] = { args... };
+  static_assert (is_samedecltype(arr), int[sizeof...(Args)]::value, );
+}
+
+int main()
+{
+  func(1, 2, 3, 4);
+}


Re: [C++ Patch / RFC] PR 53211

2013-06-18 Thread Jason Merrill

On 06/18/2013 10:46 AM, Paolo Carlini wrote:

Ah, fantastic. I really hoped we could say something like that but
seemed too easy ;) I'm finishing testing the below then.


OK.

Jason




Re: [C++ Patch / RFC] PR 53211

2013-06-17 Thread Jason Merrill

On 06/17/2013 04:08 PM, Paolo Carlini wrote:

+  if (TREE_CODE (TREE_TYPE (*tp)) == ARRAY_TYPE
+  !TYPE_DOMAIN (TREE_TYPE (*tp))
+  DECL_INITIAL (*tp)
+  type_dependent_expression_p (DECL_INITIAL (*tp)))
+   return *tp;


I think this approach makes sense, but it should go in 
type_dependent_expression_p rather than instantiation_dependent_r.


And please revert my fix for 56794, since this should fix one as well.

Jason



Re: [C++ Patch / RFC] PR 53211

2013-06-17 Thread Paolo Carlini

Hi,

On 06/17/2013 10:30 PM, Jason Merrill wrote:

On 06/17/2013 04:08 PM, Paolo Carlini wrote:

+  if (TREE_CODE (TREE_TYPE (*tp)) == ARRAY_TYPE
+   !TYPE_DOMAIN (TREE_TYPE (*tp))
+   DECL_INITIAL (*tp)
+   type_dependent_expression_p (DECL_INITIAL (*tp)))
+return *tp;


I think this approach makes sense, but it should go in 
type_dependent_expression_p rather than instantiation_dependent_r.


And please revert my fix for 56794, since this should fix one as well.
I see... There is a little difficulty in that 56794 involves a non-type 
variadic parameter and in that case type_dependent_expression_p returns 
false. If I use value_dependent_expression_p things work, but I'm not 
sure it's 100% correct.


I considered replacing it with uses_template_parms?!? Testing is fine 
with it too. It's also fine with both type_dependent_expression_p || 
value_dependent_expression_p.


Eventually, we'll have to decide where we want to commit this: 56794 is 
fixed in 4.7 and 4.8 too, but it's true that the issue with the specific 
testcase attached by Jon isn't a regression.


Thanks,
Paolo.


/cp
2013-06-18

PR c++/53211
* pt.c (type_dependent_expression_p): Handle an array of unknown
bound depending on a variadic parameter.
* parser.c (cp_parser_range_for): Revert PR56794 changes.

/testsuite
2013-06-18

PR c++/53211
* g++.dg/cpp0x/decltype55.C: New.

Index: cp/parser.c
===
--- cp/parser.c (revision 200151)
+++ cp/parser.c (working copy)
@@ -9750,10 +9750,7 @@ cp_parser_range_for (cp_parser *parser, tree scope
range_expr = error_mark_node;
   stmt = begin_range_for_stmt (scope, init);
   finish_range_for_decl (stmt, range_decl, range_expr);
-  if (range_expr != error_mark_node
-  !type_dependent_expression_p (range_expr)
- /* The length of an array might be dependent.  */
-  COMPLETE_TYPE_P (complete_type (TREE_TYPE (range_expr)))
+  if (!type_dependent_expression_p (range_expr)
  /* do_auto_deduction doesn't mess with template init-lists.  */
   !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
do_range_for_auto_deduction (range_decl, range_expr);
Index: cp/pt.c
===
--- cp/pt.c (revision 200151)
+++ cp/pt.c (working copy)
@@ -20079,6 +20079,26 @@ type_dependent_expression_p (tree expression)
VAR_HAD_UNKNOWN_BOUND (expression))
 return true;
 
+  /* An array of unknown bound depending on a variadic parameter, eg:
+
+ templatetypename... Args
+   void foo (Args... args)
+   {
+ int arr[] = { args... };
+   }
+
+ templateint... vals
+   void bar ()
+   {
+ int arr[] = { vals... };
+   }  */
+  if (VAR_P (expression)
+   TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE
+   !TYPE_DOMAIN (TREE_TYPE (expression))
+   DECL_INITIAL (expression)
+   value_dependent_expression_p (DECL_INITIAL (expression)))
+   return true;
+
   if (TREE_TYPE (expression) == unknown_type_node)
 {
   if (TREE_CODE (expression) == ADDR_EXPR)
Index: testsuite/g++.dg/cpp0x/decltype55.C
===
--- testsuite/g++.dg/cpp0x/decltype55.C (revision 0)
+++ testsuite/g++.dg/cpp0x/decltype55.C (working copy)
@@ -0,0 +1,20 @@
+// PR c++/53211
+// { dg-do compile { target c++11 } }
+
+templatetypename A, typename B
+  struct is_same { static const bool value = false; };
+
+templatetypename A
+  struct is_sameA, A { static const bool value = true; };
+
+templatetypename... Args
+void func(Args... args)
+{
+  int arr[] = { args... };
+  static_assert (is_samedecltype(arr), int[sizeof...(Args)]::value, );
+}
+
+int main()
+{
+  func(1, 2, 3, 4);
+}