[clang] [Clang][Sema] Fix crash when diagnosing near-match for 'constexpr' redeclaration in C++11 (PR #92452)
Krystian Stasiowski via cfe-commits
cfe-commits at lists.llvm.org
Fri May 17 05:49:15 PDT 2024
https://github.com/sdkrystian updated https://github.com/llvm/llvm-project/pull/92452
>From 27fab1ec54259941e3ded174de18cd99aa89bf7e Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Thu, 16 May 2024 16:42:27 -0400
Subject: [PATCH 1/2] [Clang][Sema] Fix crash when diagnosing near-match for
'constexpr' redeclaration in C++11
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/include/clang/Sema/DeclSpec.h | 12 ++++++------
clang/lib/Sema/SemaDecl.cpp | 18 +++++++++---------
.../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 11 +++++++++++
4 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2d2928e418623..411a5f752899d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -724,6 +724,8 @@ Bug Fixes to C++ Support
templates during partial ordering when deducing template arguments from a function declaration or when
taking the address of a function template.
- Fix a bug with checking constrained non-type template parameters for equivalence. Fixes (#GH77377).
+- Fix a C++11 crash when a non-const non-static member function is defined out-of-line with
+ the ``constexpr`` specifier.
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 23bc780e04979..44d96db54b5f0 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
/// Retrieve the location of the 'const' qualifier.
SourceLocation getConstQualifierLoc() const {
- assert(MethodQualifiers);
- return MethodQualifiers->getConstSpecLoc();
+ return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
+ : SourceLocation();
}
/// Retrieve the location of the 'volatile' qualifier.
SourceLocation getVolatileQualifierLoc() const {
- assert(MethodQualifiers);
- return MethodQualifiers->getVolatileSpecLoc();
+ return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
+ : SourceLocation();
}
/// Retrieve the location of the 'restrict' qualifier.
SourceLocation getRestrictQualifierLoc() const {
- assert(MethodQualifiers);
- return MethodQualifiers->getRestrictSpecLoc();
+ return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
+ : SourceLocation();
}
/// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0dbdf923df95a..22749dc4799bc 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9203,15 +9203,15 @@ 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"));
+ 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 (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
+ ConstLoc.isValid())
+ DB << FixItHint::CreateRemoval(ConstLoc);
} else
SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
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
>From 569e2f158ca66f759ab7f00780cecfccf5f5055a Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski <sdkrystian at gmail.com>
Date: Fri, 17 May 2024 08:49:03 -0400
Subject: [PATCH 2/2] [FOLD] undo changes to FunctionTypeInfo and check
hasMethodTypeQualifiers instead
---
clang/include/clang/Sema/DeclSpec.h | 12 ++++++------
clang/lib/Sema/SemaDecl.cpp | 6 +++---
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 44d96db54b5f0..23bc780e04979 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -1527,20 +1527,20 @@ struct DeclaratorChunk {
/// Retrieve the location of the 'const' qualifier.
SourceLocation getConstQualifierLoc() const {
- return MethodQualifiers ? MethodQualifiers->getConstSpecLoc()
- : SourceLocation();
+ assert(MethodQualifiers);
+ return MethodQualifiers->getConstSpecLoc();
}
/// Retrieve the location of the 'volatile' qualifier.
SourceLocation getVolatileQualifierLoc() const {
- return MethodQualifiers ? MethodQualifiers->getVolatileSpecLoc()
- : SourceLocation();
+ assert(MethodQualifiers);
+ return MethodQualifiers->getVolatileSpecLoc();
}
/// Retrieve the location of the 'restrict' qualifier.
SourceLocation getRestrictQualifierLoc() const {
- return MethodQualifiers ? MethodQualifiers->getRestrictSpecLoc()
- : SourceLocation();
+ assert(MethodQualifiers);
+ return MethodQualifiers->getRestrictSpecLoc();
}
/// Retrieve the location of the 'mutable' qualifier, if any.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 22749dc4799bc..8a24273875db6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9209,9 +9209,9 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
if (const auto &FTI = ExtraArgs.D.getFunctionTypeInfo(); !NewFDisConst)
DB << FixItHint::CreateInsertion(FTI.getRParenLoc().getLocWithOffset(1),
" const");
- else if (SourceLocation ConstLoc = FTI.getConstQualifierLoc();
- ConstLoc.isValid())
- DB << FixItHint::CreateRemoval(ConstLoc);
+ else if (FTI.hasMethodTypeQualifiers() &&
+ FTI.getConstQualifierLoc().isValid())
+ DB << FixItHint::CreateRemoval(FTI.getConstQualifierLoc());
} else
SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
More information about the cfe-commits
mailing list