ipa-utils.h (warn_types_mismatch, [...]): Declare.
authorJan Hubicka <hubicka@gcc.gnu.org>
Sat, 16 May 2015 23:18:29 +0000 (23:18 +0000)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 16 May 2015 23:18:29 +0000 (23:18 +0000)
* ipa-utils.h (warn_types_mismatch, odr_or_derived_type_p,
odr_types_equivalent_p): Declare.
(odr_type_p): Use gcc_checking_assert.
(type_in_anonymous_namespace_p) Declare.
(type_with_linkage_p): Declare.
* common.opt (Wlto-type-mismatch): New warning.
* ipa-devirt.c (compound_type_base): New function.
(odr_or_derived_type_p): New function.
(odr_types_equivalent_p): New function.
(add_type_duplicate): Simplify.
(type_with_linkage_p): Add hack to prevent false positives on C types
(type_in_anonymous_namespace_p): Likewise.
* tree.c (need_assembler_name_p): Use type_with_linkage.
* tree.h (type_in_anonymous_namespace_p): Remove.
* doc/invoke.texi (-Wlto-type-mismatch): Document

* lto-symtab.c (warn_type_compatibility_p): Break out from ...;
compare ODR types (if available) and function types.
(lto_symtab_merge): ... here; output ODR violation warnings
and call warn_types_mismatch.

* gfortran.dg/lto/20091028-2_1.c: Fix return value.
* gfortran.dg/lto/pr41576_1.f90: Add interface.
* gfortran.dg/lto/pr41521_0.f90: Disable lto-type-mismatch
* gfortran.dg/lto/pr60635_0.f90: Disable lto-type-mismatch.
* gfortran.dg/lto/20091028-1_1.c: Fix return type.
* gcc.dg/lto/20120723_0.c: Disbale lto-type-mismatch.

From-SVN: r223258

16 files changed:
gcc/common.opt
gcc/doc/invoke.texi
gcc/ipa-devirt.c
gcc/ipa-utils.h
gcc/lto/ChangeLog
gcc/lto/lto-symtab.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/20120723_0.c
gcc/testsuite/gfortran.dg/lto/20091028-1_1.c
gcc/testsuite/gfortran.dg/lto/20091028-2_1.c
gcc/testsuite/gfortran.dg/lto/pr41521_0.f90
gcc/testsuite/gfortran.dg/lto/pr41576_0.f90
gcc/testsuite/gfortran.dg/lto/pr41576_1.f90
gcc/testsuite/gfortran.dg/lto/pr60635_0.f90
gcc/tree.c
gcc/tree.h

index 859488f7a1c0dcf225c8722371d3a3cc5d30a887..562d34a05ae632c690f079ef2f6bc046345f6c09 100644 (file)
@@ -607,6 +607,10 @@ Woverflow
 Common Var(warn_overflow) Init(1) Warning
 Warn about overflow in arithmetic expressions
 
+Wlto-type-mismatch
+Common Var(warn_lto_type_mismatch) Init(1) Warning
+During link time optimization warn about mismatched types of global declarations
+
 Wpacked
 Common Var(warn_packed) Warning
 Warn when the packed attribute has no effect on struct layout
index 117b5d99dfc7ad2c60225c21c4f8d65f726695fc..1e484232b2bb7bbf9a51b990242f48e9d61328c7 100644 (file)
@@ -2698,6 +2698,14 @@ In this case, @code{PRId64} is treated as a separate preprocessing token.
 
 This warning is enabled by default.
 
+@item -Wlto-type-mismatch
+@opindex Wlto-type-mismatch
+@opindex Wno-lto-type-mistmach
+
+During the link-time optimization warn about type mismatches in between
+global declarations from different compilation units.
+Requires @option{-flto} to be enabled.  Enabled by default.
+
 @item -Wnarrowing @r{(C++ and Objective-C++ only)}
 @opindex Wnarrowing
 @opindex Wno-narrowing
index c073ac879b2d6c88dc6f873730ec65f9fea2801c..bf43859f47e7a22716567ad783c6c8a69ffe241c 100644 (file)
@@ -247,9 +247,14 @@ struct GTY(()) odr_type_d
 
 /* Return true if T is a type with linkage defined.  */
 
