[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-28 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #11 from GCC Commits  ---
The master branch has been updated by Jakub Jelinek :

https://gcc.gnu.org/g:29ac92436aa5c702e9e02c206e7590ebd806398e

commit r14-9227-g29ac92436aa5c702e9e02c206e7590ebd806398e
Author: Jakub Jelinek 
Date:   Wed Feb 28 23:20:13 2024 +0100

c++: Fix explicit instantiation of const variable templates after earlier
implicit instantation [PR113976]

Already previously instantiated const variable templates had
cp_apply_type_quals_to_decl called when they were instantiated,
but if they need runtime initialization, their TREE_READONLY flag
has been subsequently cleared.
Explicit variable template instantiation calls grokdeclarator which
calls cp_apply_type_quals_to_decl on them again, setting TREE_READONLY
flag again, but nothing clears it afterwards, so we emit such
instantiations into rodata sections and segfault when the dynamic
initialization attempts to initialize them.

The following patch fixes that by not calling cp_apply_type_quals_to_decl
on already instantiated variable declarations.

2024-02-28  Jakub Jelinek  
Patrick Palka  

PR c++/113976
* decl.cc (grokdeclarator): Don't call cp_apply_type_quals_to_decl
on DECL_TEMPLATE_INSTANTIATED VAR_DECLs.

* g++.dg/cpp1y/var-templ87.C: New test.

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-19 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #10 from Patrick Palka  ---
(In reply to Jakub Jelinek from comment #8)
> E.g.
> --- gcc/cp/decl.cc.jj 2024-02-15 09:51:34.460065992 +0100
> +++ gcc/cp/decl.cc2024-02-19 18:20:23.423410659 +0100
> @@ -15263,7 +15263,14 @@ grokdeclarator (const cp_declarator *dec
>  /* Record constancy and volatility on the DECL itself .  There's
> no need to do this when processing a template; we'll do this
> for the instantiated declaration based on the type of DECL.  */
> -if (!processing_template_decl)
> +if (!processing_template_decl
> + /* Don't do it for instantiated variable templates either,
> +cp_apply_type_quals_to_decl should have been called on it
> +already and might have have been overridden in cp_finish_decl
> +if initializer needs runtime initialization.  */
> + && (!VAR_P (decl)
> + || DECL_LANG_SPECIFIC (decl) == NULL
> + || !DECL_USE_TEMPLATE (decl)))

Maybe checking !DECL_TEMPLATE_INSTANTIATED would be better, since that's set
only when the specialization's definition is instantiated from instantiate_body
as opposed to DECL_USE_TEMPLATE which gets set when the specialization is
formed?

>cp_apply_type_quals_to_decl (type_quals, decl);
>  
>  return decl;
> fixes it, but it is just a random shot in the dark.  I think we want to
> differentiate
> between freshly created VAR_DECL from the grokdeclarator vs. existing
> VAR_DECL grokdeclarator just looked up.

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-19 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #9 from Jakub Jelinek  ---
Note, adjusted testcase:
struct S { int a, b; };
int foo () { return 42; }
template 
const S a = { 42, foo () };
const S *b = &a <0>;
template 
const S c =  { 42, foo () };
template const S c <0>;
template 
const S d =  { 42, foo () };
const S *e = &d <0>;
template const S d <0>;
template 
const S f =  { 42, foo () };
template const S f <0>;
const S *g = &f <0>;
int main () {}
started crashing with r6-1525-g350562a75dfb4ac658adf620665871eb47166652
(before that commit it failed to link).
When there is partly constant and partly dynamic initializer, we were never
considering putting it into .bss section.

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-19 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #8 from Jakub Jelinek  ---
E.g.
--- gcc/cp/decl.cc.jj   2024-02-15 09:51:34.460065992 +0100
+++ gcc/cp/decl.cc  2024-02-19 18:20:23.423410659 +0100
@@ -15263,7 +15263,14 @@ grokdeclarator (const cp_declarator *dec
 /* Record constancy and volatility on the DECL itself .  There's
no need to do this when processing a template; we'll do this
for the instantiated declaration based on the type of DECL.  */
-if (!processing_template_decl)
+if (!processing_template_decl
+   /* Don't do it for instantiated variable templates either,
+  cp_apply_type_quals_to_decl should have been called on it
+  already and might have have been overridden in cp_finish_decl
+  if initializer needs runtime initialization.  */
+   && (!VAR_P (decl)
+   || DECL_LANG_SPECIFIC (decl) == NULL
+   || !DECL_USE_TEMPLATE (decl)))
   cp_apply_type_quals_to_decl (type_quals, decl);

 return decl;
fixes it, but it is just a random shot in the dark.  I think we want to
differentiate
between freshly created VAR_DECL from the grokdeclarator vs. existing VAR_DECL
grokdeclarator just looked up.

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-19 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

Jakub Jelinek  changed:

   What|Removed |Added

   Keywords|needs-bisection |
 CC||jason at gcc dot gnu.org,
   ||mpolacek at gcc dot gnu.org,
   ||ppalka at gcc dot gnu.org

--- Comment #7 from Jakub Jelinek  ---
So, what happens is that during the implicit instantiation we first set
TREE_READONLY
on the just created decl:
#0  c_apply_type_quals_to_decl (type_quals=1, decl=)
at ../../gcc/c-family/c-common.cc:3851
#1  0x0089a73a in cp_apply_type_quals_to_decl (type_quals=1,
decl=) at ../../gcc/cp/typeck.cc:11747
#2  0x0078d061 in tsubst_decl (t=,
args=, complain=3, use_spec_table=false) at
../../gcc/cp/pt.cc:15609
#3  0x007b0faf in instantiate_template (tmpl=, orig_args=, complain=3) at
../../gcc/cp/pt.cc:22100
#4  0x0076dc12 in finish_template_variable (var=, complain=3) at ../../gcc/cp/pt.cc:10521
then clear it because it has a non-const initializer:
#0  cp_finish_decl (decl=, init=, init_const_expr_p=false, asmspec_tree=, flags=4,
decomp=0x0)
at ../../gcc/cp/decl.cc:8945
#1  0x007c64f5 in instantiate_body (pattern=, args=, d=, nested_p=false)
at ../../gcc/cp/pt.cc:27006
#2  0x007c838f in instantiate_decl (d=,
defer_ok=false, expl_inst_class_mem_p=false) at ../../gcc/cp/pt.cc:27323
#3  0x005a1145 in mark_used (decl=,
complain=3) at ../../gcc/cp/decl2.cc:6008
but then mark it TREE_READONLY again in
#0  c_apply_type_quals_to_decl (type_quals=1, decl=)
at ../../gcc/c-family/c-common.cc:3851
#1  0x0089a73a in cp_apply_type_quals_to_decl (type_quals=1,
decl=) at ../../gcc/cp/typeck.cc:11747
#2  0x00566b7c in grokdeclarator (declarator=0x3ebfa00,
declspecs=0x7fffd9e0, decl_context=NORMAL, initialized=0,
attrlist=0x7fffda50) at ../../gcc/cp/decl.cc:15267
#3  0x006dc206 in cp_parser_explicit_instantiation
(parser=0x7fffea2dea80) at ../../gcc/cp/parser.cc:19864

