[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #11 from Marek Polacek --- We never instantiated fnc because mark_used checks /* Check this too in case we're within instantiate_non_dependent_expr. */ if (DECL_TEMPLATE_INFO (decl) && uses_template_parms (DECL_TI_ARGS (decl))) return true; and here uses_template_parms says yes because value_dependent_expression_p says 'a' is value-dep. Note we can't use in_template_function in v_d_e_p.
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #10 from Marek Polacek --- So I have --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -27969,6 +27969,13 @@ value_dependent_expression_p (tree expression) else if (TYPE_REF_P (TREE_TYPE (expression))) /* FIXME cp_finish_decl doesn't fold reference initializers. */ return true; + /* We have a constexpr variable and we're processing a template. When +there's lifetime extension involved (for which finish_compound_literal +used to create a temporary), we'll not be able to evaluate the +variable until instantiating, so pretend it's value-dependent. */ + else if (DECL_DECLARED_CONSTEXPR_P (expression) + && !TREE_CONSTANT (expression)) + return true; return false; case DYNAMIC_CAST_EXPR: but that breaks struct foo { }; template void fnc() { } void test() { static constexpr foo a; fnc(); } with: $ ./cc1plus -quiet nontype-auto16.C nontype-auto16.C:6:31: warning: ‘void fnc() [with const foo& F = a]’ used but never defined 6 | template void fnc() { } | ^~~ nontype-auto16.C:13:1: internal compiler error: Segmentation fault 13 | } | ^ 0x19a5624 crash_signal /home/mpolacek/src/gcc/gcc/toplev.cc:314 0x7fe161facb1f ??? /usr/src/debug/glibc-2.36-9.fc37.x86_64/signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 0xcbfe74 tree_check(tree_node const*, char const*, int, char const*, tree_code) /home/mpolacek/src/gcc/gcc/tree.h:3795 0x12c2224 symbol_table::decl_assembler_name_hash(tree_node const*) /home/mpolacek/src/gcc/gcc/symtab.cc:84 The warning is obviously wrong and the cause for the ICE, I'd say. test isn't a function template but uses_template_parms / verify_unstripped_args set p_t_d, so we still reach the new code.
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #9 from Jason Merrill --- (In reply to Marek Polacek from comment #8) > > Instead, we should probably treat num as value-dependent even though it > > actually isn't. > > An attempt to implement that: > > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -27969,6 +27969,12 @@ value_dependent_expression_p (tree expression) >else if (TYPE_REF_P (TREE_TYPE (expression))) > /* FIXME cp_finish_decl doesn't fold reference initializers. */ > return true; > + else if (DECL_DECLARED_CONSTEXPR_P (expression) > + && TREE_STATIC (expression) I'd expect we could get a similar issue with non-static constexprs. > + && !DECL_NAMESPACE_SCOPE_P (expression) This seems an unnecessary optimization? > + && DECL_INITIAL (expression) Perhaps we also want to return true if DECL_INITIAL is null? > + && TREE_CODE (DECL_INITIAL (expression)) == IMPLICIT_CONV_EXPR) Maybe !TREE_CONSTANT?
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #8 from Marek Polacek --- > Instead, we should probably treat num as value-dependent even though it > actually isn't. An attempt to implement that: --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -27969,6 +27969,12 @@ value_dependent_expression_p (tree expression) else if (TYPE_REF_P (TREE_TYPE (expression))) /* FIXME cp_finish_decl doesn't fold reference initializers. */ return true; + else if (DECL_DECLARED_CONSTEXPR_P (expression) + && TREE_STATIC (expression) + && !DECL_NAMESPACE_SCOPE_P (expression) + && DECL_INITIAL (expression) + && TREE_CODE (DECL_INITIAL (expression)) == IMPLICIT_CONV_EXPR) + return true; return false; case DYNAMIC_CAST_EXPR:
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #7 from Marek Polacek --- // PR c++/109876 using size_t = decltype(sizeof 0); namespace std { template struct initializer_list { const int *_M_array; size_t _M_len; constexpr size_t size() const { return _M_len; } }; } // namespace std template struct Array {}; template void g() { static constexpr std::initializer_list num{2}; Array ctx; }
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 Jason Merrill changed: What|Removed |Added CC||jason at gcc dot gnu.org --- Comment #6 from Jason Merrill --- (In reply to Patrick Palka from comment #5) > Seems related to PR89144 too -- there we were mishandling defining a > non-dependent static std::initializer_list member variable, here we're > subsequently trying to use it. The issue there is that the initializer_list wasn't static, but here it is, so the array temporary should be as well. And presumably the problem is that we aren't representing that lifetime extension in a template. And checking the initializer gives up on trying to enforce that. But then when we try to evaluate the template argument we find that we don't have a constant value to work with, and complain. Instead, we should probably treat num as value-dependent even though it actually isn't. Or fix it to be properly evaluated by representing the lifetime extension somehow.
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 Patrick Palka changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=89144 CC||ppalka at gcc dot gnu.org --- Comment #5 from Patrick Palka --- Seems related to PR89144 too -- there we were mishandling defining a non-dependent static std::initializer_list member variable, here we're subsequently trying to use it.
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 Marek Polacek changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |mpolacek at gcc dot gnu.org Status|NEW |ASSIGNED
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #4 from Marek Polacek --- On trunk we no longer create a static temporary var for { 1, 2 }, because the code in finish_compound_literal is now guarded by '&& fcl_context == fcl_c99' but it's fcl_functional here.
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 --- Comment #3 from Andrew Pinski --- What fixed it on the GCC 8 branch?
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 Marek Polacek changed: What|Removed |Added Priority|P3 |P2
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 Andrew Pinski changed: What|Removed |Added Known to fail||9.1.0, 9.5.0 Last reconfirmed|2023-05-16 00:00:00 | Priority|P2 |P3 Known to work||8.5.0 --- Comment #2 from Andrew Pinski --- Confirmed.
[Bug c++/109876] [10/11/12/13/14 Regression] initializer_list not usable in constant expressions in a template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109876 Marek Polacek changed: What|Removed |Added Status|UNCONFIRMED |NEW Target Milestone|--- |10.5 Ever confirmed|0 |1 Last reconfirmed||2023-05-16 Priority|P3 |P2 Keywords||rejects-valid Summary|initializer_list not usable |[10/11/12/13/14 Regression] |in constant expressions in |initializer_list not usable |a template |in constant expressions in ||a template CC||mpolacek at gcc dot gnu.org --- Comment #1 from Marek Polacek --- Stopped working with r8-509-g6064858051d6e0 commit 6064858051d6e07bb89f3384c0d828f07c576c7a Author: Jason Merrill Date: Tue May 9 09:48:58 2017 -0400 PR c++/70167 - array prvalue treated as lvalue