PR c++/70029 - ICE with ref-qualifier and -flto
authorJason Merrill <jason@redhat.com>
Fri, 8 Sep 2017 22:39:17 +0000 (18:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 8 Sep 2017 22:39:17 +0000 (18:39 -0400)
PR c++/70029 - ICE with ref-qualifier and -flto
gcc/
* langhooks.h (struct lang_hooks_for_types): Add
copy_lang_qualifiers.
* attribs.c (build_type_attribute_qual_variant): Use it.
* langhooks-def.h (LANG_HOOKS_COPY_LANG_QUALIFIERS): Default to
NULL.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it.
* tree.c (verify_type): Re-enable TYPE_CANONICAL main variant check.
gcc/cp/
* tree.c (cxx_copy_lang_qualifiers): New.
* cp-tree.h: Declare it.
* cp-objcp-common.h: Define LANG_HOOKS_COPY_LANG_QUALIFIERS.

From-SVN: r251911

gcc/ChangeLog
gcc/attribs.c
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.h
gcc/cp/cp-tree.h
gcc/cp/tree.c
gcc/langhooks-def.h
gcc/langhooks.h
gcc/testsuite/g++.dg/lto/pr70029_0.C [new file with mode: 0644]
gcc/tree.c

index e4163aa5f16a7a9ba832c823ad0066a1cd9264e9..b9b04565d287bcf114645f9e440eadf2800a0e5d 100644 (file)
@@ -1,3 +1,14 @@
+2017-09-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/70029 - ICE with ref-qualifier and -flto
+       * langhooks.h (struct lang_hooks_for_types): Add
+       copy_lang_qualifiers.
+       * attribs.c (build_type_attribute_qual_variant): Use it.
+       * langhooks-def.h (LANG_HOOKS_COPY_LANG_QUALIFIERS): Default to
+       NULL.
+       (LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it.
+       * tree.c (verify_type): Re-enable TYPE_CANONICAL main variant check.
+
 2017-09-08  Eric Botcazou  <ebotcazou@adacore.com>
 
        PR target/81988
index faa0649e190d6ea36a2ae6d3ce65c268966b3781..b8f58a7459643c3d82eb8cac0eddbb4d9f6fde70 100644 (file)
@@ -959,8 +959,9 @@ build_decl_attribute_variant (tree ddecl, tree attribute)
    Record such modified types already made so we don't make duplicates.  */
 
 tree
-build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
+build_type_attribute_qual_variant (tree otype, tree attribute, int quals)
 {
+  tree ttype = otype;
   if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
     {
       tree ntype;
@@ -983,6 +984,11 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
        }
 
       ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
+      if (lang_hooks.types.copy_lang_qualifiers
+         && otype != TYPE_MAIN_VARIANT (otype))
+       ttype = (lang_hooks.types.copy_lang_qualifiers
+                (ttype, TYPE_MAIN_VARIANT (otype)));
+
       ntype = build_distinct_type_copy (ttype);
 
       TYPE_ATTRIBUTES (ntype) = attribute;
@@ -1000,6 +1006,9 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
        TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
 
       ttype = build_qualified_type (ntype, quals);
+      if (lang_hooks.types.copy_lang_qualifiers
+         && otype != TYPE_MAIN_VARIANT (otype))
+       ttype = lang_hooks.types.copy_lang_qualifiers (ttype, otype);
     }
   else if (TYPE_QUALS (ttype) != quals)
     ttype = build_qualified_type (ttype, quals);
index 6c4a31d7850e902c4f1b7c39e79c8a2558123ad5..730a2dace19d7d61049548a2c03a4e198b7e01e1 100644 (file)
@@ -1,3 +1,10 @@
+2017-09-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/70029 - ICE with ref-qualifier and -flto
+       * tree.c (cxx_copy_lang_qualifiers): New.
+       * cp-tree.h: Declare it.
+       * cp-objcp-common.h: Define LANG_HOOKS_COPY_LANG_QUALIFIERS.
+
 2017-09-06  Jason Merrill  <jason@redhat.com>
 
        PR c++/82053 - ICE with default argument in lambda in template
index 10fcdf324fc4881e61950adfa370402e9e8b00d2..3e4cc9c5d4ceaee544d6e7363236c47ea0695776 100644 (file)
@@ -99,6 +99,8 @@ extern void cp_register_dumps (gcc::dump_manager *);
 #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE cxx_builtin_function_ext_scope
 #undef LANG_HOOKS_TYPE_HASH_EQ
 #define LANG_HOOKS_TYPE_HASH_EQ        cxx_type_hash_eq
+#undef LANG_HOOKS_COPY_LANG_QUALIFIERS
+#define LANG_HOOKS_COPY_LANG_QUALIFIERS        cxx_copy_lang_qualifiers
 #undef LANG_HOOKS_MISSING_NORETURN_OK_P
 #define LANG_HOOKS_MISSING_NORETURN_OK_P cp_missing_noreturn_ok_p
 #undef LANG_HOOKS_BLOCK_MAY_FALLTHRU
index a0e31d3d19d313dbbe7944e81bf17149e307069f..a57de335f1a6c4b32e5cb1e71faf2485ca47900c 100644 (file)
@@ -6963,6 +6963,7 @@ extern tree convert_bitfield_to_declared_type   (tree);
 extern tree cp_save_expr                       (tree);
 extern bool cast_valid_in_integral_constant_expression_p (tree);
 extern bool cxx_type_hash_eq                   (const_tree, const_tree);
+extern tree cxx_copy_lang_qualifiers           (const_tree, const_tree);
 
 extern void cxx_print_statistics               (void);
 extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
index 12c31fb83420534d1083b9684ea7b249a1f5bac3..f387f38639b937e22119aaf658664cff95918189 100644 (file)
@@ -4626,6 +4626,21 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb)
                            TYPE_RAISES_EXCEPTIONS (typeb), ce_exact);
 }
 