Perhaps that
/* Record constancy and volatility on the DECL itself .  There's
   no need to do this when processing a template; we'll do this
   for the instantiated declaration based on the type of DECL.  */
if (!processing_template_decl)
  cp_apply_type_quals_to_decl (type_quals, decl);
at the end of grokdeclarator needs some further guarding, not do it if it has
been already implicitly instantiated or something similar.
Because I'm afraid by that point I'm afraid information that the var needs to
be runtime initialized isn't present on the VAR_DECL anymore (except in cleared
TREE_READONLY).

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-19 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #6 from Jakub Jelinek  ---
Testcase showing that it is just this case of implicit instantiation followed
by explicit that is problematic:
int foo () { return 42; }
template 
const int a = foo ();
const int *b = &a <0>;
template 
const int c = foo ();
template const int c <0>;
template 
const int d = foo ();
const int *e = &d <0>;
template const int d <0>;
template 
const int f = foo ();
template const int f <0>;
const int *g = &f <0>;
int main () {}

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-19 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P2

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-18 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek  ---
That sounds like a FE bug to me, rather than middle-end.

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-18 Thread pinskia at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #4 from Andrew Pinski  ---
(In reply to Jeffrey A. Law from comment #3)
> What does the standard say about changing const objects?

It says it is undefined. Note there is no changing const object in this code;
just the const variable is dynamically initialized which is 100% defined.

[Bug c++/113976] [11/12/13/14 Regression] explicit instantiation of const variable template following implicit instantiation is assembled in .rodata instead of .bss since r8-2857-g2ec399d8a6c9c2

2024-02-18 Thread law at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113976

--- Comment #3 from Jeffrey A. Law  ---
What does the standard say about changing const objects?