aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-08-15 18:47:29 -0400
committerMarek Polacek <polacek@redhat.com>2024-08-19 13:29:30 -0400
commit53283c3231a7b94e728619cccbf21170fb36b2a8 (patch)
tree9f00304d88d43edf2d57b55558e2711008272f51 /gcc/cp
parent8191f15022b0ea44fcb549449b0458d07ae02e0a (diff)
downloadgcc-53283c3231a7b94e728619cccbf21170fb36b2a8.zip
gcc-53283c3231a7b94e728619cccbf21170fb36b2a8.tar.gz
gcc-53283c3231a7b94e728619cccbf21170fb36b2a8.tar.bz2
c++: ICE with enum and conversion fn in template [PR115657]
Here we initialize an enumerator with a class prvalue with a conversion function. When we fold it in build_enumerator, we create a TARGET_EXPR for the object, and subsequently crash in tsubst_expr, which should not see such a code. Normally, we fix similar problems by using an IMPLICIT_CONV_EXPR but here I may get away with not using the result of fold_non_dependent_expr unless the result is a constant. A TARGET_EXPR is not constant. PR c++/115657 gcc/cp/ChangeLog: * decl.cc (build_enumerator): Call maybe_fold_non_dependent_expr instead of fold_non_dependent_expr. gcc/testsuite/ChangeLog: * g++.dg/cpp1y/constexpr-recursion2.C: New test. * g++.dg/template/conv21.C: New test.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/decl.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index f23b635..12139e1 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17387,9 +17387,15 @@ build_enumerator (tree name, tree value, tree enumtype, tree attributes,
tree type;
/* scalar_constant_value will pull out this expression, so make sure
- it's folded as appropriate. */
+ it's folded as appropriate.
+
+ Creating a TARGET_EXPR in a template breaks when substituting, and
+ here we would create it for instance when using a class prvalue with
+ a user-defined conversion function. So don't use such a tree. We
+ instantiate VALUE here to get errors about bad enumerators even in
+ a template that does not get instantiated. */
if (processing_template_decl)
- value = fold_non_dependent_expr (value);
+ value = maybe_fold_non_dependent_expr (value);
/* If the VALUE was erroneous, pretend it wasn't there; that will
result in the enum being assigned the next value in sequence. */