+/* Copy the language-specific type variant modifiers from TYPEB to TYPEA.  For
+   C++, these are the exception-specifier and ref-qualifier.  */
+
+tree
+cxx_copy_lang_qualifiers (const_tree typea, const_tree typeb)
+{
+  tree type = CONST_CAST_TREE (typea);
+  if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
+    {
+      type = build_exception_variant (type, TYPE_RAISES_EXCEPTIONS (typeb));
+      type = build_ref_qualified_type (type, type_memfn_rqual (typeb));
+    }
+  return type;
+}
+
 /* Apply FUNC to all language-specific sub-trees of TP in a pre-order
    traversal.  Called from walk_tree.  */
 
index ea2006ccec5c6aa2052e87a3b9c7eb4b4c61dc8c..61b081bd7ccc57d90cae9e3203edfea17fd61191 100644 (file)
@@ -186,6 +186,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
   lhd_omp_firstprivatize_type_sizes
 #define LANG_HOOKS_OMP_MAPPABLE_TYPE   lhd_omp_mappable_type
 #define LANG_HOOKS_TYPE_HASH_EQ                NULL
+#define LANG_HOOKS_COPY_LANG_QUALIFIERS NULL
 #define LANG_HOOKS_GET_ARRAY_DESCR_INFO        NULL
 #define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
 #define LANG_HOOKS_GET_TYPE_BIAS       NULL
@@ -211,6 +212,7 @@ extern tree lhd_unit_size_without_reusable_padding (tree);
   LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
   LANG_HOOKS_OMP_MAPPABLE_TYPE, \
   LANG_HOOKS_TYPE_HASH_EQ, \
+  LANG_HOOKS_COPY_LANG_QUALIFIERS, \
   LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
   LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
   LANG_HOOKS_GET_TYPE_BIAS, \
index 88f6f71b559f8339cf12b8acc70f000d2a1baec7..b0c9829a6cd4df0246a748f9422ef186db201472 100644 (file)
@@ -123,6 +123,10 @@ struct lang_hooks_for_types
      FUNCTION_TYPE or METHOD_TYPE.  */
   bool (*type_hash_eq) (const_tree, const_tree);
 
+  /* If non-NULL, return TYPE1 with any language-specific modifiers copied from
+     TYPE2.  */
+  tree (*copy_lang_qualifiers) (const_tree, const_tree);
+
   /* Return TRUE if TYPE uses a hidden descriptor and fills in information
      for the debugger about the array bounds, strides, etc.  */
   bool (*get_array_descr_info) (const_tree, struct array_descr_info *);
diff --git a/gcc/testsuite/g++.dg/lto/pr70029_0.C b/gcc/testsuite/g++.dg/lto/pr70029_0.C
new file mode 100644 (file)
index 0000000..9c8c31c
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/70029
+// { dg-lto-do assemble }
+
+struct A
+{
+  A();
+  int foo() && __attribute__ ((__warn_unused_result__)) { return 0; }
+};
+
+A a;
index 7a70eb7760d55a431d6c72ffb9d7564178a08302..721330a4a499e722fd3233988bf54843b0136a6c 100644 (file)
@@ -13220,9 +13220,7 @@ verify_type (const_tree t)
       debug_tree (ct);
       error_found = true;
     }
-  /* FIXME: this is violated by the C++ FE as discussed in PR70029, when
-     FUNCTION_*_QUALIFIED flags are set.  */
-  if (0 && TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct)
+  if (TYPE_MAIN_VARIANT (t) == t && ct && TYPE_MAIN_VARIANT (ct) != ct)
    {
       error ("TYPE_CANONICAL of main variant is not main variant");
       debug_tree (ct);