PR c++/116416
gcc/cp/ChangeLog:
* constexpr.cc (maybe_constant_init_1): Generalize type of
of manifestly_const_eval parameter from bool to mce_value.
(maybe_constant_init): Define 3-parameter version taking a
manifestly_const_eval instead of bool parameter.
(cxx_constant_init): Adjust maybe_constant_init_1.
* cp-gimplify.cc (cp_fold_r) <case TARGET_EXPR>: Pass mce_false
to maybe_constant_init during prvalue folding if ff_mce_false is
set.
* cp-tree.h (maybe_constant_init): Declare new overload.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/constexpr-prvalue1.C: Adjust to instead inspect
the 'original' dump.
* g++.dg/cpp1y/constexpr-prvalue1a.C: New test.
---
gcc/cp/constexpr.cc | 16 +++++++---
gcc/cp/cp-gimplify.cc | 4 ++-
gcc/cp/cp-tree.h | 1 +
.../g++.dg/cpp1y/constexpr-prvalue1.C | 11 ++++---
.../g++.dg/cpp1y/constexpr-prvalue1a.C | 32 +++++++++++++++++++
5 files changed, 53 insertions(+), 11 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 497f64f3ceaa..0242425370f4 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9679,7 +9679,7 @@ fold_non_dependent_init (tree t,
static tree
maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
- bool manifestly_const_eval)
+ mce_value manifestly_const_eval)
{
if (!t)
return t;
@@ -9709,13 +9709,13 @@ maybe_constant_init_1 (tree t, tree decl, bool
allow_non_constant,
bool is_static = (decl && DECL_P (decl)
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
if (is_static)
- manifestly_const_eval = true;
+ manifestly_const_eval = mce_true;
- if (cp_unevaluated_operand && !manifestly_const_eval)
+ if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
return fold_to_constant (t);
t = cxx_eval_outermost_constant_expr (t, allow_non_constant, !is_static,
- mce_value (manifestly_const_eval),
+ manifestly_const_eval,
false, decl);
}
if (TREE_CODE (t) == TARGET_EXPR)
@@ -9731,6 +9731,12 @@ maybe_constant_init_1 (tree t, tree decl, bool
allow_non_constant,
tree
maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
+{
+ return maybe_constant_init_1 (t, decl, true, mce_value
(manifestly_const_eval));
+}
+
+tree
+maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval)
{
return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
}
@@ -9740,7 +9746,7 @@ maybe_constant_init (tree t, tree decl, bool
manifestly_const_eval)
tree
cxx_constant_init (tree t, tree decl)
{
- return maybe_constant_init_1 (t, decl, false, true);
+ return maybe_constant_init_1 (t, decl, false, mce_true);
}
#if 0
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 550cea29dd29..8dfa5ac2b88d 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1480,7 +1480,9 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
*walk_subtrees = 0;
if (!flag_no_inline)
{
- tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt));
+ tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt),
+ (data->flags & ff_mce_false
+ ? mce_false : mce_unknown));
if (folded != init && TREE_CONSTANT (folded))
init = folded;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 927f51b116b3..55f986e25c14 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8837,6 +8837,7 @@ extern void cxx_constant_dtor (tree,
tree);
extern tree cxx_constant_init (tree, tree = NULL_TREE);
extern tree maybe_constant_value (tree, tree = NULL_TREE,
mce_value = mce_unknown);
extern tree maybe_constant_init (tree, tree =
NULL_TREE, bool = false);
+extern tree maybe_constant_init (tree, tree, mce_value);
extern tree fold_non_dependent_expr (tree,
tsubst_flags_t =
tf_warning_or_error,
bool = false, tree =
NULL_TREE);
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C
b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C
index ad31e3001167..a17fed786fe8 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1.C
@@ -1,6 +1,6 @@
// PR c++/116416
// { dg-do compile { target c++14 } }
-// { dg-options "-O" }
+// { dg-options "-O -fdump-tree-original" }
struct Str {
constexpr Str() {}
@@ -17,14 +17,15 @@ extern void callback(Str str);
void
func1()
{
- callback(Str{"Test"});
+ callback(Str{"Test1"});
}
void
func2()
{
- Str str{"Test"};
+ Str str{"Test2"};
callback(str);
}
-// Check that we don't call Str::Str(char const*)
-// { dg-final { scan-assembler-not "_ZN3StrC1EPKc" } }
+// Check that the front end folds both constructor calls.
+// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test1\", .length=5}"
"original" } }
+// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test2\", .length=5}"
"original" } }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C
b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C
new file mode 100644
index 000000000000..3f6ef97f9bf4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-prvalue1a.C
@@ -0,0 +1,32 @@
+// PR c++/116416
+// A version of constexpr-prvalue1.C that calls
__builtin_is_constant_evaluated.
+// { dg-do compile { target c++14 } }
+// { dg-options "-O -fdump-tree-original" }
+
+struct Str {
+ constexpr Str() {}
+ constexpr Str(const char *instr) {
+ str = instr; length = 0;
+ for (auto index = 0; instr[index]; ++index) {
+ length += __builtin_is_constant_evaluated() ? 1 : 1;
+ }
+ }
+ const char *str = nullptr;
+ int length = 0;
+};
+extern void callback(Str str);
+void
+func1()
+{
+ callback(Str{"Test1"});
+}
+void
+func2()
+{
+ Str str{"Test2"};
+ callback(str);
+}
+
+// Check that the front end folds both constructor calls.
+// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test1\", .length=5}"
"original" } }
+// { dg-final { scan-tree-dump "{.str=\\(const char \\*\\) \"Test2\", .length=5}"
"original" } }