Skip to content

Commit c98e867

Browse files
authored
[Clang] Fix false positive -Wignored-qualifiers (#169664)
A deduced return type can be an object type, in which case `const` can have an effect. Delay the diagnostic to the point at which the type is deduced. Add tests for lambdas. Fixes #43054 Note that there is a discussion in #43054 about adding a separate warning for "const return types are weird" for the class type cases, but it would have to be a separate warning - warning which currently exists in clang-tidy as `readability-const-return-type`.
1 parent 0940f68 commit c98e867

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ Improvements to Clang's diagnostics
396396
- Fixed false positives in ``-Waddress-of-packed-member`` diagnostics when
397397
potential misaligned members get processed before they can get discarded.
398398
(#GH144729)
399+
- Fix a false positive warning in ``-Wignored-qualifiers`` when the return type is undeduced. (#GH43054)
399400

400401
- Clang now emits a diagnostic with the correct message in case of assigning to const reference captured in lambda. (#GH105647)
401402

clang/lib/Sema/SemaStmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3889,6 +3889,11 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
38893889
// Update all declarations of the function to have the deduced return type.
38903890
Context.adjustDeducedFunctionResultType(FD, Deduced);
38913891

3892+
if (!Deduced->isDependentType() && !Deduced->isRecordType() &&
3893+
!FD->isFunctionTemplateSpecialization())
3894+
diagnoseIgnoredQualifiers(
3895+
diag::warn_qual_return_type,
3896+
FD->getDeclaredReturnType().getLocalCVRQualifiers(), FD->getLocation());
38923897
return false;
38933898
}
38943899

clang/lib/Sema/SemaType.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5067,8 +5067,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
50675067
// cv-qualifiers on return types are pointless except when the type is a
50685068
// class type in C++.
50695069
if ((T.getCVRQualifiers() || T->isAtomicType()) &&
5070+
// A dependent type or an undeduced type might later become a class
5071+
// type.
50705072
!(S.getLangOpts().CPlusPlus &&
5071-
(T->isDependentType() || T->isRecordType()))) {
5073+
(T->isRecordType() || T->isDependentType() ||
5074+
T->isUndeducedAutoType()))) {
50725075
if (T->isVoidType() && !S.getLangOpts().CPlusPlus &&
50735076
D.getFunctionDefinitionKind() ==
50745077
FunctionDefinitionKind::Definition) {

clang/test/SemaCXX/return.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -std=c++11 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify
2+
// RUN: %clang_cc1 %s -std=c++14 -fcxx-exceptions -fexceptions -fsyntax-only -Wignored-qualifiers -verify
23

34
int test1() {
45
throw;
@@ -132,3 +133,27 @@ void cxx_unresolved_expr() {
132133
// expr doesn't assert.
133134
return int(undeclared, 4; // expected-error {{use of undeclared identifier 'undeclared'}}
134135
}
136+
137+
#if __cplusplus >= 201402L
138+
namespace GH43054 {
139+
struct S{};
140+
const auto foo() { return 0; } // expected-warning {{'const' type qualifier on return type has no effect}}
141+
const auto bar() { return S{}; }
142+
template <typename T>
143+
const auto baz() { return T{}; }
144+
145+
void test() {
146+
baz<int>();
147+
baz<S>();
148+
149+
[]() -> const auto { // expected-warning {{'const' type qualifier on return type has no effect}}
150+
return 0;
151+
}();
152+
153+
[]() -> const auto {
154+
return S{};
155+
}();
156+
}
157+
}
158+
159+
#endif

0 commit comments

Comments
 (0)