You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Followup to #125526. This allows the unique object duplication warning
to fire on code inside of templates. Previously, it was disabled there
to prevent false positives if the template was never instantiated.
The patch has two parts: first, we move the check from
`FinalizeDeclaration` (which is only called during parsing) to
`CheckCompleteVariableDeclaration` (which is also called during template
instantiation). Since the code we're moving is fairly bulky, we abstract
it into a separate function for convenience.
Second, we disable the warning during template parsing, and add a check
later to see if the variable we're acting on on originated from a
template. If so, it has the potential to be duplicated just like an
inline variable.
## Testing
Unit tests for template have been added to the existing test suite. To
evaluate the patch on real code, I ran it on chromium and on clang
itself. As expected, in both cases we got strictly more warnings than
before. I manually looked through each new warning, and they all seemed
legitimate.
In chromium, we found [79 new warnings across 55
files](https://github.com/user-attachments/files/18676635/new_warnings_chromium.txt),
mostly in third-party code (for a total of 234 warnings across 137
files). In clang, we found [8 new warnings across 6
files](https://github.com/user-attachments/files/18676658/new_warnings_clang.txt),
for a total of 17 warnings across 11 files.
Copy file name to clipboardExpand all lines: clang/test/SemaCXX/unique_object_duplication.h
+86-1Lines changed: 86 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -154,4 +154,89 @@ namespace GlobalTest {
154
154
};
155
155
156
156
inlinefloat Test::disallowedStaticMember2 = 2.3; // hidden-warning {{'disallowedStaticMember2' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
int disallowedTemplate1 = 0; // hidden-warning {{'disallowedTemplate1<int>' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
167
+
168
+
template int disallowedTemplate1<int>; // hidden-note {{in instantiation of}}
169
+
170
+
171
+
// Should work for implicit instantiation as well
172
+
template <typename T>
173
+
int disallowedTemplate2 = 0; // hidden-warning {{'disallowedTemplate2<int>' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
// Ensure we only get warnings for templates that are actually instantiated
181
+
template <typename T>
182
+
int maybeAllowedTemplate = 0; // Not instantiated, so no warning here
183
+
184
+
template <typename T>
185
+
int maybeAllowedTemplate<T*> = 1; // hidden-warning {{'maybeAllowedTemplate<int *>' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
186
+
187
+
template <>
188
+
int maybeAllowedTemplate<bool> = 2; // hidden-warning {{'maybeAllowedTemplate<bool>' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
189
+
190
+
template int maybeAllowedTemplate<int*>; // hidden-note {{in instantiation of}}
191
+
192
+
193
+
194
+
// Should work the same for static class members
195
+
template <typename T>
196
+
structS {
197
+
staticint staticMember;
198
+
};
199
+
200
+
template <typename T>
201
+
int S<T>::staticMember = 0; // Never instantiated
202
+
203
+
// T* specialization
204
+
template <typename T>
205
+
structS<T*> {
206
+
staticint staticMember;
207
+
};
208
+
209
+
template <typename T>
210
+
int S<T*>::staticMember = 1; // hidden-warning {{'staticMember' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
int S<T&>::staticMember = 2; // hidden-warning {{'staticMember' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
staticint staticLocal; // hidden-warning {{'staticLocal' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
232
+
return &staticLocal;
233
+
}
234
+
235
+
template <>
236
+
int* wrapper<int*>() {
237
+
staticint staticLocal; // hidden-warning {{'staticLocal' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}}
238
+
return &staticLocal;
239
+
}
240
+
241
+
auto dummy = wrapper<bool>(); // hidden-note {{in instantiation of}}
0 commit comments