From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 121400 invoked by alias); 11 May 2015 14:28:22 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 121391 invoked by uid 89); 11 May 2015 14:28:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.5 required=5.0 tests=AWL,BAYES_40,KAM_LAZY_DOMAIN_SECURITY,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 11 May 2015 14:28:15 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 23D4B542F5C; Mon, 11 May 2015 16:28:11 +0200 (CEST) Date: Mon, 11 May 2015 14:28:00 -0000 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, jason@redhat.com Subject: False ODR violation positives on anonymous namespace types Message-ID: <20150511142810.GA6584@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2015-05/txt/msg00941.txt.bz2 Jason, I got my firefox tree building again and noticed that my patch to enable ODR merging on non-class types caused false positives: /aux/hubicka/trunk-install/include/c++/6.0.0/ext/new_allocator.h:66:26: warning: type ‘(anonymous namespace)::ObservationWithStack const&’ violates one definition rule [-Wodr] typedef const _Tp& const_reference; ^ /aux/hubicka/trunk-install/include/c++/6.0.0/ext/alloc_traits.h:110:53: note: it is defined as a pointer to different type in another translation unit typedef const value_type& const_reference; ^ /aux/hubicka/firefox8/xpcom/build/MainThreadIOLogger.cpp:28:8: note: type ‘const struct ObservationWithStack’ should match type ‘const struct value_type’ struct ObservationWithStack ^ /aux/hubicka/trunk-install/include/c++/6.0.0/ext/alloc_traits.h:103:53: note: the incompatible type is defined here typedef typename _Base_type::value_type value_type; ^ Here the obvious problem is that we try to merge type in anonymous namespace. This is because at LTO time odr_type_p returns true and type_in_anonymous_namespace returns false. odr_type_p basically checks that we computed mangled type name for it which is done in free_lang_data as follows: { /* We use DECL_ASSEMBLER_NAME to hold mangled type names for One Definition Rule merging. */ if (flag_lto_odr_type_mering && TREE_CODE (decl) == TYPE_DECL && DECL_NAME (decl) && decl == TYPE_NAME (TREE_TYPE (decl)) && !is_lang_specific (TREE_TYPE (decl)) /* Save some work. Names of builtin types are always derived from properties of its main variant. A special case are integer types where mangling do make differences between char/signed char/unsigned char etc. Storing name for these makes e.g. -fno-signed-char/-fsigned-char mismatches to be handled well. See cp/mangle.c:write_builtin_type for details. */ && (TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE && TREE_CODE (TREE_TYPE (decl)) != BOOLEAN_TYPE && TREE_CODE (TREE_TYPE (decl)) != REAL_TYPE && TREE_CODE (TREE_TYPE (decl)) != FIXED_POINT_TYPE) && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE) && !type_in_anonymous_namespace_p (TREE_TYPE (decl))) return !DECL_ASSEMBLER_NAME_SET_P (decl); and obviously we are not intended to mangle tyhis type and it should be caught by type_in_anonymous_namespace_p check: bool type_in_anonymous_namespace_p (const_tree t) { /* TREE_PUBLIC of TYPE_STUB_DECL may not be properly set for bulitin types; those have CONTEXT NULL. */ if (!TYPE_CONTEXT (t)) return false; return (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t))); } We already discussed earlier that type_in_anonymous_namespace_p is not working on compund types, because these do not have TYPE_STUB_DECL. I tought those are !TYPE_NAME types. What is reason for !TYPE_NAME type with no TYPE_STUB_DECL? Is it always a compound type with typedef name? One possible solution is to avoid producing mangled names so these won't be odr_type_p at LTO time: Index: tree.c =================================================================== --- tree.c (revision 222991) +++ tree.c (working copy) @@ -5173,6 +5173,7 @@ need_assembler_name_p (tree decl) && TREE_CODE (TREE_TYPE (decl)) != REAL_TYPE && TREE_CODE (TREE_TYPE (decl)) != FIXED_POINT_TYPE) && !TYPE_ARTIFICIAL (TREE_TYPE (decl)) + && TYPE_STUB_DECL (TREE_TYPE (decl)) && !variably_modified_type_p (TREE_TYPE (decl), NULL_TREE) && !type_in_anonymous_namespace_p (TREE_TYPE (decl))) return !DECL_ASSEMBLER_NAME_SET_P (decl); which silence the warnings, but I think it also may cause false negatives. Ohter option is to make type_in_anonymous_namespace_p work. The types in question are anonymous because they are defined within anonymous template, would the following work in type_in_anonymous_namespace_p? + /* Types (such as pointer_type) defined within class types may not + have their own TYPE_STUB_DECL. Look for the outer type. */ + while (!TYPE_STUB_DECL (t) && TYPE_NAME (t) + && TREE_CODE (TYPE_NAME (t)) == TYPE_DECL + && DECL_CONTEXT (TYPE_NAME (t)) + && TYPE_P (DECL_CONTEXT (TYPE_NAME (t)))) + t = DECL_CONTEXT (TYPE_NAME (t)); Last option would be make anonymous_namespace_p to walk to compound type bases. I made variant of this in https://gcc.gnu.org/ml/gcc-patches/2015-05/msg00880.html (odr_or_derived_type_p, modifying type_in_anonymous_namespace_p to work same way is definitly easy) What would be a preffered fix for this? Honza