Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,33 @@ void ignore_const_alias() {
p_local0 = &a[1];
}

void* ignore_const_return(){
void* const p = nullptr;
return p;
}

void const* const_return(){
void * p = nullptr;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p' of type 'void *' can be declared 'const'
// CHECK-FIXES: void const* p
return p;
}

template<typename T>
T* ignore_const_return_template(){
T* const p = nullptr;
return p;
}

template<typename T>
T const* const_return_template(){
T * p = nullptr;
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: pointee of variable 'p' of type 'int *' can be declared 'const'
// CHECK-FIXES: T const* p
return p;
}

void instantiate_return_templates() {
ignore_const_return_template<int>();
const_return_template<int>();
}
8 changes: 7 additions & 1 deletion clang/lib/Analysis/ExprMutationAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,10 +787,16 @@ ExprMutationAnalyzer::Analyzer::findPointeeToNonConst(const Expr *Exp) {
// FIXME: false positive if the pointee does not change in lambda
const auto CaptureNoConst = lambdaExpr(hasCaptureInit(Exp));

// Return statement in function with non-const pointer return type
const auto ReturnAsNonConst = returnStmt(
hasDescendant(equalsNode(Exp)),
hasAncestor(functionDecl(returns(NonConstPointerOrDependentType))));

const auto Matches =
match(stmt(anyOf(forEachDescendant(
stmt(anyOf(AssignToNonConst, PassAsNonConstArg,
CastToNonConst, CaptureNoConst))
CastToNonConst, CaptureNoConst,
ReturnAsNonConst))
.bind("stmt")),
forEachDescendant(InitToNonConst))),
Stm, Context);
Expand Down