[C++] PR 85065 ("[concepts] ICE with invalid use of a concept")

Message ID 1323550c-2bd5-8351-231e-c4093ab960a4@oracle.com
State New
Headers show
Series
  • [C++] PR 85065 ("[concepts] ICE with invalid use of a concept")
Related show

Commit Message

Paolo Carlini Sept. 3, 2018, 8:59 p.m.
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.carlini@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.carlini@oracle.com>

	PR c++/85065
	* g++.dg/concepts/pr85065.C: New.

Patch

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" }