aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2018-11-01 10:19:31 +0100
committerMartin Liska <marxin@gcc.gnu.org>2018-11-01 09:19:31 +0000
commitddd0d18c9c07025d578f445dc9a3544020861197 (patch)
treefc18f31e77d64af9f8639b83af8e225bb3023243 /gcc
parent964f78b7e75a4dd4c5c68cec0858270fbfc1d37b (diff)
downloadgcc-ddd0d18c9c07025d578f445dc9a3544020861197.zip
gcc-ddd0d18c9c07025d578f445dc9a3544020861197.tar.gz
gcc-ddd0d18c9c07025d578f445dc9a3544020861197.tar.bz2
Make __PRETTY_FUNCTION__-like functions mergeable string csts (PR c++/64266).
2018-11-01 Martin Liska <mliska@suse.cz> Jason Merrill <jason@redhat.com> PR c++/64266 PR bootstrap/70422 PR ipa/81277 * cp-tree.h (DECL_FNAME_P): New macro. * decl.c (cp_make_fname_decl): Set DECL_DECLARED_CONSTEXPR_P, DECL_VALUE_EXPR, DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P. (cp_finish_decl): * lambda.c (is_capture_proxy): Use DECL_FNAME_P. * pt.c (tsubst_expr): Handle DECL_PRETTY_FUNCTION_P. 2018-11-01 Martin Liska <mliska@suse.cz> Jason Merrill <jason@redhat.com> PR c++/64266 PR bootstrap/70422 PR ipa/81277 * g++.dg/cpp0x/constexpr-__func__2.C: Make it a compilation test. * g++.old-deja/g++.ext/pretty4.C: Remove as the run-time assumptions are not longer valid. Co-Authored-By: Jason Merrill <jason@redhat.com> From-SVN: r265711
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h8
-rw-r--r--gcc/cp/decl.c25
-rw-r--r--gcc/cp/lambda.c1
-rw-r--r--gcc/cp/pt.c16
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C7
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/pretty4.C85
8 files changed, 60 insertions, 106 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8e586a1..6d48345 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+2018-11-01 Martin Liska <mliska@suse.cz>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/64266
+ PR bootstrap/70422
+ PR ipa/81277
+ * cp-tree.h (DECL_FNAME_P): New macro.
+ * decl.c (cp_make_fname_decl): Set DECL_DECLARED_CONSTEXPR_P,
+ DECL_VALUE_EXPR, DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ (cp_finish_decl):
+ * lambda.c (is_capture_proxy): Use DECL_FNAME_P.
+ * pt.c (tsubst_expr): Handle DECL_PRETTY_FUNCTION_P.
+
2018-10-31 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (OVL_DEDUP_P): New.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 03e8883..42449f1 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3132,6 +3132,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 11320b6..1cea526 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);
@@ -4474,23 +4474,35 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
if (name)
free (CONST_CAST (char *, name));
- TREE_STATIC (decl) = 1;
+ /* As we're using pushdecl_with_scope, we must set the context. */
+ DECL_CONTEXT (decl) = current_function_decl;
+
TREE_READONLY (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
+ DECL_DECLARED_CONSTEXPR_P (decl) = 1;
+ TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
+ if (init)
+ {
+ SET_DECL_VALUE_EXPR (decl, init);
+ DECL_HAS_VALUE_EXPR_P (decl) = 1;
+ /* For decl_constant_var_p. */
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+ }
+
if (current_function_decl)
{
DECL_CONTEXT (decl) = current_function_decl;
decl = pushdecl_outermost_localscope (decl);
- cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
- LOOKUP_ONLYCONVERTING);
+ if (decl != error_mark_node)
+ add_decl_expr (decl);
}
else
{
DECL_THIS_STATIC (decl) = true;
- pushdecl_top_level_and_finish (decl, init);
+ pushdecl_top_level_and_finish (decl, NULL_TREE);
}
return decl;
@@ -7052,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 297327f..318671b 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 fc6cf9895..2dc0cb1 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16735,6 +16735,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
@@ -16793,17 +16797,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
complain, in_decl, &first,
&cnt);
- 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));
- }
- else
- init = tsubst_init (init, decl, args, complain, in_decl);
+ init = tsubst_init (init, decl, args, complain, in_decl);
if (VAR_P (decl))
const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 157b588..8a0e66d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2018-11-01 Martin Liska <mliska@suse.cz>
+ Jason Merrill <jason@redhat.com>
+
+ PR c++/64266
+ PR bootstrap/70422
+ PR ipa/81277
+ * g++.dg/cpp0x/constexpr-__func__2.C: Make it a compilation
+ test.
+ * g++.old-deja/g++.ext/pretty4.C: Remove as the run-time
+ assumptions are not longer valid.
+
2018-10-31 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/20520
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
index e678290..673fb4f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
@@ -1,5 +1,5 @@
// PR c++/70353
-// { dg-do link { target c++11 } }
+// { dg-do compile { target c++11 } }
constexpr const char* ce ()
{
@@ -8,6 +8,5 @@ constexpr const char* ce ()
const char *c = ce();
-int main()
-{
-}
+#define SA(X) static_assert((X),#X)
+SA(ce()[0] == 'c');
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/pretty4.C b/gcc/testsuite/g++.old-deja/g++.ext/pretty4.C
deleted file mode 100644
index 9017d56..0000000
--- a/gcc/testsuite/g++.old-deja/g++.ext/pretty4.C
+++ /dev/null
@@ -1,85 +0,0 @@
-// { dg-do run }
-// Copyright (C) 2000 Free Software Foundation, Inc.
-// Contributed by Nathan Sidwell 3 Mar 2000 <nathan@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 void const *strings[4];
-static void const *tpls[4];
-static unsigned pos = 0;
-static int fail;
-static void const *ptr = 0;
-
-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]) {}
-
-template<unsigned I> void PV (char const (&objRef)[I])
-{
- strings[pos] = objRef;
- tpls[pos] = __PRETTY_FUNCTION__;
- pos++;
-}
-
-void fn ()
-{
- PV (__FUNCTION__);
- PV (__func__);
- PV (__PRETTY_FUNCTION__);
- PV ("wibble");
-}
-
-void baz ()
-{
- ptr = __FUNCTION__;
- // there should be no string const merging
- if (ptr == "baz")
- fail = 1;
- // but all uses should be the same.
- if (ptr != __FUNCTION__)
- fail = 1;
-}
-int baz (int)
-{
- return ptr == __FUNCTION__;
-}
-
-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;
-
- // __FUNCTION__ should be unique across functions with the same base name
- // (it's a local static, _not_ a string).
- baz ();
- if (fail)
- return 1;
- if (baz (1))
- return 1;
- fn ();
-
- // Check the names of fn. They should all be distinct strings (though two
- // will have the same value).
- if (strings[0] == strings[1])
- return 1;
- if (strings[0] == strings[2])
- return 1;
- if (strings[1] == strings[2])
- return 1;
-
- // check the names of the template functions so invoked
- if (tpls[0] != tpls[1])
- return 1;
- if (tpls[0] == tpls[2])
- return 1;
-
- return 0;
-}