Skip to content

Commit a7a2fbe

Browse files
committed
Enable for templates
1 parent d95344c commit a7a2fbe

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13399,8 +13399,11 @@ bool Sema::GloballyUniqueObjectMightBeAccidentallyDuplicated(
1339913399
// about the properties of the function containing it.
1340013400
const ValueDecl *Target = Dcl;
1340113401
// VarDecls and FunctionDecls have different functions for checking
13402-
// inline-ness, so we have to do it manually.
13402+
// inline-ness, and whether they were originally templated, so we have to
13403+
// call the appropriate functions manually.
1340313404
bool TargetIsInline = Dcl->isInline();
13405+
bool TargetWasTemplated =
13406+
Dcl->getTemplateSpecializationKind() != TSK_Undeclared;
1340413407

1340513408
// Update the Target and TargetIsInline property if necessary
1340613409
if (Dcl->isStaticLocal()) {
@@ -13416,12 +13419,13 @@ bool Sema::GloballyUniqueObjectMightBeAccidentallyDuplicated(
1341613419
Target = FunDcl;
1341713420
// IsInlined() checks for the C++ inline property
1341813421
TargetIsInline = FunDcl->isInlined();
13422+
TargetWasTemplated =
13423+
FunDcl->getTemplateSpecializationKind() != TSK_Undeclared;
1341913424
}
1342013425

13421-
// Non-inline variables can only legally appear in one TU
13422-
// FIXME: This also applies to templated variables, but that can rarely lead
13423-
// to false positives so templates are disabled for now.
13424-
if (!TargetIsInline)
13426+
// Non-inline functions/variables can only legally appear in one TU,
13427+
// unless they were part of a template.
13428+
if (!TargetIsInline && !TargetWasTemplated)
1342513429
return false;
1342613430

1342713431
// If the object isn't hidden, the dynamic linker will prevent duplication.
@@ -13436,18 +13440,20 @@ bool Sema::GloballyUniqueObjectMightBeAccidentallyDuplicated(
1343613440
return true;
1343713441
}
1343813442

13439-
void Sema::DiagnoseDangerousUniqueObjectDuplication(const VarDecl* VD) {
13443+
void Sema::DiagnoseDangerousUniqueObjectDuplication(const VarDecl *VD) {
1344013444
// If this object has external linkage and hidden visibility, it might be
1344113445
// duplicated when built into a shared library, which causes problems if it's
1344213446
// mutable (since the copies won't be in sync) or its initialization has side
13443-
// effects (since it will run once per copy instead of once globally)
13447+
// effects (since it will run once per copy instead of once globally).
1344413448
// FIXME: Windows uses dllexport/dllimport instead of visibility, and we don't
1344513449
// handle that yet. Disable the warning on Windows for now.
13446-
// FIXME: Checking templates can cause false positives if the template in
13447-
// question is never instantiated (e.g. only specialized templates are used).
13450+
13451+
// Don't diagnose if we're inside a template;
13452+
// we'll diagnose during instantiation instead.
1344813453
if (!Context.getTargetInfo().shouldDLLImportComdatSymbols() &&
1344913454
!VD->isTemplated() &&
1345013455
GloballyUniqueObjectMightBeAccidentallyDuplicated(VD)) {
13456+
1345113457
// Check mutability. For pointers, ensure that both the pointer and the
1345213458
// pointee are (recursively) const.
1345313459
QualType Type = VD->getType().getNonReferenceType();

0 commit comments

Comments
 (0)