-static bool
+bool
 type_with_linkage_p (const_tree t)
 {
+  /* Builtin types do not define linkage, their TYPE_CONTEXT is NULL.  */
+  if (!TYPE_CONTEXT (t)
+      || !TYPE_NAME (t) || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL)
+    return false;
+
   return (RECORD_OR_UNION_TYPE_P (t)
          || TREE_CODE (t) == ENUMERAL_TYPE);
 }
@@ -261,12 +266,21 @@ bool
 type_in_anonymous_namespace_p (const_tree t)
 {
   gcc_assert (type_with_linkage_p (t));
-  /* TREE_PUBLIC of TYPE_STUB_DECL may not be properly set for
-     backend produced types (such as va_arg_type); those have CONTEXT NULL
-     and never are considered anonymoius.  */
-  if (!TYPE_CONTEXT (t))
-    return false;
-  return (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)));
+
+  if (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)))
+    {
+      tree ctx = DECL_CONTEXT (TYPE_NAME (t));
+      while (ctx)
+       {
+         if (TREE_CODE (ctx) == NAMESPACE_DECL)
+           return !TREE_PUBLIC (ctx);
+         if (TREE_CODE (ctx) == BLOCK)
+           ctx = BLOCK_SUPERCONTEXT (ctx);
+         else
+           ctx = get_containing_scope (ctx);
+       }
+    }
+  return false;
 }
 
 /* Return true of T is type with One Definition Rule info attached. 
@@ -589,6 +603,59 @@ types_must_be_same_for_odr (tree t1, tree t2)
     return TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2);
 }
 
+/* If T is compound type, return type it is based on.  */
+
+static tree
+compound_type_base (const_tree t)
+{
+  if (TREE_CODE (t) == ARRAY_TYPE
+      || POINTER_TYPE_P (t)
+      || TREE_CODE (t) == COMPLEX_TYPE
+      || VECTOR_TYPE_P (t))
+    return TREE_TYPE (t);
+  if (TREE_CODE (t) == METHOD_TYPE)
+    return TYPE_METHOD_BASETYPE (t);
+  if (TREE_CODE (t) == OFFSET_TYPE)
+    return TYPE_OFFSET_BASETYPE (t);
+  return NULL_TREE;
+}
+
+/* Return true if T is either ODR type or compound type based from it.
+   If the function return true, we know that T is a type originating from C++
+   source even at link-time.  */
+
+bool
+odr_or_derived_type_p (const_tree t)
+{
+  do
+    {
+      if (odr_type_p (t))
+       return true;
+      /* Function type is a tricky one. Basically we can consider it
+        ODR derived if return type or any of the parameters is.
+        We need to check all parameters because LTO streaming merges
+        common types (such as void) and they are not considered ODR then.  */
+      if (TREE_CODE (t) == FUNCTION_TYPE)
+       {
+         if (TYPE_METHOD_BASETYPE (t))
+           t = TYPE_METHOD_BASETYPE (t);
+         else
+          {
+            if (TREE_TYPE (t) && odr_or_derived_type_p (TREE_TYPE (t)))
+              return true;
+            for (t = TYPE_ARG_TYPES (t); t; t = TREE_CHAIN (t))
+              if (odr_or_derived_type_p (TREE_VALUE (t)))
+                return true;
+            return false;
+          }
+       }
+      else
+       t = compound_type_base (t);
+    }
+  while (t);
+  return t;
+}
+
 /* Compare types T1 and T2 and return true if they are
    equivalent.  */
 
@@ -1223,6 +1290,16 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
       return false;
     }
 
