diff mbox

Fix PR c++/68290

Message ID 2539259.e9D4ZPEAx6@polaris
State New
Headers show

Commit Message

Eric Botcazou Nov. 26, 2015, 11:19 p.m. UTC
Hi,

this is a variant of the just fixed PR c++/68434 on SPARC64/Solaris:

/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/concepts/auto1.C:16:6: 
internal compiler error: canonical types differ for identical types C and C

with the same underlying issue, which is that TYPE_CANONICAL is computed 
before PLACEHOLDER_TYPE_CONSTRAINTS is set in make_constrained_auto.

Tested on x86_64-suse-linux, OK for the mainline?


2015-11-26  Eric Botcazou  <ebotcazou@adacore.com>

	PR c++/68290
	* constraint.cc (make_constrained_auto): Move to...
	* pt.c (make_auto_1): Add set_canonical parameter and set
	TYPE_CANONICAL on the type only if it is true.
	(make_decltype_auto): Adjust call to make_auto_1.
	(make_auto): Likewise.
	(splice_late_return_type): Likewise.
	(make_constrained_auto): ...here.  Call make_auto_1 instead of
	make_auto and pass false.  Set TYPE_CANONICAL directly.
diff mbox

Patch

Index: constraint.cc
===================================================================
--- constraint.cc	(revision 230924)
+++ constraint.cc	(working copy)
@@ -1353,32 +1353,6 @@  finish_template_introduction (tree tmpl_
 }
 
 
-/* Make a "constrained auto" type-specifier. This is an
-   auto type with constraints that must be associated after
-   deduction.  The constraint is formed from the given
-   CONC and its optional sequence of arguments, which are
-   non-null if written as partial-concept-id.  */
-tree
-make_constrained_auto (tree con, tree args)
-{
-  tree type = make_auto();
-
-  /* Build the constraint. */
-  tree tmpl = DECL_TI_TEMPLATE (con);
-  tree expr;
-  if (VAR_P (con))
-    expr = build_concept_check (tmpl, type, args);
-  else
-    expr = build_concept_check (build_overload (tmpl, NULL_TREE), type, args);
-
-  tree constr = make_predicate_constraint (expr);
-  PLACEHOLDER_TYPE_CONSTRAINTS (type) = constr;
-
-  /* Attach the constraint to the type declaration. */
-  tree decl = TYPE_NAME (type);
-  return decl;
-}
-
 /* Given the predicate constraint T from a constrained-type-specifier, extract
    its TMPL and ARGS.  FIXME why do we need two different forms of
    constrained-type-specifier?  */
Index: pt.c
===================================================================
--- pt.c	(revision 230924)
+++ pt.c	(working copy)
@@ -23467,10 +23467,10 @@  make_args_non_dependent (vec<tree, va_gc
 
 /* Returns a type which represents 'auto' or 'decltype(auto)'.  We use a
    TEMPLATE_TYPE_PARM with a level one deeper than the actual template
-   parms.  */
+   parms.  If set_canonical is true, we set TYPE_CANONICAL on it.  */
 
 static tree
-make_auto_1 (tree name)
+make_auto_1 (tree name, bool set_canonical)
 {
   tree au = cxx_make_type (TEMPLATE_TYPE_PARM);
   TYPE_NAME (au) = build_decl (input_location,
@@ -23479,7 +23479,8 @@  make_auto_1 (tree name)
   TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
     (0, processing_template_decl + 1, processing_template_decl + 1,
      TYPE_NAME (au), NULL_TREE);
-  TYPE_CANONICAL (au) = canonical_type_parameter (au);
+  if (set_canonical)
+    TYPE_CANONICAL (au) = canonical_type_parameter (au);
   DECL_ARTIFICIAL (TYPE_NAME (au)) = 1;
   SET_DECL_TEMPLATE_PARM_P (TYPE_NAME (au));
 
@@ -23489,13 +23490,43 @@  make_auto_1 (tree name)
 tree
 make_decltype_auto (void)
 {
-  return make_auto_1 (get_identifier ("decltype(auto)"));
+  return make_auto_1 (get_identifier ("decltype(auto)"), true);
 }
 
 tree
 make_auto (void)
 {
-  return make_auto_1 (get_identifier ("auto"));
+  return make_auto_1 (get_identifier ("auto"), true);
+}
+
+/* Make a "constrained auto" type-specifier. This is an
+   auto type with constraints that must be associated after
+   deduction.  The constraint is formed from the given
+   CONC and its optional sequence of arguments, which are
+   non-null if written as partial-concept-id.  */
+
+tree
+make_constrained_auto (tree con, tree args)
+{
+  tree type = make_auto_1 (get_identifier ("auto"), false);
+
+  /* Build the constraint. */
+  tree tmpl = DECL_TI_TEMPLATE (con);
+  tree expr;
+  if (VAR_P (con))
+    expr = build_concept_check (tmpl, type, args);
+  else
+    expr = build_concept_check (build_overload (tmpl, NULL_TREE), type, args);
+
+  tree constr = make_predicate_constraint (expr);
+  PLACEHOLDER_TYPE_CONSTRAINTS (type) = constr;
+
+  /* Our canonical type depends on the constraint.  */
+  TYPE_CANONICAL (type) = canonical_type_parameter (type);
+
+  /* Attach the constraint to the type declaration. */
+  tree decl = TYPE_NAME (type);
+  return decl;
 }
 
 /* Given type ARG, return std::initializer_list<ARG>.  */
@@ -23811,7 +23842,7 @@  splice_late_return_type (tree type, tree
 	/* In an abbreviated function template we didn't know we were dealing
 	   with a function template when we saw the auto return type, so update
 	   it to have the correct level.  */
-	return make_auto_1 (TYPE_IDENTIFIER (type));
+	return make_auto_1 (TYPE_IDENTIFIER (type), true);
     }
   return type;
 }