[clang] f52a467 - [Clang] Ensure the method scope at the late parsing of noexcept specifiers (#98023)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 11 18:51:49 PDT 2024
Author: Younan Zhang
Date: 2024-07-12T09:51:46+08:00
New Revision: f52a4679e683807d699e105a6139a5a91401667f
URL: https://github.com/llvm/llvm-project/commit/f52a4679e683807d699e105a6139a5a91401667f
DIFF: https://github.com/llvm/llvm-project/commit/f52a4679e683807d699e105a6139a5a91401667f.diff
LOG: [Clang] Ensure the method scope at the late parsing of noexcept specifiers (#98023)
Previously, we only pushed the function scope once we entered the
function definition, whereas tryCaptureVariable() requires at least one
function scope available when ParmVarDecls being captured have been
owned by a function. This led to problems parsing the noexcept
specifiers, as the DeclRefExprs inside them were improperly computed.
Fixes https://github.com/llvm/llvm-project/issues/97453
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Parse/ParseCXXInlineMethods.cpp
clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index be2f06766a755..e68398c167a23 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1011,7 +1011,7 @@ Bug Fixes to C++ Support
- Fixed a type constraint substitution issue involving a generic lambda expression. (#GH93821)
- Fix a crash caused by improper use of ``__array_extent``. (#GH80474)
- Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307),
- (#GH88081), (#GH89496), (#GH90669) and (#GH91633).
+ (#GH88081), (#GH89496), (#GH90669), (#GH91633) and (#GH97453).
- Fixed a crash in constraint instantiation under nested lambdas with dependent parameters.
- Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368).
- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849)
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 943ce0fdde3a3..9ccbbf9a7d5d0 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -511,11 +511,28 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
// and the end of the function-definition, member-declarator, or
// declarator.
CXXMethodDecl *Method;
+ FunctionDecl *FunctionToPush;
if (FunctionTemplateDecl *FunTmpl
= dyn_cast<FunctionTemplateDecl>(LM.Method))
- Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ FunctionToPush = FunTmpl->getTemplatedDecl();
else
- Method = dyn_cast<CXXMethodDecl>(LM.Method);
+ FunctionToPush = cast<FunctionDecl>(LM.Method);
+ Method = dyn_cast<CXXMethodDecl>(FunctionToPush);
+
+ // Push a function scope so that tryCaptureVariable() can properly visit
+ // function scopes involving function parameters that are referenced inside
+ // the noexcept specifier e.g. through a lambda expression.
+ // Example:
+ // struct X {
+ // void ICE(int val) noexcept(noexcept([val]{}));
+ // };
+ // Setup the CurScope to match the function DeclContext - we have such
+ // assumption in IsInFnTryBlockHandler().
+ ParseScope FnScope(this, Scope::FnScope);
+ Sema::ContextRAII FnContext(Actions, FunctionToPush,
+ /*NewThisContext=*/false);
+ Sema::FunctionScopeRAII PopFnContext(Actions);
+ Actions.PushFunctionScope();
Sema::CXXThisScopeRAII ThisScope(
Actions, Method ? Method->getParent() : nullptr,
diff --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
index b9aeffbf034b2..a01edc77e02af 100644
--- a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
+++ b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
@@ -157,3 +157,21 @@ void f5() {
// expected-error at -1 {{no member named 'non_existent' in 'typeid_::X<true>'}}
}
} // namespace typeid_
+
+namespace GH97453 {
+
+struct UnconstrainedCtor {
+ int value_;
+
+ template <typename T>
+ constexpr UnconstrainedCtor(T value) noexcept(noexcept(value_ = value))
+ : value_(static_cast<int>(value)) {}
+};
+
+UnconstrainedCtor U(42);
+
+struct X {
+ void ICE(int that) noexcept(noexcept([that]() {}));
+};
+
+} // namespace GH97453
More information about the cfe-commits
mailing list