+  if ((type_with_linkage_p (t1) && type_in_anonymous_namespace_p (t1))
+      || (type_with_linkage_p (t2) && type_in_anonymous_namespace_p (t2)))
+    {
+      /* We can not trip this when comparing ODR types, only when trying to
+        match different ODR derivations from different declarations.
+        So WARN should be always false.  */
+      gcc_assert (!warn);
+      return false;
+    }
+
   if (comp_type_attributes (t1, t2) != 1)
     {
       warn_odr (t1, t2, NULL, NULL, warn, warned,
@@ -1625,6 +1702,20 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
   return true;
 }
 
+/* Return true if TYPE1 and TYPE2 are equivalent for One Definition Rule.  */
+
+bool
+odr_types_equivalent_p (tree type1, tree type2)
+{
+  hash_set<type_pair,pair_traits> visited;
+
+#ifdef ENABLE_CHECKING
+  gcc_assert (odr_or_derived_type_p (type1) && odr_or_derived_type_p (type2));
+#endif
+  return odr_types_equivalent_p (type1, type2, false, NULL,
+                                &visited);
+}
+
 /* TYPE is equivalent to VAL by ODR, but its tree representation differs
    from VAL->type.  This may happen in LTO where tree merging did not merge
    all variants of the same type or due to ODR violation.
@@ -1749,12 +1840,8 @@ add_type_duplicate (odr_type val, tree type)
                  base_mismatch = true;
              }
            else
-             {
-               hash_set<type_pair,pair_traits> visited;
-               if (!odr_types_equivalent_p (type1, type2, false, NULL,
-                                            &visited))
-                 base_mismatch = true;
-             }
+             if (!odr_types_equivalent_p (type1, type2))
+               base_mismatch = true;
            if (base_mismatch)
              {
                if (!warned && !val->odr_violated)
index 13c59a830bafafa08b8e74c88ec7e9189f945685..3378f6946f946206d3aaf203d6d6cb300718a1c2 100644 (file)
@@ -63,7 +63,9 @@ possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
                                   void **cache_token = NULL,
                                   bool speuclative = false);
 odr_type get_odr_type (tree, bool insert = false);
-bool odr_type_p (const_tree t);
+bool type_in_anonymous_namespace_p (const_tree);
+bool type_with_linkage_p (const_tree);
+bool odr_type_p (const_tree);
 bool possible_polymorphic_call_target_p (tree ref, gimple stmt, struct cgraph_node *n);
 void dump_possible_polymorphic_call_targets (FILE *, tree, HOST_WIDE_INT,
                                             const ipa_polymorphic_call_context &);
@@ -85,6 +87,9 @@ bool types_must_be_same_for_odr (tree, tree);
 bool types_odr_comparable (tree, tree, bool strict = false);
 cgraph_node *try_speculative_devirtualization (tree, HOST_WIDE_INT,
                                               ipa_polymorphic_call_context);
+void warn_types_mismatch (tree t1, tree t2);
+bool odr_or_derived_type_p (const_tree t);
+bool odr_types_equivalent_p (tree type1, tree type2);
 
 /* Return vector containing possible targets of polymorphic call E.
    If COMPLETEP is non-NULL, store true if the list is complete. 
index ff8a213ab62c24ed85c5e93989243a077f63cbd9..3725d1a25eba2e8d7eae876af00ff6775498024b 100644 (file)
@@ -1,3 +1,10 @@
+2015-05-17  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto-symtab.c (warn_type_compatibility_p): Break out from ...;
+       compare ODR types (if available) and function types.
+       (lto_symtab_merge): ... here; output ODR violation warnings
+       and call warn_types_mismatch.
+
 2015-04-29  Jan Hubicka  <hubicka@ucw.cz>
 
        * lto.c (lto_fixup_state): Call verify_type.
index 396d3e27f2320a47f0ac6941024a3eca3594726d..995c7c98c75ecebc4c31ea6b7a4171c7caf0ef14 100644 (file)
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-prop.h"
 #include "ipa-inline.h"
 #include "builtins.h"
+#include "print-tree.h"
 
 /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
    all edges and removing the old node.  */
@@ -203,45 +204,49 @@ lto_varpool_replace_node (varpool_node *vnode,
   vnode->remove ();
 }
 
-/* Merge two variable or function symbol table entries PREVAILING and ENTRY.
-   Return false if the symbols are not fully compatible and a diagnostic
-   should be emitted.  */
+/* Return non-zero if we want to output waring about T1 and T2.
+   Return value is a bitmask of reasons of violation:
+   Bit 0 indicates that types are not compatible of memory layout.
+   Bot 1 indicates that types are not compatible because of C++ ODR rule.  */
 
-static bool
-lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
+static int
+warn_type_compatibility_p (tree prevailing_type, tree type)
 {
-  tree prevailing_decl = prevailing->decl;
-  tree decl = entry->decl;
-  tree prevailing_type, type;
-
-  if (prevailing_decl == decl)
-    return true;
-
-  /* Merge decl state in both directions, we may still end up using
-     the new decl.  */
-  TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
-  TREE_ADDRESSABLE (decl) |= TREE_ADDRESSABLE (prevailing_decl);
-
-  /* The linker may ask us to combine two incompatible symbols.
-     Detect this case and notify the caller of required diagnostics.  */
-
-  if (TREE_CODE (decl) == FUNCTION_DECL)
+  int lev = 0;
+  /* C++ provide a robust way to check for type compatibility via the ODR
+     rule.  */
+  if (odr_or_derived_type_p (prevailing_type) && odr_type_p (type)
+      && !odr_types_equivalent_p (prevailing_type, type))
+    lev = 2;
+
+  /* Function types needs special care, because types_compatible_p never
+     thinks prototype is compatible to non-prototype.  */
+  if ((TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
+      && TREE_CODE (type) == TREE_CODE (prevailing_type))
     {
-      if (!types_compatible_p (TREE_TYPE (prevailing_decl),
-                              TREE_TYPE (decl)))
-       /* If we don't have a merged type yet...sigh.  The linker
-          wouldn't complain if the types were mismatched, so we
-          probably shouldn't either.  Just use the type from
-          whichever decl appears to be associated with the
-          definition.  If for some odd reason neither decl is, the
-          older one wins.  */
-       (void) 0;
-
-      return true;
+      lev |= warn_type_compatibility_p (TREE_TYPE (prevailing_type),
+                                       TREE_TYPE (type));
+      if (TREE_CODE (type) == METHOD_TYPE)
+       lev |= warn_type_compatibility_p (TYPE_METHOD_BASETYPE (prevailing_type),
+                                         TYPE_METHOD_BASETYPE (type));
+      if (prototype_p (prevailing_type) && prototype_p (type)
+         && TYPE_ARG_TYPES (prevailing_type) != TYPE_ARG_TYPES (type))
+       {
+         tree parm1, parm2;
+         for (parm1 = TYPE_ARG_TYPES (prevailing_type),
+              parm2 = TYPE_ARG_TYPES (type);
+              parm1 && parm2;
+              parm1 = TREE_CHAIN (prevailing_type),
+              parm2 = TREE_CHAIN (type))
+           lev |= warn_type_compatibility_p (TREE_VALUE (parm1),
+                                             TREE_VALUE (parm2));
+         if (parm1 || parm2)
+           lev = 3;
+       }
+      if (comp_type_attributes (prevailing_type, type) == 0)
+       lev = 3;
+      return lev;
     }
-
-  /* Now we exclusively deal with VAR_DECLs.  */
-
   /* Sharing a global symbol is a strong hint that two types are
      compatible.  We could use this information to complete
      incomplete pointed-to types more aggressively here, ignoring
@@ -254,19 +259,22 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
      ???  In principle we might want to only warn for structurally
      incompatible types here, but unless we have protective measures
      for TBAA in place that would hide useful information.  */
-  prevailing_type = TYPE_MAIN_VARIANT (TREE_TYPE (prevailing_decl));
-  type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
+  prevailing_type = TYPE_MAIN_VARIANT (prevailing_type);
+  type = TYPE_MAIN_VARIANT (type);
 
   if (!types_compatible_p (prevailing_type, type))
     {
-      if (COMPLETE_TYPE_P (type))
-       return false;
+      if (TREE_CODE (prevailing_type) == FUNCTION_TYPE
+         || TREE_CODE (type) == METHOD_TYPE)
+       return 1 | lev;
+      if (COMPLETE_TYPE_P (type) && COMPLETE_TYPE_P (prevailing_type))
+       return 1 | lev;
 
       /* If type is incomplete then avoid warnings in the cases
         that TBAA handles just fine.  */
 
       if (TREE_CODE (prevailing_type) != TREE_CODE (type))
-       return false;
+       return 1 | lev;
 
       if (TREE_CODE (prevailing_type) == ARRAY_TYPE)
        {
@@ -280,10 +288,10 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
            }
 
          if (TREE_CODE (tem1) != TREE_CODE (tem2))
-           return false;
+           return 1 | lev;
 
          if (!types_compatible_p (tem1, tem2))
-           return false;
+           return 1 | lev;
        }
 
       /* Fallthru.  Compatible enough.  */
@@ -292,6 +300,43 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
   /* ???  We might want to emit a warning here if type qualification
      differences were spotted.  Do not do this unconditionally though.  */
 
+  return lev;
+}
+
+/* Merge two variable or function symbol table entries PREVAILING and ENTRY.
+   Return false if the symbols are not fully compatible and a diagnostic
+   should be emitted.  */
+
+static bool
+lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
+{
+  tree prevailing_decl = prevailing->decl;
+  tree decl = entry->decl;
+
+  if (prevailing_decl == decl)
+    return true;
+
+  /* Merge decl state in both directions, we may still end up using
+     the new decl.  */
+  TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
+  TREE_ADDRESSABLE (decl) |= TREE_ADDRESSABLE (prevailing_decl);
+
+  /* The linker may ask us to combine two incompatible symbols.
+     Detect this case and notify the caller of required diagnostics.  */
+
+  if (TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      if (warn_type_compatibility_p (TREE_TYPE (prevailing_decl),
+                                    TREE_TYPE (decl)))
+       return false;
+
+      return true;
+    }
+
+  if (warn_type_compatibility_p (TREE_TYPE (prevailing_decl),
+                                TREE_TYPE (decl)))
+    return false;
+
   /* There is no point in comparing too many details of the decls here.
      The type compatibility checks or the completing of types has properly
      dealt with most issues.  */
@@ -483,24 +528,39 @@ lto_symtab_merge_decls_2 (symtab_node *first, bool diagnosed_p)
   /* Diagnose all mismatched re-declarations.  */
   FOR_EACH_VEC_ELT (mismatches, i, decl)
     {
-      if (!types_compatible_p (TREE_TYPE (prevailing->decl),
-                              TREE_TYPE (decl)))
-       diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
-                                  "type of %qD does not match original "
-                                  "declaration", decl);
-
+      int level = warn_type_compatibility_p (TREE_TYPE (prevailing->decl),
+                                            TREE_TYPE (decl));
+      if (level)
+       {
+         bool diag = false;
+         if (level > 1)
+           diag = warning_at (DECL_SOURCE_LOCATION (decl),
+                              OPT_Wodr,
+                              "%qD violates the C++ One Definition Rule ",
+                              decl);
+         if (!diag && (level & 1))
+           diag = warning_at (DECL_SOURCE_LOCATION (decl),
+                              OPT_Wlto_type_mismatch,
+                              "type of %qD does not match original "
+                              "declaration", decl);
+         if (diag)
+           warn_types_mismatch (TREE_TYPE (prevailing->decl),
+                                TREE_TYPE (decl));
+         diagnosed_p |= diag;
+       }
       else if ((DECL_USER_ALIGN (prevailing->decl)
                && DECL_USER_ALIGN (decl))
               && DECL_ALIGN (prevailing->decl) < DECL_ALIGN (decl))
        {
-         diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
+         diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl),
+                                    OPT_Wlto_type_mismatch,
                                     "alignment of %qD is bigger than "
                                     "original declaration", decl);
        }
     }
   if (diagnosed_p)
     inform (DECL_SOURCE_LOCATION (prevailing->decl),
-           "previously declared here");
+           "%qD was previously declared here", prevailing->decl);
 
   mismatches.release ();
 }
