Hi,

in this error-recovery ICE, upon the error make_constrained_auto assigns error_mark_node to PLACEHOLDER_TYPE_CONSTRAINTS (type) which then causes a crash later when hash_placeholder_constraint is called on it. I think we should cope with this somehow, I believe that consistency with the way we use error_mark_node in this part of the front-end prevents us from avoiding to assign the error_mark_node in the first place and, for the reasons explained in my previous patch, we want to unconditionally call make_constrained_auto. This said, catching in practice the error_mark_node would normally mean renouncing to the pattern 'if (tree c = ...)' which we lately appear to like a lot and seems indeed neat. Thus I'm wondering if we want instead to add a macro like ERROR_AS_NULL, which of course would be also useful in many other places - essentially in all the circumstances where we want to check for a kosher node, thus neither null nor error_mark_node. What do you think? What about the name, in case? Tested x86_64-linux.

Thanks, Paolo.

/////////////////

/cp
2018-09-03  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/85065
        * cp-tree.h (ERROR_AS_NULL): New.
        * pt.c (auto_hash::hash): Use it.
        (do_auto_deduction): Likewise.

/testsuite
2018-09-03  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/85065
        * g++.dg/concepts/pr85065.C: New.
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h        (revision 264063)
+++ cp/cp-tree.h        (working copy)
@@ -1877,6 +1877,8 @@ struct GTY(()) language_function {
 /* In parser.c.  */
 extern tree cp_literal_operator_id (const char *);
 
+#define ERROR_AS_NULL(NODE) ((NODE) == error_mark_node ? NULL_TREE : (NODE))
+
 /* TRUE if a tree code represents a statement.  */
 extern bool statement_code_p[MAX_TREE_CODES];
 
Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 264069)
+++ cp/pt.c     (working copy)
@@ -26120,7 +26120,7 @@ struct auto_hash : default_hash_traits<tree>
 inline hashval_t
 auto_hash::hash (tree t)
 {
-  if (tree c = PLACEHOLDER_TYPE_CONSTRAINTS (t))
+  if (tree c = ERROR_AS_NULL (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
     /* Matching constrained-type-specifiers denote the same template
        parameter, so hash the constraint.  */
     return hash_placeholder_constraint (c);
@@ -26879,7 +26879,7 @@ do_auto_deduction (tree type, tree init, tree auto
 
   /* Check any placeholder constraints against the deduced type. */
   if (flag_concepts && !processing_template_decl)
-    if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (auto_node))
+    if (tree constr = ERROR_AS_NULL (PLACEHOLDER_TYPE_CONSTRAINTS (auto_node)))
       {
         /* Use the deduced type to check the associated constraints. If we
            have a partial-concept-id, rebuild the argument list so that
Index: testsuite/g++.dg/concepts/pr85065.C
===================================================================
--- testsuite/g++.dg/concepts/pr85065.C (nonexistent)
+++ testsuite/g++.dg/concepts/pr85065.C (working copy)
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-fconcepts" }
+
+template<int> concept bool C = true;
+
+C c = 0;  // { dg-error "invalid reference to concept" }

Reply via email to