This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RFA: PATCH to tree-inline.c:remap_decls for c++/70353 (ICE with __func__ and constexpr)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>
- Date: Mon, 28 Mar 2016 17:26:30 -0400
- Subject: RFA: PATCH to tree-inline.c:remap_decls for c++/70353 (ICE with __func__ and constexpr)
- Authentication-results: sourceware.org; auth=none
The constexpr evaluation code uses the inlining code to remap the
constexpr function body for evaluation so that recursion works properly.
In this testcase __func__ is declared as a static local variable, so
rather than remap it, remap_decls tries to add it to the local_decls
list for the function we're inlining into. But there is no such
function in this case, so we crash.
Avoid the add_local_decl call when cfun is null avoids the ICE (thanks
Jakub), but results in an undefined symbol. Calling
varpool_node::finalize_decl instead allows cgraph to handle the
reference from 'c' properly.
OK if testing passes?
commit d875b432434be92ab345c3851fa3ba4bef738399
Author: Jason Merrill <jason@redhat.com>
Date: Mon Mar 28 17:14:43 2016 -0400
PR c++/70353
* tree-inline.c (remap_decls): Use varpool_node::finalize_decl if
cfun is null.
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
new file mode 100644
index 0000000..e678290
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
@@ -0,0 +1,13 @@
+// PR c++/70353
+// { dg-do link { target c++11 } }
+
+constexpr const char* ce ()
+{
+ return __func__;
+}
+
+const char *c = ce();
+
+int main()
+{
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 9d4f8f7..74b0ca9 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -614,10 +614,16 @@ remap_decls (tree decls, vec<tree, va_gc> **nonlocalized_list,
if (can_be_nonlocal (old_var, id))
{
/* We need to add this variable to the local decls as otherwise
- nothing else will do so. */
+ nothing else will do so. If we're not in a function,
+ tell cgraph about it. */
if (TREE_CODE (old_var) == VAR_DECL
&& ! DECL_EXTERNAL (old_var))
- add_local_decl (cfun, old_var);
+ {
+ if (cfun)
+ add_local_decl (cfun, old_var);
+ else
+ varpool_node::finalize_decl (old_var);
+ }
if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
&& !DECL_IGNORED_P (old_var)
&& nonlocalized_list)