[clang] 3efaf9c - [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (#92452)
via cfe-commits
cfe-commits at lists.llvm.org
Mon May 20 09:04:11 PDT 2024
Author: Krystian Stasiowski
Date: 2024-05-20T12:04:07-04:00
New Revision: 3efaf9caa56393597839b796d34f92459c711605
URL: https://github.com/llvm/llvm-project/commit/3efaf9caa56393597839b796d34f92459c711605
DIFF: https://github.com/llvm/llvm-project/commit/3efaf9caa56393597839b796d34f92459c711605.diff
LOG: [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (#92452)
Clang crashes when diagnosing the following invalid redeclaration in
C++11:
```
struct A {
void f();
};
constexpr void A::f() { } // crash here
```
This happens because `DiagnoseInvalidRedeclaration` tries to create a
fix-it to remove `const` from the out-of-line declaration of `f`, but
there is no `SourceLocation` for the `const` qualifier (it's implicitly
`const` due to `constexpr`) and an assert in
`FunctionTypeInfo::getConstQualifierLoc` fails.
This patch changes `DiagnoseInvalidRedeclaration` to only suggest the removal of the
`const` qualifier when it was explicitly specified in the _cv-qualifier-seq_ of the declaration.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDecl.cpp
clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5a123b0b86dda..a89e10524aa1f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -742,6 +742,8 @@ Bug Fixes to C++ Support
- Fix a bug with checking constrained non-type template parameters for equivalence. Fixes (#GH77377).
- Fix a bug where the last argument was not considered when considering the most viable function for
explicit object argument member functions. Fixes (#GH92188).
+- Fix a C++11 crash when a non-const non-static member function is defined out-of-line with
+ the ``constexpr`` specifier. Fixes (#GH61004).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 557fe10619c35..6764a979168d6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9217,19 +9217,20 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
<< Idx << FDParam->getType()
<< NewFD->getParamDecl(Idx - 1)->getType();
} else if (FDisConst != NewFDisConst) {
- SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
- << NewFDisConst << FD->getSourceRange().getEnd()
- << (NewFDisConst
- ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
- .getConstQualifierLoc())
- : FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
- .getRParenLoc()
- .getLocWithOffset(1),
- " const"));
- } else
+ auto DB = SemaRef.Diag(FD->getLocation(),
+ diag::note_member_def_close_const_match)
+ << NewFDisConst << FD->getSourceRange().getEnd();
+ if (const auto &FTI = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
+ DB << FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
+ " const");
+ else if (FTI.hasMethodTypeQualifiers() &&
+ FTI.getConstQualifierLoc().isValid())
+ DB << FixItHint::CreateRemoval(FTI.getConstQualifierLoc());
+ } else {
SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
: diag::note_local_decl_close_match);
+ }
}
return nullptr;
}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index a28a5f91c4775..788e93b56bb38 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -154,3 +154,14 @@ namespace {
// FIXME: We should diagnose this prior to C++17.
const int &r = A::n;
}
+
+#if __cplusplus < 201402L
+namespace ImplicitConstexprDef {
+ struct A {
+ void f(); // expected-note {{member declaration does not match because it is not const qualified}}
+ };
+
+ constexpr void A::f() { } // expected-warning {{'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior}}
+ // expected-error at -1 {{out-of-line definition of 'f' does not match any declaration in 'ImplicitConstexprDef::A'}}
+}
+#endif
More information about the cfe-commits
mailing list