From b7f592fc5d0770f7cebe2d45843538b37077175c Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 29 Nov 2017 13:22:44 +0000 Subject: [PATCH] [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 --- gcc/ChangeLog | 6 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/opt/pr83187.C | 32 ++++++++++ gcc/tree.c | 93 +++++++++++++++--------------- 4 files changed, 90 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr83187.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01d6a9291ba..d0efe6f98cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-11-29 Nathan Sidwell + + PR c++/83817 + * tree.c (build_complex_type): Fix canonicalization. Only fill in + type if it is new. + 2017-11-29 Wilco Dijkstra * config/aarch64/aarch64.c (aarch64_print_operand): Add new diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dbe90640f6b..3b90be1b7b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-11-29 Nathan Sidwell + + PR c++/83187 + * g++.dg/opt/pr83187.C: New. + 2017-11-29 Jakub Jelinek PR middle-end/83185 diff --git a/gcc/testsuite/g++.dg/opt/pr83187.C b/gcc/testsuite/g++.dg/opt/pr83187.C new file mode 100644 index 00000000000..632d64b18e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr83187.C @@ -0,0 +1,32 @@ +// { 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 class COMPLEX; + +template <> +struct COMPLEX +{ + COMPLEX(double r, double i); + + __complex__ mem; +}; + +COMPLEX::COMPLEX (double r, double i) + : mem {r, i} {} + +typedef double dbl_t; + +dbl_t var; + +void foo (COMPLEX *ptr) +{ + const dbl_t unused = var; + + *ptr = COMPLEX (cos (var), sin (var)); +} diff --git a/gcc/tree.c b/gcc/tree.c index b3902479c32..5416866a644 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8083,65 +8083,66 @@ build_offset_type (tree basetype, tree type) tree build_complex_type (tree component_type, bool named) { - tree t; - gcc_assert (INTEGRAL_TYPE_P (component_type) || SCALAR_FLOAT_TYPE_P (component_type) || FIXED_POINT_TYPE_P (component_type)); /* 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. */ - hashval_t hash = type_hash_canon_hash (t); - t = type_hash_canon (hash, t); - - if (!COMPLETE_TYPE_P (t)) - layout_type (t); + hashval_t hash = type_hash_canon_hash (probe); + tree t = type_hash_canon (hash, probe); - 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); - else if (TYPE_CANONICAL (component_type) != component_type) + else if (TYPE_CANONICAL (TREE_TYPE (t)) != TREE_TYPE (t)) TYPE_CANONICAL (t) - = build_complex_type (TYPE_CANONICAL (component_type), named); - } - - /* We need to create a name, since complex is a fundamental type. */ - if (!TYPE_NAME (t) && named) - { - const char *name; - if (component_type == char_type_node) - name = "complex char"; - else if (component_type == signed_char_type_node) - name = "complex signed char"; - else if (component_type == unsigned_char_type_node) - name = "complex unsigned char"; - else if (component_type == short_integer_type_node) - name = "complex short int"; - else if (component_type == short_unsigned_type_node) - name = "complex short unsigned int"; - else if (component_type == integer_type_node) - name = "complex int"; - else if (component_type == unsigned_type_node) - name = "complex unsigned int"; - else if (component_type == long_integer_type_node) - name = "complex long int"; - else if (component_type == long_unsigned_type_node) - name = "complex long unsigned int"; - else if (component_type == long_long_integer_type_node) - name = "complex long long int"; - else if (component_type == long_long_unsigned_type_node) - name = "complex long long unsigned int"; - else - name = 0; + = build_complex_type (TYPE_CANONICAL (TREE_TYPE (t)), named); - if (name != 0) - TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, - get_identifier (name), t); + /* We need to create a name, since complex is a fundamental type. */ + if (named) + { + const char *name = NULL; + + if (TREE_TYPE (t) == char_type_node) + name = "complex char"; + else if (TREE_TYPE (t) == signed_char_type_node) + name = "complex signed char"; + else if (TREE_TYPE (t) == unsigned_char_type_node) + name = "complex unsigned char"; + else if (TREE_TYPE (t) == short_integer_type_node) + name = "complex short int"; + else if (TREE_TYPE (t) == short_unsigned_type_node) + name = "complex short unsigned int"; + else if (TREE_TYPE (t) == integer_type_node) + name = "complex int"; + else if (TREE_TYPE (t) == unsigned_type_node) + name = "complex unsigned int"; + else if (TREE_TYPE (t) == long_integer_type_node) + name = "complex long int"; + else if (TREE_TYPE (t) == long_unsigned_type_node) + name = "complex long unsigned int"; + else if (TREE_TYPE (t) == long_long_integer_type_node) + name = "complex long long int"; + else if (TREE_TYPE (t) == long_long_unsigned_type_node) + name = "complex long long unsigned int"; + + if (name != NULL) + TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL, + get_identifier (name), t); + } } return build_qualified_type (t, TYPE_QUALS (component_type)); -- 2.30.2