[clang] 0f5dbfd - Revert D123909 "[Clang] Use of decltype(capture) in parameter-declaration-clause"

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 20 10:32:48 PDT 2022


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'}}
-}


        


More information about the cfe-commits mailing list