Re: [C++ Patch / RFC] PR 53211
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
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: + + template + void foo (Args... args) + { + int arr[] = { args... }; + } + + template + 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 } } + +template + struct is_same { static const bool value = false; }; + +template + struct is_same { static const bool value = true; }; + +template +void func(Args... args) +{ + int arr[] = { args... }; + static_assert (is_same::value, ""); +} + +int main() +{ + func(1, 2, 3, 4); +}
Re: [C++ Patch / RFC] PR 53211
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
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: + + template + void foo (Args... args) + { + int arr[] = { args... }; + } + + template + 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 } } + +template + struct is_same { static const bool value = false; }; + +template + struct is_same { static const bool value = true; }; + +template +void func(Args... args) +{ + int arr[] = { args... }; + static_assert (is_same::value, ""); +} + +int main() +{ + func(1, 2, 3, 4); +}
Re: [C++ Patch / RFC] PR 53211
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