https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123728
Bug ID: 123728
Summary: Wsubobject-linkage warns despite no anonymous
namespaces at all in a header
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: luto at kernel dot org
Target Milestone: ---
I reduced a really old warning from a test case using gtest and anonymous
namespaces. Here's the reduced version:
--- file.cpp ---
#include "header.h"
namespace { struct LocalEnum {}; }
struct Test {
typedef LocalEnum ParamType;
static void AddToRegistry() {
TestMetaFactory<Test> factory;
}
};
--- header.h ---
template <class TestClass>
struct ParameterizedTestFactory {
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {}
const ParamType parameter_;
};
template <class TestCase>
struct TestMetaFactory {
virtual void CreateTestFactory(typename TestCase::ParamType parameter) {
ParameterizedTestFactory<TestCase> f(parameter);
}
};
--- end ---
$ g++ -c -Wsubobject-linkage file.cpp
In file included from file.cpp:1:
header.h: In instantiation of 'struct ParameterizedTestFactory<Test>':
header.h:12:40: required from 'void
TestMetaFactory<TestCase>::CreateTestFactory(typename TestCase::ParamType)
[with TestCase = Test; typename TestCase::ParamType = {anonymous}::LocalEnum]'
header.h:11:16: required from here
header.h:2:8: warning: 'ParameterizedTestFactory<Test>' has a field 'const
ParameterizedTestFactory<Test>::ParamType
ParameterizedTestFactory<Test>::parameter_' whose type uses the anonymous
namespace [-Wsubobject-linkage]
2 | struct ParameterizedTestFactory {
| ^~~~~~~~~~~~~~~~~~~~~~~~
This warning predates C++11, I believe, but I can trigger it just fine on gcc
trunk using c++23 on Compiler Explorer.
It's hard for me to imagine that there's any possibility of an ODR violation
here. The header file contains only templates. The offending instance of the
template is parametrized on a type that isn't in a header (and in the Compiler
Explorer version is in the actual main C++ file), and that template in turn has
a typedef to the offending internal linkage type. But there is no way to refer
to this instance of the template outside the C++ file.
The virtual function seems to be an important -- removing the keyword virtual
from the header silences the warning. But even if one could someone call that
virtual function without naming TestMetaFactory<Test> (which is impossible in
this example but would be possible if it had a non-template base class), there
should still not be an ODR violation, as can't be another definition of
TestMetaFactory<Test>.
Here it is, approximately, on Compiler Explorer. I'm not a Compiler Explorer
expert and this is the first time I've every tried putting more than one file
into it.
https://godbolt.org/z/7z8xcMMGP
https://godbolt.org/#z:OYLghAFBqd5QCxAFwE4FN0BoCWIIDGAtgIYDW6AgqsAM4gDkAtACIDCAspQNICiA%2BgCEAqgEkAMi34AVAJoAFXgFIAzCwBK6ADYB1HMgQt0AI1EA7AGYB7BlgJWiABxxb0qcSTPAAriWDpRABMQAiUAJkFwwTtvWmQHAHlvZEdkgDEXdDMSInQUBHR%2BdAAPdAJkkmNXLAtM%2Blh0QP0rVCCQADYazLaARgAWLtds3JBSHDMAOgJHRyxQBlscWnMCLW9AxsYABkXaDhJxgGUrb1QCPIYe3YTHLO3bLU9gNoWASiwIRubW4J7BgN%2BAFZ/sM8pxyOhxEtkLQJshisg5oxHKgrAArMrICC0BAkW60V5KLaUImUYgQ/hEcY4IjeIj8DAAR28OAwgQgADVeOpDqIEgA5ADUKgmgMJxNJJECgSKpXKyEqrmxuPxzJIGFJgq1gpxePQtAA9ARWat0FMZprtbr8QaMAQFV5XObHJatWNJtNHOKScSFTR0Mh%2BFpxmQgzhjKh1Th9cq9bQ1RridrBRYiMhAt7dis1htggwdrg9gczMdTud7oWbnd8w8nm1yRR3p8mvEfiABrVXG0wlsQTk8gUpW4JggkQtC9n1psa4X9kcTmcLldK7czBXHl4XgxXu8luCKPJURj7RW0SA/mZ0AB3DJd4JhHrvLSMQG2NczqyMaQYdCC8IqZdkHuHcsDIEAe1FPoAHYAE4%2BkBHtAWguCkKwZ8GD6N8K0/cd6F7ICaybGAoGIiAkHsDZeBbFpcHwTssn7UZi2dGorDMZBDgIEhXHPDs2OQYRaHQeRilPDo0KeEIoiiLAhNce0cDY/AskCNgrDWIg1xUXsVKhS9%2BTpYw3HPMIsEcKxaH0RSzDUjStN7czLOQay9PQAyiCM1ATNk7RMWsw4/WQWy6Xsnz5OctiAvVZBXPczzvLiaLgs0kBtNkwLYsM4yejCd5aAXcsGH/cZVinP8wjCQcNlQEdwjCUlSVBWhHBIc4/ygwQdTQbx7UFcQrC4rReDMOl2siKCWFUTqlAmhriTiVAeuQQVpH1ZaZsiJNBWQABPW4NgsPqBu44bRvkdUcmkPb0Cmy1EucghBQANysHBAkFShpWkKxNGAaFUB2iBXjG10VrWjgAxINJWtbHbVDYVa4lUXgUxhlo4ZUTbKC1GbJolWbMbmygDQNQUAClYmW6xUEFNSnEyGneGKRwtBaNxSXGZb3SBhqOtBjBkFOMxBS2W78ZYbc0JfLCPyY8YWIInYm3IqxKOo1BaIgejQRAfdIWhWF4URax2M47i8n6Vj2ME4TRJnM8/g3UAG2wOS/KUz4zFU9SQvPLBdPGNysq8noHIsqy2OStc/kciOzEyjzst7N2FMiwKo79lOIpLDLA7ipP0qSn2Ur%2BRLUBivPg/PLY8oKi4XcpalaXpJkWTZTluV5AVhVFb1SRRdFMWxbxjCsYxj2QPviSlGUSjKCoqnQCADEKOf5UVG6trdZjPSnyg/X8QNgzMUNgwjKMYxX2V54VRfQdTdNMyfaWsHfAtPz1qE4kNhEsEVyWyIhFVugKi3xNba0YlVYco4TYcUGhbPi1shIiTEgMJ2UkIgySztZZSXsM5/ADvpKuPROix2zvgsy4ds4J3iiQsK7sc5FzspnXyqdGHlxodlToZcgrF2joXDhldE4h3aLXMsFxkDoCcI8SRf4VBsFWCQWgtAwZxDYI8ZRyNSQLSWoKc6kZciSNQDgAAXo0RGyBob2nRiDLau19roEOvYhiuRVFBQ0fQEA%2BjLrXT0RdIgV1bhi2xoKEoLMcDGmWt4wxbhTHmLWlY2GEBomBN/C1AxAY3DAxAKDLU6T%2BxGP4BAfJMTUDAw2rjS09gzBxD8QY1JgoSmZNQPwYJlTCYSl9FIlmJBZHw0UcotxbAlE3RUMoea3VeoWIhgqRJNiKlbSeqyQW3FnqvXemwDAvT0AWLmQDZe11QRDJGSALx/iGlNKMeUvmW86kFNiWYwIuy0YA3hhY4ZQlkYpmKf45phIOkhMqeLNpxJJboVfK/bCIAoE1VHP/ECML8DvDAn0AAHBMPomKsXYuxVLDCtgiAgEBL2N%2BtgcK2Dwn/YCHxSKkRVvTVwGs8CEAcM4RlIA6DZEcDiKwxsXBGPoBAYwFZjDjHVDtRgy5RXZABgkcemJJW2HsEQXI7EEhmC0BKmcGxjDeGAMMrQWh6CXFsBsUgjoLgFiaHaZyT19QVjXskJcix2LaHXOGSMAM1IbArGgGkiqsB2tQKPISRhzXAGPvMJWNRHh0A5NGK8VZ3zLlgWbHiltYE2xQfbVKEkvAYMiBENC4Z6hQB1g/QNxkGBQR6Cobc7wrCOGzsapgcRAiqBYKETBEQwgqEFEwBIfamAWC0PEMlQbjEbFLXlVh2dcHe2YQQr2nCQ6UKctZChZCXJCNofQthUVy4UOwWnaKK7M7pz4ee09O7srvDQJgc8z8GAQtJVgHCgpiiovaEwdofRBTAAII9Zei0T7AwgN%2BTA5UAKvFsPC94iKgagSJSKJC7QtgwRgmEGCWwoKoq2LWtBjBMJYEJX0LYkFUUqDI0hSj1HOivvJbJEA%2BFqVwFgEgE4KRkjgP4mmhBVsBLILtgWM8Kg/4/jen7K8kZHCKqfS%2BqFDAkhceWlYQ6n7v2/v/YBwUwHvCgd03TNlbgoMqBg1Swi8H0BDi8oh9CxHCVhHaBMHoPRKNOdc%2B59oOVIWy1wsxiz0a2OIBAI61smt1R0HOpeLQhwEBWCvK%2B5VbLenWWi9oOLCXk1KtZQzDlrnTLJYZvyRi44iuMuU5lxLAa17UDoCADA%2BVxGGgKIaqwcJf5rwCk0d8thU3wN4gJrNwnbAOzzc7aSRaz6logOWtMlavLVtrfWt9TbrItrbR2rthbBA9n7YO/tI6x1vonW9e1kB3ggecrkb66lp3pR6%2Bl2L8XqsmvEw%2Bv40m8RybxQpvzTMb4tA/V%2Bn9f6AOPVcxMMIhnJvRBWj%2BKDj5YPASfQ51KIoVCY6x9j7Hvn36MApQFuDSHAQ9FFICCnlOqcU86OhOteOyUE8CytsCsEMUIS2EhWC8FEK08YGEAl1cSWKeR5ZvFAuGdvqZ8ToNlklJ9CAA%3D
(Interestingly, GPT-5.2 Codex was unable to reduce this test case. creduce
successfully reduced it to a variant that seemed to have a legitimate
subobject-linkage warning. I ended up reducing it by hand.)