index 6732ed6dc047313dffdc8af7c6573a2c74738c45..5133549afed0f749164e8425c6f17f14b39bf7e5 100644 (file)
@@ -1,3 +1,12 @@
+2015-05-16  Jan Hubica  <hubicka@ucw.cz>
+
+       * gfortran.dg/lto/20091028-2_1.c: Fix return value.
+       * gfortran.dg/lto/pr41576_1.f90: Add interface.
+       * gfortran.dg/lto/pr41521_0.f90: Disable lto-type-mismatch
+       * gfortran.dg/lto/pr60635_0.f90: Disable lto-type-mismatch.
+       * gfortran.dg/lto/20091028-1_1.c: Fix return type.
+       * gcc.dg/lto/20120723_0.c: Disbale lto-type-mismatch.
+
 2015-05-16  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/65903
index 78cfdf77c5bde2cd34f48d3c14a6bc6908e5c9be..77694d8503ac93c06c4d287cea83f76ad0be4792 100644 (file)
@@ -3,7 +3,7 @@
    ??? This testcase is invalid C and can only pass on specific platforms.  */
 /* { dg-lto-do run } */
 /* { dg-skip-if "" { { sparc*-*-* } && ilp32 } { "*" } { "" } } */
-/* { dg-lto-options { {-O3 -fno-early-inlining -flto}} } */
+/* { dg-lto-options { {-O3 -fno-early-inlining -flto -Wno-lto-type-mismatch}} } */
 
 extern void abort (void);
 
