diff mbox

[C++] Fix same canonical type node ICE for constrained functions (PR c++/68434)

Message ID CACqP_wyfEMuwk6CVgptQWBD4CTahq2GOrON3YVwjxecq7kJ+AA@mail.gmail.com
State New
Headers show

Commit Message

Ryan Burn Nov. 24, 2015, 12:30 p.m. UTC
This patch rearranges the step in tsubst where a type's
PLACEHOLDER_TYPE_CONSTRAINTS are set so that it happens before calling
the function canonical_type_parameter.

canonical_type_parameter makes comparisons between types stored in the
canonical_template_parms global variable. One of the steps in
comparing types (equivalent_placeholder_constraints) references the
PLACEHOLDER_TYPE_CONSTRAINTS on types. If constraints aren't set at
this point, types with different PLACEHOLDER_TYPE_CONSTRAINTS can
compare equal and receive the same TYPE_CANONICAL parameter.

Bootstrapped and regression tested on x86_64-linux

2015-11-19  Ryan Burn  <contact@rnburn.com>

      PR c++/68434
       * pt.c (tsubst): Set PLACEHOLDER_TYPE_CONSTRAINTS before
         calling canonical_type_parameter.

       * g++.dg/concepts/pr68434.C: New test
diff mbox

Patch

Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 230777)
+++ gcc/cp/pt.c	(working copy)
@@ -12977,6 +12977,12 @@ 
 		TYPE_POINTER_TO (r) = NULL_TREE;
 		TYPE_REFERENCE_TO (r) = NULL_TREE;
 
+		/* Propagate constraints on placeholders.  */
+                if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+                  if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (t))
+		    PLACEHOLDER_TYPE_CONSTRAINTS (r)
+		      = tsubst_constraint (constr, args, complain, in_decl);
+
 		if (TREE_CODE (r) == TEMPLATE_TEMPLATE_PARM)
 		  /* We have reduced the level of the template
 		     template parameter, but not the levels of its
@@ -12991,12 +12997,6 @@ 
 		else
 		  TYPE_CANONICAL (r) = canonical_type_parameter (r);
 
-		/* Propagate constraints on placeholders.  */
-                if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-                  if (tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (t))
-		    PLACEHOLDER_TYPE_CONSTRAINTS (r)
-		      = tsubst_constraint (constr, args, complain, in_decl);
-
 		if (code == BOUND_TEMPLATE_TEMPLATE_PARM)
 		  {
 		    tree argvec = tsubst (TYPE_TI_ARGS (t), args,
Index: gcc/testsuite/g++.dg/concepts/pr68434.C
===================================================================
--- gcc/testsuite/g++.dg/concepts/pr68434.C	(revision 0)
+++ gcc/testsuite/g++.dg/concepts/pr68434.C	(working copy)
@@ -0,0 +1,21 @@ 
+// { dg-options "-std=c++1z" }
+
+template <class>
+concept bool C1 () {
+  return true;
+}
+
+template <class>
+concept bool C2 () {
+  return true;
+}
+
+template <class Expr>
+concept bool C3 () {
+  return requires (Expr expr) {
+      {expr}->C1;
+      {expr}->C2;
+  };
+}
+
+auto f (C3);