@@ -13440,6 +13440,23 @@ bool Sema::GloballyUniqueObjectMightBeAccidentallyDuplicated(
1344013440 return true;
1344113441}
1344213442
13443+ // Determine whether the object seems mutable for the purpose of diagnosing
13444+ // possible unique object duplication, i.e. non-const-qualified, and
13445+ // not an always-constant type like a function.
13446+ // Not perfect: doesn't account for mutable members, for example, or
13447+ // elements of container types.
13448+ // For nested pointers, any individual level being non-const is sufficient.
13449+ bool looksMutable(QualType T, const ASTContext &Ctx) {
13450+ T = T.getNonReferenceType();
13451+ if (T->isFunctionType())
13452+ return false;
13453+ if (!T.isConstant(Ctx))
13454+ return true;
13455+ if (T->isPointerType())
13456+ return looksMutable(T->getPointeeType(), Ctx);
13457+ return false;
13458+ }
13459+
1344313460void Sema::DiagnoseUniqueObjectDuplication(const VarDecl *VD) {
1344413461 // If this object has external linkage and hidden visibility, it might be
1344513462 // duplicated when built into a shared library, which causes problems if it's
@@ -13454,24 +13471,10 @@ void Sema::DiagnoseUniqueObjectDuplication(const VarDecl *VD) {
1345413471 !VD->isTemplated() &&
1345513472 GloballyUniqueObjectMightBeAccidentallyDuplicated(VD)) {
1345613473
13457- // Check mutability. For pointers, ensure that both the pointer and the
13458- // pointee are (recursively) const.
13459- QualType Type = VD->getType().getNonReferenceType();
13460- if (!Type.isConstant(VD->getASTContext())) {
13474+ QualType Type = VD->getType();
13475+ if (looksMutable(Type, VD->getASTContext())) {
1346113476 Diag(VD->getLocation(), diag::warn_possible_object_duplication_mutable)
1346213477 << VD;
13463- } else {
13464- while (Type->isPointerType()) {
13465- Type = Type->getPointeeType();
13466- if (Type->isFunctionType())
13467- break;
13468- if (!Type.isConstant(VD->getASTContext())) {
13469- Diag(VD->getLocation(),
13470- diag::warn_possible_object_duplication_mutable)
13471- << VD;
13472- break;
13473- }
13474- }
1347513478 }
1347613479
1347713480 // To keep false positives low, only warn if we're certain that the
0 commit comments