index b3afc23fb8e849a784b9240c26b167edeb3bdfea..2db8438bc49575b50edf4d6389f481afb75be087 100644 (file)
@@ -1,9 +1,9 @@
 extern void bcopy(const void *, void *, __SIZE_TYPE__ n);
 char *p;
-int int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize,
-                          int * itypesize, int * typesize,
-                          int * DataHandle, char * Data,
-                          int * Count, int * code)
+void int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize,
+                           int * itypesize, int * typesize,
+                           int * DataHandle, char * Data,
+                           int * Count, int * code)
 {
   bcopy (typesize, p, sizeof(int)) ;
   bcopy (Data, p, *Count * *typesize) ;
index 496aaf11220bc50397948534e42ec00e007c6da2..e4718c214e035640b6e3f53b62b56bdb1ece69d2 100644 (file)
@@ -1,9 +1,9 @@
 extern void *memcpy(void *dest, const void *src, __SIZE_TYPE__ n);
 char *p;
-int int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize,
-                          int * itypesize, int * typesize,
-                          int * DataHandle, char * Data,
-                          int * Count, int * code)
+void int_gen_ti_header_c_ (char * hdrbuf, int * hdrbufsize,
+                           int * itypesize, int * typesize,
+                           int * DataHandle, char * Data,
+                           int * Count, int * code)
 {
   memcpy (typesize, p, sizeof(int)) ;
   memcpy (Data, p, *Count * *typesize) ;
index d882779263d8a03ff31ac44dcf8e9e519ae53e07..9ec8d370561a86a41f79be632749b3616e71f41d 100644 (file)
@@ -1,9 +1,16 @@
 ! { dg-lto-do link }
-! { dg-lto-options {{-g -flto} {-g -O -flto}} }
+! { dg-lto-options {{-g -flto -Wno-lto-type-mismatch} {-g -O -flto -Wno-lto-type-mismatch}} }
 program species
 integer spk(2)
 real eval(2)
 spk = 2
 call atom(1.1,spk,eval)
 end program
+interface
+  subroutine atom(sol,k,eval)
+    real, intent(in) :: sol
+    integer, intent(in) :: k(2)
+    real, intent(out) :: eval(2)
+  end subroutine
+end interface
 
index feda0b174cb483101d50cd83751dfb9a28b1f8ee..609c17ed20a5e4900dc78c394ad9d1c70abcf419 100644 (file)
@@ -1,5 +1,5 @@
 ! { dg-lto-do run }
-! { dg-lto-options { { -O2 -flto -Werror } } }
+! { dg-lto-options { { -O2 -flto -Werror -Wno-lto-type-mismatch } } }
 
 subroutine foo
   common /bar/ a, b
index 6aefcc875e34c85004d1ed58e5e0e8c280774471..877e044af1aaeac5b9e80f169be4792307dc22e7 100644 (file)
@@ -5,3 +5,8 @@ program test
   if (c/=1 .or. d/=2) call abort
 end program test
 
+interface
+  subroutine foo()
+  end subroutine
+end interface
+
index e121879859003846bb83f0a4127d22c153d260a9..37d084d802a57d78a55a3d8a184e248f01ff7b16 100644 (file)
@@ -1,4 +1,5 @@
 ! { dg-lto-do link }
+! { dg-lto-options {{ -Wno-lto-type-mismatch }} }
 program test
   use iso_fortran_env
 
index ae2cfdd3ebace3bcaa43ebcd1781eb303e04407f..6297f04865ca1e3eca6bf67ff0f5a003a14b1142 100644 (file)
@@ -5182,8 +5182,7 @@ need_assembler_name_p (tree decl)
       && DECL_NAME (decl)
       && decl == TYPE_NAME (TREE_TYPE (decl))
       && !TYPE_ARTIFICIAL (TREE_TYPE (decl))
-      && (((RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
-          || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+      && ((type_with_linkage_p (TREE_TYPE (decl))
           && !type_in_anonymous_namespace_p (TREE_TYPE (decl)))
          || TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE)
       && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
index 6d5254dcb438617dccef1692fdf1b627b78b93e1..912b05405d81c2e84a82c563b171b5fa79fbdc45 100644 (file)
@@ -4544,7 +4544,6 @@ extern tree obj_type_ref_class (tree ref);
 extern bool types_same_for_odr (const_tree type1, const_tree type2,
                                bool strict=false);
 extern bool contains_bitfld_component_ref_p (const_tree);
-extern bool type_in_anonymous_namespace_p (const_tree);
 extern bool block_may_fallthru (const_tree);
 extern void using_eh_for_cleanups (void);
 extern bool using_eh_for_cleanups_p (void);