Hi,
in this error-recovery regression, after a sensible error message issued
by cxx_constant_init, store_init_value stores an error_mark_node as
DECL_INITIAL of the VAR_DECL for 'j'. This error_mark_node reappears
much later, to cause a crash during gimplification. As far as I know,
the choice of storing error_mark_nodes too is the outcome of a rather
delicate error-recovery strategy and I don't think we want to revisit it
at this time, thus the remaining option is catching later the
error_mark_node, at a "good" time. I note, in passing, that the do loop
in gimplify_expr which uses the crashing STRIP_USELESS_TYPE_CONVERSION
seems a bit lacking from the error-recovery point of view, because at
each iteration it *does* cover for error_operand_p (save_expr) but only
immediately after the call, when it's too late.
All the above said, I believe that at least for the 8.1.0 needs we may
want to catch the error_mark_node in cp_build_modify_expr, when we are
handling the assignment 'a.n = j;': convert_for_assignment produces a
NOP_EXPR from the VAR_DECL for 'j' which then cp_convert_and_check
regenerates (deep in convert_to_integer_1 via maybe_fold_build1_loc) in
the final bare-bone form, with the error_mark_node as the first operand.
Passes testing on x86_64-linux.
Thanks, Paolo.
/////////////////////////
/cp
2018-04-13 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/85112
* typeck.c (cp_build_modify_expr): Return error_mark_node upon
an error_mark_node wrapped in a NOP_EXPR too.
/testsuite
2018-04-13 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/85112
* g++.dg/cpp0x/pr85112.C: New.
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 259359)
+++ cp/typeck.c (working copy)
@@ -8234,7 +8234,9 @@ cp_build_modify_expr (location_t loc, tree lhs, en
TREE_OPERAND (newrhs, 0));
}
- if (newrhs == error_mark_node)
+ if (newrhs == error_mark_node
+ || (TREE_CODE (newrhs) == NOP_EXPR
+ && TREE_OPERAND (newrhs, 0) == error_mark_node))
return error_mark_node;
if (c_dialect_objc () && flag_objc_gc)
Index: testsuite/g++.dg/cpp0x/pr85112.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr85112.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/pr85112.C (working copy)
@@ -0,0 +1,17 @@
+// PR c++/85112
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ int m;
+ int n : 4;
+};
+
+int i; // { dg-message "not const" }
+
+void foo()
+{
+ constexpr int j = i; // { dg-error "not usable" }
+ A a;
+ a.n = j;
+}