Skip to content

Commit 13ec049

Browse files
committed
Check mutability recursively
1 parent 3e61c1a commit 13ec049

File tree

3 files changed

+24
-16
lines changed

3 files changed

+24
-16
lines changed

clang/include/clang/AST/Type.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,10 +1086,20 @@ class QualType {
10861086
/// applied to this type.
10871087
unsigned getCVRQualifiers() const;
10881088

1089+
// Determine whether the object seems constant (i.e., const-qualified)
10891090
bool isConstant(const ASTContext& Ctx) const {
10901091
return QualType::isConstant(*this, Ctx);
10911092
}
10921093

1094+
// Determine whether the object seems mutable, (i.e. non-const-qualified, and
1095+
// not an always-constant type like a function).
1096+
// Not perfect: doesn't account for mutable members, for example, or
1097+
// elements of container types.
1098+
// For nested pointers, any individual level being non-const is sufficient.
1099+
bool isMutable(const ASTContext &Ctx) const {
1100+
return QualType::isMutable(*this, Ctx);
1101+
}
1102+
10931103
/// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
10941104
bool isPODType(const ASTContext &Context) const;
10951105

@@ -1617,6 +1627,7 @@ class QualType {
16171627
// "static"-ize them to avoid creating temporary QualTypes in the
16181628
// caller.
16191629
static bool isConstant(QualType T, const ASTContext& Ctx);
1630+
static bool isMutable(QualType T, const ASTContext &Ctx);
16201631
static QualType getDesugaredType(QualType T, const ASTContext &Context);
16211632
static SplitQualType getSplitDesugaredType(QualType T);
16221633
static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);

clang/lib/AST/Type.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,17 @@ bool QualType::isConstant(QualType T, const ASTContext &Ctx) {
139139
return T.getAddressSpace() == LangAS::opencl_constant;
140140
}
141141

142+
bool QualType::isMutable(QualType T, const ASTContext &Ctx) {
143+
T = T.getNonReferenceType();
144+
if (T->isFunctionType())
145+
return false;
146+
if (!T.isConstant(Ctx))
147+
return true;
148+
if (T->isPointerType())
149+
return QualType::isMutable(T->getPointeeType(), Ctx);
150+
return false;
151+
}
152+
142153
std::optional<QualType::NonConstantStorageReason>
143154
QualType::isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
144155
bool ExcludeDtor) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13454,24 +13454,10 @@ void Sema::DiagnoseUniqueObjectDuplication(const VarDecl *VD) {
1345413454
!VD->isTemplated() &&
1345513455
GloballyUniqueObjectMightBeAccidentallyDuplicated(VD)) {
1345613456

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())) {
13457+
QualType Type = VD->getType();
13458+
if (Type.isMutable(VD->getASTContext())) {
1346113459
Diag(VD->getLocation(), diag::warn_possible_object_duplication_mutable)
1346213460
<< 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-
}
1347513461
}
1347613462

1347713463
// To keep false positives low, only warn if we're certain that the

0 commit comments

Comments
 (0)