@@ -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