Skip to content

[Clang] Ensure the method scope at the late parsing of noexcept specifiers #98023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 12, 2024
Merged
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
2 changes: 1 addition & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 19 additions & 2 deletions clang/lib/Parse/ParseCXXInlineMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
18 changes: 18 additions & 0 deletions clang/test/SemaCXX/cxx0x-noexcept-expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,21 @@ void f5() {
// expected-error@-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
Loading