summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-25 21:29:26 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-25 21:29:26 +0000
commita478a028f1e445c05b162236d708de6935d4b5e2 (patch)
tree539f2664a65fff87648c21b1f5ed7a833fe023c8
parentb0bf58c4cc30f551c21b51facb916ff8fa8ec746 (diff)
downloadgcc-a478a028f1e445c05b162236d708de6935d4b5e2.tar.gz
PR c++/64266
PR c++/70353 Core issue 1962 * decl.c (cp_fname_init): Decay the initializer to pointer. (cp_make_fname_decl): Set DECL_DECLARED_CONSTEXPR_P, DECL_VALUE_EXPR, DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P. Don't call cp_finish_decl. * pt.c (tsubst_expr) [DECL_EXPR]: Set DECL_VALUE_EXPR, DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P. Don't call cp_finish_decl. * constexpr.c (cxx_eval_constant_expression) [VAR_DECL]: Handle DECL_VALUE_EXPR. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234484 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/constexpr.c4
-rw-r--r--gcc/cp/decl.c19
-rw-r--r--gcc/cp/pt.c26
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C10
-rw-r--r--gcc/testsuite/g++.dg/ext/fnname5.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/pretty4.C85
7 files changed, 91 insertions, 101 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 45450ec2f06..5cb8eaa252c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2016-03-25 Jason Merrill <jason@redhat.com>
+ Martin Liška <mliska@suse.cz>
+
+ PR c++/64266
+ PR c++/70353
+ Core issue 1962
+ * decl.c (cp_fname_init): Decay the initializer to pointer.
+ (cp_make_fname_decl): Set DECL_DECLARED_CONSTEXPR_P,
+ DECL_VALUE_EXPR, DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ Don't call cp_finish_decl.
+ * pt.c (tsubst_expr) [DECL_EXPR]: Set DECL_VALUE_EXPR,
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P. Don't call cp_finish_decl.
+ * constexpr.c (cxx_eval_constant_expression) [VAR_DECL]:
+ Handle DECL_VALUE_EXPR.
+
2016-03-24 Jason Merrill <jason@redhat.com>
PR c++/70386
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 8ea71113d99..7776caca4d3 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -3363,6 +3363,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
return (*ctx->values->get (t));
case VAR_DECL:
+ if (DECL_HAS_VALUE_EXPR_P (t))
+ return cxx_eval_constant_expression (ctx, DECL_VALUE_EXPR (t), lval,
+ non_constant_p, overflow_p);
+ /* Fall through. */
case CONST_DECL:
/* We used to not check lval for CONST_DECL, but darwin.c uses
CONST_DECL for aggregate constants. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cd5db3f06dc..a88b642f8dd 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4185,13 +4185,15 @@ cp_fname_init (const char* name, tree *type_p)
type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST);
type = build_cplus_array_type (type, domain);
- *type_p = type;
+ *type_p = type_decays_to (type);
if (init)
TREE_TYPE (init) = type;
else
init = error_mark_node;
+ init = decay_conversion (init, tf_warning_or_error);
+
return init;
}
@@ -4217,12 +4219,20 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
/* As we're using pushdecl_with_scope, we must set the context. */
DECL_CONTEXT (decl) = current_function_decl;
- TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
+ DECL_DECLARED_CONSTEXPR_P (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)
{
cp_binding_level *b = current_binding_level;
@@ -4231,13 +4241,12 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
while (b->level_chain->kind != sk_function_parms)
b = b->level_chain;
pushdecl_with_scope (decl, b, /*is_friend=*/false);
- cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
- LOOKUP_ONLYCONVERTING);
+ 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;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a6398c04f85..e0b7a2a90aa 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15194,21 +15194,25 @@ 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;
maybe_push_decl (decl);
- 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/g++.dg/cpp0x/constexpr-__func__2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
new file mode 100644
index 00000000000..226ae199daa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-__func__2.C
@@ -0,0 +1,10 @@
+// PR c++/70353
+// { dg-do compile { target c++11 } }
+
+constexpr const char* ce ()
+{
+ return __func__;
+}
+
+#define SA(X) static_assert((X),#X)
+SA(ce()[0] == 'c');
diff --git a/gcc/testsuite/g++.dg/ext/fnname5.C b/gcc/testsuite/g++.dg/ext/fnname5.C
new file mode 100644
index 00000000000..a2ead1dd7fd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/fnname5.C
@@ -0,0 +1,33 @@
+// PR c++/64266
+/* { dg-do compile } */
+
+extern "C" int printf (const char *, ...);
+
+struct A
+{
+ void foo(int i)
+ {
+ printf ("__FUNCTION__ = %s\n", __FUNCTION__);
+ printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);
+ }
+
+ void foo()
+ {
+ printf ("__FUNCTION__ = %s\n", __FUNCTION__);
+ }
+};
+
+int
+main ()
+{
+ A a;
+ a.foo (0);
+ a.foo ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "_ZZN1A3fooEvE12__FUNCTION__" } } */
+/* { dg-final { scan-assembler-not "_ZZN1A3fooEiE12__FUNCTION__" } } */
+/* { dg-final { scan-assembler-not "_ZZN1A3fooEiE19__PRETTY_FUNCTION__" } } */
+/* { dg-final { scan-assembler ".string \"void A::foo\\(int\\)\"" } } */
+/* { dg-final { scan-assembler ".string \"foo\"" } } */
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 9017d567132..00000000000
--- 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;
-}