This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to fix ICE in generic lambda with user-defined conversion (PR c++/84125)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Tue, 30 Jan 2018 21:18:01 +0100
- Subject: C++ PATCH to fix ICE in generic lambda with user-defined conversion (PR c++/84125)
- Authentication-results: sourceware.org; auth=none
This testcase breaks since r256550 because we end up trying to build_address of
a CONSTRUCTOR, but that doesn't work because we hit
gcc_checking_assert (TREE_CODE (t) != CONSTRUCTOR);
finish_static_assert gets {} as 'condition'. In the testcase we have a
user-defined conversion, so {} should be turned to false, via
perform_implicit_conversion_flags -> ... -> build_user_type_conversion_1, but
that crashes as explained above.
This only happens while processing generic lambda because processing_template_decl is 1,
so finish_compound_literal returns {} instead of a TARGET_EXPR.
Part of r256550 was this change:
@@ -8640,9 +8642,9 @@ finish_static_assert (tree condition, tree message, location_t location,
}
/* Fold the expression and convert it to a boolean value. */
- condition = instantiate_non_dependent_expr (condition);
- condition = cp_convert (boolean_type_node, condition, tf_warning_or_error);
- condition = maybe_constant_value (condition);
+ condition = perform_implicit_conversion_flags (boolean_type_node, condition,
+ complain, LOOKUP_NORMAL);
+ condition = fold_non_dependent_expr (condition);
if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
/* Do nothing; the condition is satisfied. */
where instantiate_non_dependent_expr turned {} into TARGET_EXPR <D.2369, {}>,
which we can process just fine. So perhaps we need to put the call back.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2018-01-30 Marek Polacek <polacek@redhat.com>
PR c++/84125
* semantics.c (finish_static_assert): Call
instantiate_non_dependent_expr.
* g++.dg/cpp1y/lambda-generic-84125.C: New test.
diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index b758051965e..38829e327c7 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -8642,6 +8642,7 @@ finish_static_assert (tree condition, tree message, location_t location,
}
/* Fold the expression and convert it to a boolean value. */
+ condition = instantiate_non_dependent_expr (condition);
condition = perform_implicit_conversion_flags (boolean_type_node, condition,
complain, LOOKUP_NORMAL);
condition = fold_non_dependent_expr (condition);
diff --git gcc/testsuite/g++.dg/cpp1y/lambda-generic-84125.C gcc/testsuite/g++.dg/cpp1y/lambda-generic-84125.C
index e69de29bb2d..8bf6a09652e 100644
--- gcc/testsuite/g++.dg/cpp1y/lambda-generic-84125.C
+++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-84125.C
@@ -0,0 +1,10 @@
+// PR c++/84125
+// { dg-do compile { target c++14 } }
+
+struct X { constexpr operator bool() const { return true; } };
+
+int main(){
+ [](auto) {
+ static_assert(X{}, "");
+ };
+}
Marek