Skip to content

Commit 168791d

Browse files
HerrCai0907vbvictor
authored andcommitted
[ExprMutation] handle return non-const type (llvm#161396)
Co-authored-by: Baranov Victor <[email protected]>
1 parent 18836cf commit 168791d

File tree

4 files changed

+57
-9
lines changed

4 files changed

+57
-9
lines changed

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,8 @@ Changes in existing checks
342342
- Improved :doc:`misc-const-correctness
343343
<clang-tidy/checks/misc/const-correctness>` check to avoid false
344344
positives when pointers is tranferred to non-const references
345-
and avoid false positives of function pointer.
345+
and avoid false positives of function pointer and fix false
346+
positives on return of non-const pointer.
346347

347348
- Improved :doc:`misc-header-include-cycle
348349
<clang-tidy/checks/misc/header-include-cycle>` check performance.

clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-pointer-as-pointers.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ void ignore_const_alias() {
4848
p_local0 = &a[1];
4949
}
5050

51+
void *return_non_const() {
52+
void *const a = nullptr;
53+
return a;
54+
}
55+
5156
void function_pointer_basic() {
5257
void (*const fp)() = nullptr;
5358
fp();

clang/lib/Analysis/ExprMutationAnalyzer.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ class ExprPointeeResolve {
140140
// explicit cast will be checked in `findPointeeToNonConst`
141141
const CastKind kind = ICE->getCastKind();
142142
if (kind == CK_LValueToRValue || kind == CK_DerivedToBase ||
143-
kind == CK_UncheckedDerivedToBase)
143+
kind == CK_UncheckedDerivedToBase ||
144+
(kind == CK_NoOp && (ICE->getType() == ICE->getSubExpr()->getType())))
144145
return resolveExpr(ICE->getSubExpr());
145146
return false;
146147
}
@@ -788,13 +789,16 @@ ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) {
788789
// FIXME: false positive if the pointee does not change in lambda
789790
const auto CaptureNoConst = lambdaExpr(hasCaptureInit(Exp));
790791

791-
const auto Matches =
792-
match(stmt(anyOf(forEachDescendant(
793-
stmt(anyOf(AssignToNonConst, PassAsNonConstArg,
794-
CastToNonConst, CaptureNoConst))
795-
.bind("stmt")),
796-
forEachDescendant(InitToNonConst))),
797-
Stm, Context);
792+
const auto ReturnNoConst =
793+
returnStmt(hasReturnValue(canResolveToExprPointee(Exp)));
794+
795+
const auto Matches = match(
796+
stmt(anyOf(forEachDescendant(
797+
stmt(anyOf(AssignToNonConst, PassAsNonConstArg,
798+
CastToNonConst, CaptureNoConst, ReturnNoConst))
799+
.bind("stmt")),
800+
forEachDescendant(InitToNonConst))),
801+
Stm, Context);
798802
return selectFirst<Stmt>("stmt", Matches);
799803
}
800804

clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,4 +2038,42 @@ TEST(ExprMutationAnalyzerTest, PointeeMutatedByConditionOperator) {
20382038
EXPECT_TRUE(isPointeeMutated(Results, AST.get()));
20392039
}
20402040

2041+
TEST(ExprMutationAnalyzerTest, PointeeMutatedByReturn) {
2042+
{
2043+
const std::string Code = R"(
2044+
int * f() {
2045+
int *const x = nullptr;
2046+
return x;
2047+
})";
2048+
auto AST = buildASTFromCodeWithArgs(Code, {"-Wno-everything"});
2049+
auto Results =
2050+
match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
2051+
EXPECT_TRUE(isPointeeMutated(Results, AST.get()));
2052+
}
2053+
{
2054+
const std::string Code = R"(
2055+
int * f() {
2056+
int *const x = nullptr;
2057+
return x;
2058+
})";
2059+
// in C++23, AST will have NoOp cast.
2060+
auto AST =
2061+
buildASTFromCodeWithArgs(Code, {"-Wno-everything", "-std=c++23"});
2062+
auto Results =
2063+
match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
2064+
EXPECT_TRUE(isPointeeMutated(Results, AST.get()));
2065+
}
2066+
{
2067+
const std::string Code = R"(
2068+
int const* f() {
2069+
int *const x = nullptr;
2070+
return x;
2071+
})";
2072+
auto AST = buildASTFromCodeWithArgs(Code, {"-Wno-everything"});
2073+
auto Results =
2074+
match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
2075+
EXPECT_FALSE(isPointeeMutated(Results, AST.get()));
2076+
}
2077+
}
2078+
20412079
} // namespace clang

0 commit comments

Comments
 (0)