Commit b7f592fc by Nathan Sidwell Committed by Nathan Sidwell

[PATCH] complex type canonicalization


https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02453.html
	PR c++/83817
	* tree.c (build_complex_type): Fix canonicalization.  Only fill in
	type if it is new.

	PR c++/83187
	* g++.dg/opt/pr83187.C: New.

From-SVN: r255231
parent e69a816d
2017-11-29 Nathan Sidwell <nathan@acm.org>
PR c++/83817
* tree.c (build_complex_type): Fix canonicalization. Only fill in
type if it is new.
2017-11-29 Wilco Dijkstra <wdijkstr@arm.com> 2017-11-29 Wilco Dijkstra <wdijkstr@arm.com>
* config/aarch64/aarch64.c (aarch64_print_operand): Add new * config/aarch64/aarch64.c (aarch64_print_operand): Add new
2017-11-29 Nathan Sidwell <nathan@acm.org>
PR c++/83187
* g++.dg/opt/pr83187.C: New.
2017-11-29 Jakub Jelinek <jakub@redhat.com> 2017-11-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/83185 PR middle-end/83185
......
// { dg-do compile { target c++11 } }
// { dg-additional-options "-O1 -Wno-pedantic" }
// PR c++/83187 ICE in get_alias_set due to canonical type confusion.
extern "C" {
double cos (double);
double sin (double);
}
template <typename> class COMPLEX;
template <>
struct COMPLEX<double>
{
COMPLEX(double r, double i);
__complex__ mem;
};
COMPLEX<double>::COMPLEX (double r, double i)
: mem {r, i} {}
typedef double dbl_t;
dbl_t var;
void foo (COMPLEX<double> *ptr)
{
const dbl_t unused = var;
*ptr = COMPLEX<double> (cos (var), sin (var));
}
...@@ -8083,66 +8083,67 @@ build_offset_type (tree basetype, tree type) ...@@ -8083,66 +8083,67 @@ build_offset_type (tree basetype, tree type)
tree tree
build_complex_type (tree component_type, bool named) build_complex_type (tree component_type, bool named)
{ {
tree t;
gcc_assert (INTEGRAL_TYPE_P (component_type) gcc_assert (INTEGRAL_TYPE_P (component_type)
|| SCALAR_FLOAT_TYPE_P (component_type) || SCALAR_FLOAT_TYPE_P (component_type)
|| FIXED_POINT_TYPE_P (component_type)); || FIXED_POINT_TYPE_P (component_type));
/* Make a node of the sort we want. */ /* Make a node of the sort we want. */
t = make_node (COMPLEX_TYPE); tree probe = make_node (COMPLEX_TYPE);
TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type); TREE_TYPE (probe) = TYPE_MAIN_VARIANT (component_type);
/* If we already have such a type, use the old one. */ /* If we already have such a type, use the old one. */
hashval_t hash = type_hash_canon_hash (t); hashval_t hash = type_hash_canon_hash (probe);
t = type_hash_canon (hash, t); tree t = type_hash_canon (hash, probe);
if (!COMPLETE_TYPE_P (t))
layout_type (t);
if (TYPE_CANONICAL (t) == t) if (t == probe)
{ {
if (TYPE_STRUCTURAL_EQUALITY_P (component_type)) /* We created a new type. The hash insertion will have laid
out the type. We need to check the canonicalization and
maybe set the name. */
gcc_checking_assert (COMPLETE_TYPE_P (t)
&& !TYPE_NAME (t)
&& TYPE_CANONICAL (t) == t);
if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t)))
SET_TYPE_STRUCTURAL_EQUALITY (t); SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (component_type) != component_type) else if (TYPE_CANONICAL (TREE_TYPE (t)) != TREE_TYPE (t))
TYPE_CANONICAL (t) TYPE_CANONICAL (t)
= build_complex_type (TYPE_CANONICAL (component_type), named); = build_complex_type (TYPE_CANONICAL (TREE_TYPE (t)), named);
}
/* We need to create a name, since complex is a fundamental type. */ /* We need to create a name, since complex is a fundamental type. */
if (!TYPE_NAME (t) && named) if (named)
{ {
const char *name; const char *name = NULL;
if (component_type == char_type_node)
if (TREE_TYPE (t) == char_type_node)
name = "complex char"; name = "complex char";
else if (component_type == signed_char_type_node) else if (TREE_TYPE (t) == signed_char_type_node)
name = "complex signed char"; name = "complex signed char";
else if (component_type == unsigned_char_type_node) else if (TREE_TYPE (t) == unsigned_char_type_node)
name = "complex unsigned char"; name = "complex unsigned char";
else if (component_type == short_integer_type_node) else if (TREE_TYPE (t) == short_integer_type_node)
name = "complex short int"; name = "complex short int";
else if (component_type == short_unsigned_type_node) else if (TREE_TYPE (t) == short_unsigned_type_node)
name = "complex short unsigned int"; name = "complex short unsigned int";
else if (component_type == integer_type_node) else if (TREE_TYPE (t) == integer_type_node)
name = "complex int"; name = "complex int";
else if (component_type == unsigned_type_node) else if (TREE_TYPE (t) == unsigned_type_node)
name = "complex unsigned int"; name = "complex unsigned int";
else if (component_type == long_integer_type_node) else if (TREE_TYPE (t) == long_integer_type_node)
name = "complex long int"; name = "complex long int";
else if (component_type == long_unsigned_type_node) else if (TREE_TYPE (t) == long_unsigned_type_node)
name = "complex long unsigned int"; name = "complex long unsigned int";
else if (component_type == long_long_integer_type_node) else if (TREE_TYPE (t) == long_long_integer_type_node)
name = "complex long long int"; name = "complex long long int";
else if (component_type == long_long_unsigned_type_node) else if (TREE_TYPE (t) == long_long_unsigned_type_node)
name = "complex long long unsigned int"; name = "complex long long unsigned int";
else
name = 0;
if (name != 0) if (name != NULL)
TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
get_identifier (name), t); get_identifier (name), t);
} }
}
return build_qualified_type (t, TYPE_QUALS (component_type)); return build_qualified_type (t, TYPE_QUALS (component_type));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment