mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 19:20:44 +08:00
ipa-utils.h (warn_types_mismatch, [...]): Declare.
* 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
This commit is contained in:
parent
4d259d334e
commit
259d29e396
@ -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
|
||||
|
@ -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
|
||||
|
113
gcc/ipa-devirt.c
113
gcc/ipa-devirt.c
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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,6 +204,105 @@ lto_varpool_replace_node (varpool_node *vnode,
|
||||
vnode->remove ();
|
||||
}
|
||||
|
||||
/* 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 int
|
||||
warn_type_compatibility_p (tree prevailing_type, tree type)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
/* 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
|
||||
mismatches in both field and tag names. It's difficult though
|
||||
to guarantee that this does not have side-effects on merging
|
||||
more compatible types from other translation units though. */
|
||||
|
||||
/* We can tolerate differences in type qualification, the
|
||||
qualification of the prevailing definition will prevail.
|
||||
??? 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 (prevailing_type);
|
||||
type = TYPE_MAIN_VARIANT (type);
|
||||
|
||||
if (!types_compatible_p (prevailing_type, type))
|
||||
{
|
||||
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 1 | lev;
|
||||
|
||||
if (TREE_CODE (prevailing_type) == ARRAY_TYPE)
|
||||
{
|
||||
tree tem1 = TREE_TYPE (prevailing_type);
|
||||
tree tem2 = TREE_TYPE (type);
|
||||
while (TREE_CODE (tem1) == ARRAY_TYPE
|
||||
&& TREE_CODE (tem2) == ARRAY_TYPE)
|
||||
{
|
||||
tem1 = TREE_TYPE (tem1);
|
||||
tem2 = TREE_TYPE (tem2);
|
||||
}
|
||||
|
||||
if (TREE_CODE (tem1) != TREE_CODE (tem2))
|
||||
return 1 | lev;
|
||||
|
||||
if (!types_compatible_p (tem1, tem2))
|
||||
return 1 | lev;
|
||||
}
|
||||
|
||||
/* Fallthru. Compatible enough. */
|
||||
}
|
||||
|
||||
/* ??? 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. */
|
||||
@ -212,7 +312,6 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
|
||||
{
|
||||
tree prevailing_decl = prevailing->decl;
|
||||
tree decl = entry->decl;
|
||||
tree prevailing_type, type;
|
||||
|
||||
if (prevailing_decl == decl)
|
||||
return true;
|
||||
@ -227,70 +326,16 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry)
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
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;
|
||||
if (warn_type_compatibility_p (TREE_TYPE (prevailing_decl),
|
||||
TREE_TYPE (decl)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 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
|
||||
mismatches in both field and tag names. It's difficult though
|
||||
to guarantee that this does not have side-effects on merging
|
||||
more compatible types from other translation units though. */
|
||||
|
||||
/* We can tolerate differences in type qualification, the
|
||||
qualification of the prevailing definition will prevail.
|
||||
??? 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));
|
||||
|
||||
if (!types_compatible_p (prevailing_type, type))
|
||||
{
|
||||
if (COMPLETE_TYPE_P (type))
|
||||
return false;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (TREE_CODE (prevailing_type) == ARRAY_TYPE)
|
||||
{
|
||||
tree tem1 = TREE_TYPE (prevailing_type);
|
||||
tree tem2 = TREE_TYPE (type);
|
||||
while (TREE_CODE (tem1) == ARRAY_TYPE
|
||||
&& TREE_CODE (tem2) == ARRAY_TYPE)
|
||||
{
|
||||
tem1 = TREE_TYPE (tem1);
|
||||
tem2 = TREE_TYPE (tem2);
|
||||
}
|
||||
|
||||
if (TREE_CODE (tem1) != TREE_CODE (tem2))
|
||||
return false;
|
||||
|
||||
if (!types_compatible_p (tem1, tem2))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Fallthru. Compatible enough. */
|
||||
}
|
||||
|
||||
/* ??? We might want to emit a warning here if type qualification
|
||||
differences were spotted. Do not do this unconditionally though. */
|
||||
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
|
||||
@ -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 ();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) ;
|
||||
|
@ -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) ;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -5,3 +5,8 @@ program test
|
||||
if (c/=1 .or. d/=2) call abort
|
||||
end program test
|
||||
|
||||
interface
|
||||
subroutine foo()
|
||||
end subroutine
|
||||
end interface
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
! { dg-lto-do link }
|
||||
! { dg-lto-options {{ -Wno-lto-type-mismatch }} }
|
||||
program test
|
||||
use iso_fortran_env
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user