Author: Fangrui Song Date: 2022-04-20T10:32:41-07:00 New Revision: 0f5dbfd29ae0df215a01aff80d29255bb799fed0
URL: https://github.com/llvm/llvm-project/commit/0f5dbfd29ae0df215a01aff80d29255bb799fed0 DIFF: https://github.com/llvm/llvm-project/commit/0f5dbfd29ae0df215a01aff80d29255bb799fed0.diff LOG: Revert D123909 "[Clang] Use of decltype(capture) in parameter-declaration-clause" This reverts commit daa6d7b250edb81ffef7770a71049d7af211698b. It breaks valid code like https://reviews.llvm.org/D123909#3461716 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/lambda-capture-type-deduction.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 600185e3ddd84..eccbfa2daf27c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -281,8 +281,6 @@ C++2b Feature Support - Implemented `P2036R3: Change scope of lambda trailing-return-type <https://wg21.link/P2036R3>`_. This proposal modifies how variables captured in lambdas can appear in trailing return type expressions and how their types are deduced therein, in all C++ language versions. - `CWG2569 <https://cplusplus.github.io/CWG/issues/2569.html>`_ is also partially implemented so that - `[x](decltype(x)){}` doesn't become ill-formed with the adoption of P2036R3. CUDA Language Changes in Clang ------------------------------ diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e9b1fa0f27451..3046962dddec4 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1861,8 +1861,6 @@ class Parser : public CodeCompletionHandler { Token &Replacement); ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false); - ExprResult ParseCXXMaybeMutableAgnosticExpression(); - bool areTokensAdjacent(const Token &A, const Token &B); void CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectTypePtr, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6298838d60855..a1eb22da0f5e2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -787,23 +787,6 @@ class Sema final { /// context. unsigned FunctionScopesStart = 0; - /// Whether we are currently in the context of a mutable agnostic identifier - /// as described by CWG2569. - /// We are handling the unqualified-id of a decltype or noexcept expression. - bool InMutableAgnosticContext = false; - - /// RAII object used to change the value of \c InMutableAgnosticContext - /// within a \c Sema object. - class MutableAgnosticContextRAII { - Sema &SemaRef; - - public: - MutableAgnosticContextRAII(Sema &S) : SemaRef(S) { - SemaRef.InMutableAgnosticContext = true; - } - ~MutableAgnosticContextRAII() { SemaRef.InMutableAgnosticContext = false; } - }; - ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const { return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart, FunctionScopes.end()); @@ -5287,9 +5270,6 @@ class Sema final { CorrectionCandidateCallback *CCC = nullptr, bool IsInlineAsmIdentifier = false, Token *KeywordReplacement = nullptr); - ExprResult ActOnMutableAgnosticIdExpression(Scope *S, CXXScopeSpec &SS, - UnqualifiedId &Id); - void DecomposeUnqualifiedId(const UnqualifiedId &Id, TemplateArgumentListInfo &Buffer, DeclarationNameInfo &NameInfo, diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index e367417410c86..9cf9f7cc4c371 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1054,7 +1054,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, Sema::ExpressionEvaluationContextRecord::EK_Decltype); Result = Actions.CorrectDelayedTyposInExpr( - ParseCXXMaybeMutableAgnosticExpression(), /*InitDecl=*/nullptr, + ParseExpression(), /*InitDecl=*/nullptr, /*RecoverUncorrectedTypos=*/false, [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; }); if (Result.isInvalid()) { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 336b24942e07d..b03d4e3a90acb 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -685,34 +685,6 @@ ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { return Result; } -/// ParseCXXMaybeMutableAgnosticExpression - Handle expressions inside of -/// sizeof, decltype, noexcept -/// - unqualified-id -/// - expression -/// This serves to silence errors about captured variable referred in lambda -/// parameter list, if they are used as the unqualified-id of a decltype, -/// sizeof, or noexcept expression. -ExprResult Parser::ParseCXXMaybeMutableAgnosticExpression() { - - if (!getLangOpts().CPlusPlus11) - return ParseExpression(); - - if (Tok.is(tok::identifier) && NextToken().is(tok::r_paren)) { - UnqualifiedId Name; - CXXScopeSpec SS; - if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr, - /*ObjectHadErrors=*/false, - /*EnteringContext=*/false, - /*AllowDestructorName=*/false, - /*AllowConstructorName=*/false, - /*AllowDeductionGuide=*/false, - /*TemplateKWLoc=*/nullptr, Name)) - return ExprError(); - return Actions.ActOnMutableAgnosticIdExpression(getCurScope(), SS, Name); - } - return ParseExpression(); -} - /// ParseLambdaExpression - Parse a C++11 lambda expression. /// /// lambda-expression: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 59c1123749f54..7fbe083571e67 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2699,18 +2699,6 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, return BuildDeclarationNameExpr(SS, R, ADL); } -ExprResult Sema::ActOnMutableAgnosticIdExpression(Scope *S, CXXScopeSpec &SS, - UnqualifiedId &Id) { - MutableAgnosticContextRAII Ctx(*this); - return ActOnIdExpression(S, SS, /*TemplateKwLoc*/ - SourceLocation(), Id, - /*HasTrailingLParen*/ false, - /*IsAddressOfOperand*/ false, - /*CorrectionCandidateCallback*/ nullptr, - /*IsInlineAsmIdentifier*/ false, - /*KeywordReplacement*/ nullptr); -} - /// BuildQualifiedDeclarationNameExpr - Build a C++ qualified /// declaration name, generally during template instantiation. /// There's a large number of things which don't need to be done along @@ -18561,11 +18549,6 @@ static void buildLambdaCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI, static bool CheckCaptureUseBeforeLambdaQualifiers(Sema &S, VarDecl *Var, SourceLocation ExprLoc, LambdaScopeInfo *LSI) { - - // Allow `[a = 1](decltype(a)) {}` as per CWG2569. - if (S.InMutableAgnosticContext) - return true; - if (Var->isInvalidDecl()) return false; @@ -18648,7 +18631,7 @@ bool Sema::tryCaptureVariable( LSI = dyn_cast_or_null<LambdaScopeInfo>( FunctionScopes[FunctionScopesIndex]); if (LSI && LSI->BeforeLambdaQualifiersScope) { - if (isa<ParmVarDecl>(Var) && !Var->getDeclContext()->isFunctionOrMethod()) + if (isa<ParmVarDecl>(Var)) return true; IsInLambdaBeforeQualifiers = true; if (!CheckCaptureUseBeforeLambdaQualifiers(*this, Var, ExprLoc, LSI)) { diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp index ee5d872071cb7..90b26787ba313 100644 --- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp +++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp @@ -87,23 +87,23 @@ void err() { int y, z; // expected-note 2{{declared here}} auto implicit_tpl = [=]( // expected-note {{variable 'y' is captured here}} decltype( - [&]<decltype((y))> { return 0; }) y) { // expected-error{{captured variable 'y' cannot appear here}} + [&]<decltype(y)> { return 0; }) y) { //expected-error{{captured variable 'y' cannot appear here}} return y; }; - auto init_tpl = [x = 1]( // expected-note{{explicitly captured here}} - decltype([&]<decltype((x))> { return 0; }) y) { // expected-error {{captured variable 'x' cannot appear here}} + auto init_tpl = [x = 1]( // expected-note{{explicitly captured here}} + decltype([&]<decltype(x)> { return 0; }) y) { // expected-error {{captured variable 'x' cannot appear here}} return x; }; auto implicit = [=]( // expected-note {{variable 'z' is captured here}} decltype( - [&](decltype((z))) { return 0; }) z) { // expected-error{{captured variable 'z' cannot appear here}} + [&](decltype(z)) { return 0; }) z) { //expected-error{{captured variable 'z' cannot appear here}} return z; }; - auto init = [x = 1]( // expected-note{{explicitly captured here}} - decltype([&](decltype((x))) { return 0; }) y) { // expected-error {{captured variable 'x' cannot appear here}} + auto init = [x = 1]( // expected-note{{explicitly captured here}} + decltype([&](decltype(x)) { return 0; }) y) { // expected-error {{captured variable 'x' cannot appear here}} return x; }; @@ -141,20 +141,20 @@ void nested() { decltype([&]( decltype([=]( // expected-note {{variable 'x' is captured here}} decltype([&]( - decltype([&](decltype((x))) {}) // expected-error{{captured variable 'x' cannot appear here}} + decltype([&](decltype(x)) {}) // expected-error{{captured variable 'x' cannot appear here}} ) {})) {})) {})){}; (void)[&]( decltype([&]( decltype([&]( decltype([&]( - decltype([&](decltype((y))) {})) {})) {})) {})){}; + decltype([&](decltype(y)) {})) {})) {})) {})){}; (void)[=]( decltype([=]( decltype([=]( - decltype([=]( // expected-note {{variable 'z' is captured here}} - decltype([&]<decltype((z))> {}) // expected-error{{captured variable 'z' cannot appear here}} + decltype([=]( // expected-note {{variable 'z' is captured here}} + decltype([&]<decltype(z)> {}) // expected-error{{captured variable 'z' cannot appear here}} ) {})) {})) {})){}; } @@ -202,15 +202,3 @@ void test_dependent() { dependent_init_capture(0); dependent_variadic_capture(1, 2, 3, 4); } - -void test_CWG2569_tpl(auto a) { - (void)[=]<typename T = decltype(a)>(decltype(a) b = decltype(a)()){}; -} - -void test_CWG2569() { - int a = 0; - (void)[=]<typename T = decltype(a)>(decltype(a) b = decltype(a)()){}; - test_CWG2569_tpl(0); - - (void)[=]<typename T = decltype(not_a_thing)>(decltype(not_a_thing)){}; // expected-error 2{{use of undeclared identifier 'not_a_thing'}} -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits