On 10/29/18 9:37 AM, Jason Merrill wrote:
On Fri, Oct 26, 2018 at 3:14 AM Martin Liška <mli...@suse.cz> wrote:
On 10/24/18 7:24 PM, Jason Merrill wrote:
On Tue, Oct 23, 2018 at 4:59 AM Martin Liška <mli...@suse.cz> wrote:
However, I still see some minor ICEs, it's probably related to decay_conversion 
in cp_fname_init:

1) ./xg++ -B. 
/home/marxin/Programming/gcc/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__2.C

/home/marxin/Programming/gcc/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__2.C:6:17:
 internal compiler error: Segmentation fault
6 |     [] { return __func__; }();
   |                 ^~~~~~~~
0x1344568 crash_signal
         /home/marxin/Programming/gcc/gcc/toplev.c:325
0x7ffff6bc310f ???
         
/usr/src/debug/glibc-2.27-6.1.x86_64/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
0x9db134 is_capture_proxy(tree_node*)

Hi.


The problem in both tests is that is_capture_proxy thinks your
__func__ VAR_DECL with DECL_VALUE_EXPR is a capture proxy, since it is
neither an anonymous union proxy nor a structured binding.

I see, however I'm a rookie in area of C++ FE. Would it be solvable this problem
with lambdas?


The standard says,

The function-local predefined variable __func__ is defined as if a
definition of the form
    static const char __func__[] = "function-name ";
had been provided, where function-name is an implementation-defined
string. It is unspecified whether such a variable has an address
distinct from that of any other object in the program.

So changing the type of __func__ (from array to pointer) still breaks
conformance.  And we need to keep the type checks from pretty4.C, even
though the checks for strings being distinct need to go.

I added following patch which puts back type to const char[] (instead of char *)
and I made the variable static. Now I see pretty4.C testcase passing again.
To be honest I'm not convinced about the FE changes, so a help would
be appreciated.

OK, I'll poke at it.

This further patch teaches is_capture_proxy about function-name variables, and changes the handling of __PRETTY_FUNCTION__ in template instantiations to create new variables rather than instantiations.

The C++ changes are OK with this.

commit 100f6f38f9d8bbb5d77ba7a4ccb86a4c85aa2cd9
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Oct 29 22:35:59 2018 -0400

    fname-p

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8454cb4e178..f1a10297e79 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3122,6 +3122,14 @@ struct GTY(()) lang_decl {
   (DECL_NAME (NODE) \
    && id_equal (DECL_NAME (NODE), "__PRETTY_FUNCTION__"))
 
+/* For a DECL, true if it is __func__ or similar.  */
+#define DECL_FNAME_P(NODE)					\
+  (VAR_P (NODE) && DECL_NAME (NODE) && DECL_ARTIFICIAL (NODE)	\
+   && DECL_HAS_VALUE_EXPR_P (NODE)				\
+   && (id_equal (DECL_NAME (NODE), "__PRETTY_FUNCTION__")	\
+       || id_equal (DECL_NAME (NODE), "__FUNCTION__")		\
+       || id_equal (DECL_NAME (NODE), "__func__")))
+
 /* Nonzero if the variable was declared to be thread-local.
    We need a special C++ version of this test because the middle-end
    DECL_THREAD_LOCAL_P uses the symtab, so we can't use it for
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cce9cc99ff1..bde8023ce3b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4465,7 +4465,7 @@ cp_fname_init (const char* name, tree *type_p)
 static tree
 cp_make_fname_decl (location_t loc, tree id, int type_dep)
 {
-  const char *const name = (type_dep && processing_template_decl
+  const char *const name = (type_dep && in_template_function ()
 			    ? NULL : fname_as_string (type_dep));
   tree type;
   tree init = cp_fname_init (name, &type);
@@ -7064,8 +7064,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
 	    init = NULL_TREE;
 	  release_tree_vector (cleanups);
 	}
-      else if (!DECL_PRETTY_FUNCTION_P (decl))
+      else
 	{
+	  gcc_assert (!DECL_PRETTY_FUNCTION_P (decl));
 	  /* Deduce array size even if the initializer is dependent.  */
 	  maybe_deduce_size_from_array_init (decl, init);
 	  /* And complain about multiple initializers.  */
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 297327f1ab6..318671bbcd0 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -262,6 +262,7 @@ is_capture_proxy (tree decl)
 	  && DECL_HAS_VALUE_EXPR_P (decl)
 	  && !DECL_ANON_UNION_VAR_P (decl)
 	  && !DECL_DECOMPOSITION_P (decl)
+	  && !DECL_FNAME_P (decl)
 	  && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
 }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6975027076e..510264d38a0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16702,6 +16702,10 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 	    register_local_specialization (inst, decl);
 	    break;
 	  }
+	else if (DECL_PRETTY_FUNCTION_P (decl))
+	  decl = make_fname_decl (DECL_SOURCE_LOCATION (decl),
+				  DECL_NAME (decl),
+				  true/*DECL_PRETTY_FUNCTION_P (decl)*/);
 	else if (DECL_IMPLICIT_TYPEDEF_P (decl)
 		 && LAMBDA_TYPE_P (TREE_TYPE (decl)))
 	  /* Don't copy the old closure; we'll create a new one in
@@ -16746,19 +16750,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 		    DECL_CONTEXT (decl) = current_function_decl;
 		    cp_check_omp_declare_reduction (decl);
 		  }
-		else if (VAR_P (decl)
-			 && DECL_PRETTY_FUNCTION_P (decl))
-		  {
-		    /* For __PRETTY_FUNCTION__ we have to adjust the
-		       initializer.  */
-		    const char *const name
-		      = cxx_printable_name (current_function_decl, 2);
-		    init = cp_fname_init (name, &TREE_TYPE (decl));
-		    SET_DECL_VALUE_EXPR (decl, init);
-		    DECL_HAS_VALUE_EXPR_P (decl) = 1;
-		    DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
-		    maybe_push_decl (decl);
-		  }
 		else
 		  {
 		    int const_init = false;
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/pretty4.C b/gcc/testsuite/g++.old-deja/g++.ext/pretty4.C
new file mode 100644
index 00000000000..eb5d0de5cc6
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.ext/pretty4.C
@@ -0,0 +1,39 @@
+// { dg-do run  }
+// Copyright (C) 2000 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 3 Mar 2000 <nat...@codesourcery.com>
+
+// __PRETTY_FUNCTION__, __FUNCTION__ and __function__ should have the
+// type char const [X], where X is the right value for that particular function
+
+static int fail;
+
+void unover (char const (*)[5]) {}
+void foo (char const (*)[5]) {}
+void foo (void *) {fail = 1;}
+void foo (void const *) {fail = 1;}
+void baz (char const (&)[5]) {}
+
+void baz ()
+{
+  static void const *ptr = __FUNCTION__;
+  // all uses should be the same.
+  if (ptr != __FUNCTION__)
+    fail = 1;
+}
+
+int main ()
+{
+  // make sure we actually emit the VAR_DECL when needed, and things have the
+  // expected type.
+  foo (&__FUNCTION__);
+  baz (__FUNCTION__);
+  unover (&__FUNCTION__);
+  if (fail)
+    return 1;
+  
+  baz ();
+  if (fail)
+    return 1;
+  
+  return 0;
+}

Reply via email to