for example: trippels@gcc2-power8 llvm_build % cmake -DCMAKE_INSTALL_PREFIX=~/llvm-install -DCMAKE_BUILD_TYPE=release -DLLVM_ENABLE_ASSERTIONS=on -DLLVM_TARGETS_TO_BUILD="PowerPC" -DCMAKE_CXX_FLAGS_RELEASE:STRING="-O3 -DNDEBUG -pipe -flto=60" -DCMAKE_EXE_LINKER_FLAGS="-Wl,-O1,--hash-style=gnu,--gc-sections,--icf=safe" -DENABLE_PIC=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DLLVM_BINUTILS_INCDIR=/home/trippels/include -DCMAKE_C_COMPILER=/home/trippels/gcc_6/usr/local/bin/gcc -DCMAKE_CXX_COMPILER=/home/trippels/gcc_6/usr/local/bin/g++ ~/llvm trippels@gcc2-power8 llvm_build % make -j120 ... /home/trippels/gcc_6/usr/local/include/c++/6.0.0/ext/aligned_buffer.h:43:12: warning: type ‘struct __aligned_buffer’ violates one definition rule [-Wodr] struct __aligned_buffer ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/ext/aligned_buffer.h:43:12: note: a type with the same name but different base type is defined in another translation unit struct __aligned_buffer ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/type_traits:1985:12: note: type name ‘std::aligned_storage<104ul, 8ul>’ should match type name ‘std::aligned_storage<96ul, 8ul>’ struct aligned_storage ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/type_traits:1985:12: note: the incompatible type is defined here struct aligned_storage ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_tree.h:134:12: warning: type ‘struct _Rb_tree_node’ violates one definition rule [-Wodr] struct _Rb_tree_node : public _Rb_tree_node_base ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_tree.h:134:12: note: a different type is defined in another translation unit struct _Rb_tree_node : public _Rb_tree_node_base ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_tree.h:149:41: note: the first difference of corresponding definitions is field ‘_M_storage’ __gnu_cxx::__aligned_buffer<_Val> _M_storage; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_tree.h:149:41: note: a field of same name but different type is defined in another translation unit __gnu_cxx::__aligned_buffer<_Val> _M_storage; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/ext/aligned_buffer.h:43:12: note: type ‘struct __aligned_buffer’ should match type ‘struct __aligned_buffer’ that itself violate one definition rule struct __aligned_buffer ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/ext/aligned_buffer.h:43:12: note: the incompatible type is defined here struct __aligned_buffer ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:96:12: warning: type ‘struct pair’ violates one definition rule [-Wodr] struct pair ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:96:12: note: a different type is defined in another translation unit struct pair ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:102:11: note: the first difference of corresponding definitions is field ‘second’ _T2 second; /// @c second is a copy of the second object ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:102:11: note: a field of same name but different type is defined in another translation unit _T2 second; /// @c second is a copy of the second object ^ /home/trippels/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp:131:10: note: type ‘struct GroupInfo’ defined in anonymous namespace can not match type ‘struct GroupInfo’ struct GroupInfo { ^ /home/trippels/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp:73:8: note: the incompatible type defined in anonymous namespace in another translation unit struct GroupInfo { ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:99:19: warning: type ‘struct second_type’ violates one definition rule [-Wodr] typedef _T2 second_type; /// @c second_type is the second bound type ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:99:19: note: a different type is defined in another translation unit typedef _T2 second_type; /// @c second_type is the second bound type ^ /home/trippels/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp:132:32: note: the first difference of corresponding definitions is field ‘DiagsInGroup’ std::vector<const Record*> DiagsInGroup; ^ /home/trippels/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp:74:33: note: a field with different name is defined in another translation unit llvm::DenseSet<const Record*> Checkers; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/ext/aligned_buffer.h:43:12: warning: type ‘struct __aligned_buffer’ violates one definition rule [-Wodr] struct __aligned_buffer ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/ext/aligned_buffer.h:43:12: note: a type with the same name but different base type is defined in another translation unit struct __aligned_buffer ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/type_traits:1985:12: note: type name ‘std::aligned_storage<96ul, 8ul>’ should match type name ‘std::aligned_storage<104ul, 8ul>’ struct aligned_storage ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/type_traits:1985:12: note: the incompatible type is defined here struct aligned_storage ^ ... /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:102:12: warning: type ‘struct _Head_base’ violates one definition rule [-Wodr] struct _Head_base<_Idx, _Head, false> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:102:12: note: a different type is defined in another translation unit struct _Head_base<_Idx, _Head, false> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:147:13: note: the first difference of corresponding definitions is field ‘_M_head_impl’ _Head _M_head_impl; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:147:13: note: a field of same name but different type is defined in another translation unit _Head _M_head_impl; ^ /home/trippels/llvm/lib/DebugInfo/PDB/PDBSymbolFunc.cpp:28:7: note: type ‘struct FunctionArgEnumerator’ defined in anonymous namespace can not match type ‘struct FunctionArgEnumerator’ class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> { ^ /home/trippels/llvm/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp:24:7: note: the incompatible type defined in anonymous namespace in another translation unit class FunctionArgEnumerator : public IPDBEnumSymbols { ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:180:12: warning: type ‘struct _Tuple_impl’ violates one definition rule [-Wodr] struct _Tuple_impl<_Idx, _Head, _Tail...> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:180:12: note: a type with different bases is defined in another translation unit struct _Tuple_impl<_Idx, _Head, _Tail...> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:596:11: warning: type ‘struct tuple’ violates one definition rule [-Wodr] class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:596:11: note: a type with different bases is defined in another translation unit class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:129:11: warning: type ‘struct unique_ptr’ violates one definition rule [-Wodr] class unique_ptr ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:129:11: note: a different type is defined in another translation unit class unique_ptr ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:147:57: note: the first difference of corresponding definitions is field ‘_M_t’ __tuple_type _M_t; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:147:57: note: a field of same name but different type is defined in another translation unit __tuple_type _M_t; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:146:57: note: type ‘struct __tuple_type’ should match type ‘struct __tuple_type’ that itself violate one definition rule typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:146:57: note: the incompatible type is defined here typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:151:41: warning: type ‘struct element_type’ violates one definition rule [-Wodr] typedef _Tp element_type; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:151:41: note: a type with the same name but different base type is defined in another translation unit typedef _Tp element_type; ^ /home/trippels/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h:18:37: note: type name ‘llvm::IPDBEnumChildren<llvm::PDBSymbol>’ should match type name ‘llvm::IPDBEnumChildren<llvm::PDBSymbolData>’ template <typename ChildType> class IPDBEnumChildren { ^ /home/trippels/llvm/include/llvm/DebugInfo/PDB/IPDBEnumChildren.h:18:37: note: the incompatible type is defined here template <typename ChildType> class IPDBEnumChildren { ^ etc.
Some look real to me due to anonymous namespace usage.
(In reply to Andrew Pinski from comment #1) > Some look real to me due to anonymous namespace usage. Can you elaborate on that? I always thought that anonymous namespaces where a good tool for fixing ODR issues?
BTW gcc-5 crashes when building LLVM with lto (looks like a dup of PR66027): Linking CXX executable ../../../../bin/clang <nullptr_type 0x3fff800abda8 decltype(nullptr) unsigned DI size <integer_cst 0x3fff7f7b1158 type <integer_type 0x3fff7f7e02a0 bitsizetype> constant 64> unit size <integer_cst 0x3fff7f7b1170 type <integer_type 0x3fff7f7e01f8 sizetype> constant 8> align 8 symtab 0 alias set -1 canonical type 0x3fff7fddac98> lto1: internal compiler error: in odr_types_equivalent_p, at ipa-devirt.c:1543 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
/home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:96:12: warning: type ‘struct pair’ violates one definition rule [-Wodr] struct pair ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:96:12: note: a different type is defined in another translation unit struct pair ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:102:11: note: the first difference of corresponding definitions is field ‘second’ _T2 second; /// @c second is a copy of the second object ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/stl_pair.h:102:11: note: a field of same name but different type is defined in another translation unit _T2 second; /// @c second is a copy of the second object ^ /home/trippels/llvm/tools/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp:131:10: note: type ‘struct GroupInfo’ defined in anonymous namespace can not match type ‘struct GroupInfo’ struct GroupInfo { ^ /home/trippels/llvm/tools/clang/utils/TableGen/ClangSACheckersEmitter.cpp:73:8: note: the incompatible type defined in anonymous namespace in another translation unit struct GroupInfo { ^ This looks like a real LLVM bug. If you do class bar { anonymous_namespace_type foo; } then definin bar in non-anonymous namespace in more than one unit is ODR violation (because the type of field FOO is different in each of units). I think that it is what the warning is about: the instantiation is non-anonymous of type _T2=GroupInfo that is anonymous.
For example: % cat foo1.cpp #include <memory> namespace { class A { int i; }; } class G { std::unique_ptr<A> foo() const; }; std::unique_ptr<A> G::foo() const { return std::make_unique<A>(); } % cat foo2.cpp #include <memory> namespace { class A { bool a; }; } class H { std::unique_ptr<A> bar() const; }; std::unique_ptr<A> H::bar() const { return std::make_unique<A>(); } % g++ -flto -shared -std=c++14 foo1.cpp foo2.cpp /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:102:12: warning: type ‘struct _Head_base’ violates one definition rule [-Wodr] struct _Head_base<_Idx, _Head, false> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:102:12: note: a different type is defined in another translation unit struct _Head_base<_Idx, _Head, false> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:147:13: note: the first difference of corresponding definitions is field ‘_M_head_impl’ _Head _M_head_impl; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:147:13: note: a field of same name but different type is defined in another translation unit _Head _M_head_impl; ^ foo1.cpp:3:7: note: type ‘struct A’ defined in anonymous namespace can not match type ‘struct A’ class A { ^ foo2.cpp:3:7: note: the incompatible type defined in anonymous namespace in another translation unit class A { ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:180:12: warning: type ‘struct _Tuple_impl’ violates one definition rule [-Wodr] struct _Tuple_impl<_Idx, _Head, _Tail...> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:180:12: note: a type with different bases is defined in another translation unit struct _Tuple_impl<_Idx, _Head, _Tail...> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:596:11: warning: type ‘struct tuple’ violates one definition rule [-Wodr] class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/tuple:596:11: note: a type with different bases is defined in another translation unit class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:129:11: warning: type ‘struct unique_ptr’ violates one definition rule [-Wodr] class unique_ptr ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:129:11: note: a different type is defined in another translation unit class unique_ptr ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:147:57: note: the first difference of corresponding definitions is field ‘_M_t’ __tuple_type _M_t; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:147:57: note: a field of same name but different type is defined in another translation unit __tuple_type _M_t; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:146:57: note: type ‘struct __tuple_type’ should match type ‘struct __tuple_type’ that itself violate one definition rule typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:146:57: note: the incompatible type is defined here typedef std::tuple<typename _Pointer::type, _Dp> __tuple_type; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:151:41: warning: type ‘struct element_type’ violates one definition rule [-Wodr] typedef _Tp element_type; ^ /home/trippels/gcc_6/usr/local/include/c++/6.0.0/bits/unique_ptr.h:151:41: note: a different type is defined in another translation unit typedef _Tp element_type; ^ foo1.cpp:4:7: note: the first difference of corresponding definitions is field ‘i’ int i; ^ foo2.cpp:4:8: note: a field with different name is defined in another translation unit bool a; ^
Thank you for the testcase! With the fix for anonymous types I don't seem to get the warnings. Can you, please, check if that works for you and commit it?
(In reply to Jan Hubicka from comment #6) > Thank you for the testcase! With the fix for anonymous types I don't seem to > get the warnings. Can you, please, check if that works for you and commit > it? I still get the warnings after r223415, but I'm not 100% sure if they are valid or not.
If I change foo1.cpp from comment5 to: #include <memory> namespace first{ class A { int i; }; } using namespace first; class G { std::unique_ptr<A> foo() const; }; std::unique_ptr<A> G::foo() const { return std::make_unique<A>(); } it works fine. So it looks like a bug after all, because an anonymous namespace should be equivalent to: namespace _compiler_generated_name { ... } using namespace _compiler_generated_name;
I can reproduce these now, too. Indeed it is a bug - there is template instantiated with anonymous namespace parameter that makes it also anonymous. Sadly my fix for the false positives of type_in_anonymous_namespace_p also introduces false negatives. We really need a decision on https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01245.html
Author: hubicka Date: Sun May 24 19:38:14 2015 New Revision: 223633 URL: https://gcc.gnu.org/viewcvs?rev=223633&root=gcc&view=rev Log: PR lto/66180 * ipa-devirt.c (type_with_linkage): Check that TYPE_STUB_DECL is set; check for assembler name at LTO time. (type_in_anonymous_namespace): Remove hacks, check that all anonymous types are called "<anon>" (odr_type_p): Simplify; add check for "<anon>" (odr_subtypes_equivalent): Add odr_type_p check. * tree.c (need_assembler_name_p): Even anonymous namespace needs assembler name. * mangle.c (mangle_decl): Mangle anonymous namespace types as "<anon>". * g++.dg/lto/pr66180_0.C: New testcase. * g++.dg/lto/pr66180_1.C: New testcase. Added: trunk/gcc/testsuite/g++.dg/lto/pr66180_0.C trunk/gcc/testsuite/g++.dg/lto/pr66180_1.C Modified: trunk/gcc/ChangeLog trunk/gcc/cp/ChangeLog trunk/gcc/cp/mangle.c trunk/gcc/ipa-devirt.c trunk/gcc/testsuite/ChangeLog trunk/gcc/tree.c
Fixed. LLVM now builds without any warnings. Thanks.