diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-16 23:18:29 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-05-16 23:18:29 +0000 |
commit | 40175f70b0e3a6ecc82cd5601ec12c49b1f5b354 (patch) | |
tree | 50d7960821ec80bd6136c7a2e9106406f64e8633 /gcc/lto | |
parent | 17223f318bbd597b8bf71b8bd3cbbdd8ee3773ea (diff) | |
download | gcc-40175f70b0e3a6ecc82cd5601ec12c49b1f5b354.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223258 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto')
-rw-r--r-- | gcc/lto/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/lto/lto-symtab.c | 160 |
2 files changed, 117 insertions, 50 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index ff8a213ab62..3725d1a25eb 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -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. diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index 396d3e27f23..995c7c98c75 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -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 (); } |