Tyker updated this revision to Diff 298344.
Tyker retitled this revision from "[clang] fix consteval call in default 
arguements " to "[clang] fix consteval call in default arguements".
Tyker added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

rebased and add more fixes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74130/new/

https://reviews.llvm.org/D74130

Files:
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===================================================================
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -258,6 +258,26 @@
   return f(0);  
 };
 
+consteval int f1() {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+consteval auto g() { return f1; }
+consteval int h(int (*p)() = g()) { return p(); }
+int h1(int (*p)() = g()) { return p(); }
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+constexpr auto e = g();
+// expected-error@-1 {{must be initialized by a constant expression}}
+// expected-note@-2 {{is not a constant expression}}
+
+auto l = [](int (*p)() = g()) { return p(); };
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+auto l2 = [](int (*p)() = g()) consteval { return p(); };
+
 }
 
 namespace std {
@@ -594,3 +614,22 @@
 }
 
 } // namespace special_ctor
+
+namespace top_level {
+struct S {
+  consteval S() {}
+  int a;
+// expected-note@-1 {{subobject declared here}}
+};
+
+S s; // expected-error {{is not a constant expression}}
+// expected-note@-1 {{is not initialized}}
+
+struct S1 {
+  consteval S1() {}
+  int a = 0;
+};
+
+S1 s1;
+
+}
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -891,6 +891,10 @@
   LambdaScopeInfo *const LSI = getCurLambda();
   assert(LSI && "LambdaScopeInfo should be on stack!");
 
+  if (ParamInfo.getDeclSpec().getConstexprSpecifier() == CSK_consteval)
+    ExprEvalContexts.back().IIEndScopeAction =
+        ExpressionEvaluationContextRecord::IIESA_Drop;
+
   // Determine if we're within a context where we know that the lambda will
   // be dependent, because there are template parameters in scope.
   bool KnownDependent;
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16097,13 +16097,16 @@
   return TransformToPE(*this).TransformExpr(E);
 }
 
-void
-Sema::PushExpressionEvaluationContext(
+void Sema::PushExpressionEvaluationContext(
     ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl,
-    ExpressionEvaluationContextRecord::ExpressionKind ExprContext) {
+    ExpressionEvaluationContextRecord::ExpressionKind ExprContext,
+    bool IsLambdaParamScope) {
   ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
                                 LambdaContextDecl, ExprContext);
   Cleanup.reset();
+  if (IsLambdaParamScope)
+    ExprEvalContexts.back().IIEndScopeAction =
+        Sema::ExpressionEvaluationContextRecord::IIESA_Propagate;
   if (!MaybeODRUseExprs.empty())
     std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
 }
@@ -16183,7 +16186,9 @@
 
 ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
   if (!E.isUsable() || !Decl || !Decl->isConsteval() || isConstantEvaluated() ||
-      RebuildingImmediateInvocation)
+      RebuildingImmediateInvocation ||
+      ExprEvalContexts.back().IIEndScopeAction ==
+          ExpressionEvaluationContextRecord::IIESA_Drop)
     return E;
 
   /// Opportunistically remove the callee from ReferencesToConsteval if we can.
@@ -16312,14 +16317,31 @@
   It->getPointer()->setSubExpr(Res.get());
 }
 
-static void
-HandleImmediateInvocations(Sema &SemaRef,
-                           Sema::ExpressionEvaluationContextRecord &Rec) {
+void Sema::HandleImmediateInvocations(
+    Sema::ExpressionEvaluationContextRecord &Rec) {
   if ((Rec.ImmediateInvocationCandidates.size() == 0 &&
        Rec.ReferenceToConsteval.size() == 0) ||
-      SemaRef.RebuildingImmediateInvocation)
+      RebuildingImmediateInvocation ||
+      Rec.IIEndScopeAction ==
+          Sema::ExpressionEvaluationContextRecord::IIESA_Drop)
     return;
 
+  /// If we can't handle immediate invocations yet. add them to the outer scope.
+  /// This occurs for default argument of lambdas as we can't know if the lambda
+  /// is consteval until after the parameter context has been poped.
+  if (Rec.IIEndScopeAction ==
+      Sema::ExpressionEvaluationContextRecord::IIESA_Propagate) {
+    assert(ExprEvalContexts.size() >= 2);
+    (ExprEvalContexts.rbegin() + 1)
+        ->ImmediateInvocationCandidates.append(
+            Rec.ImmediateInvocationCandidates.begin(),
+            Rec.ImmediateInvocationCandidates.end());
+    (ExprEvalContexts.rbegin() + 1)
+        ->ReferenceToConsteval.insert(Rec.ReferenceToConsteval.begin(),
+                                      Rec.ReferenceToConsteval.end());
+    return;
+  }
+
   /// When we have more then 1 ImmediateInvocationCandidates we need to check
   /// for nested ImmediateInvocationCandidates. when we have only 1 we only
   /// need to remove ReferenceToConsteval in the immediate invocation.
@@ -16327,16 +16349,16 @@
 
     /// Prevent sema calls during the tree transform from adding pointers that
     /// are already in the sets.
-    llvm::SaveAndRestore<bool> DisableIITracking(
-        SemaRef.RebuildingImmediateInvocation, true);
+    llvm::SaveAndRestore<bool> DisableIITracking(RebuildingImmediateInvocation,
+                                                 true);
 
     /// Prevent diagnostic during tree transfrom as they are duplicates
-    Sema::TentativeAnalysisScope DisableDiag(SemaRef);
+    Sema::TentativeAnalysisScope DisableDiag(*this);
 
     for (auto It = Rec.ImmediateInvocationCandidates.rbegin();
          It != Rec.ImmediateInvocationCandidates.rend(); It++)
       if (!It->getInt())
-        RemoveNestedImmediateInvocation(SemaRef, Rec, It);
+        RemoveNestedImmediateInvocation(*this, Rec, It);
   } else if (Rec.ImmediateInvocationCandidates.size() == 1 &&
              Rec.ReferenceToConsteval.size()) {
     struct SimpleRemove : RecursiveASTVisitor<SimpleRemove> {
@@ -16352,12 +16374,11 @@
   }
   for (auto CE : Rec.ImmediateInvocationCandidates)
     if (!CE.getInt())
-      EvaluateAndDiagnoseImmediateInvocation(SemaRef, CE);
+      EvaluateAndDiagnoseImmediateInvocation(*this, CE);
   for (auto DR : Rec.ReferenceToConsteval) {
     auto *FD = cast<FunctionDecl>(DR->getDecl());
-    SemaRef.Diag(DR->getBeginLoc(), diag::err_invalid_consteval_take_address)
-        << FD;
-    SemaRef.Diag(FD->getLocation(), diag::note_declared_at);
+    Diag(DR->getBeginLoc(), diag::err_invalid_consteval_take_address) << FD;
+    Diag(FD->getLocation(), diag::note_declared_at);
   }
 }
 
@@ -16394,7 +16415,7 @@
   }
 
   WarnOnPendingNoDerefs(Rec);
-  HandleImmediateInvocations(*this, Rec);
+  HandleImmediateInvocations(Rec);
 
   // Warn on any volatile-qualified simple-assignments that are not discarded-
   // value expressions nor unevaluated operands (those cases get removed from
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -17041,6 +17041,11 @@
   if (isNonlocalVariable(D))
     PushExpressionEvaluationContext(
         ExpressionEvaluationContext::PotentiallyEvaluated, D);
+
+  bool HasConstantInitializer = false;
+  if (auto *VD = dyn_cast<VarDecl>(D))
+    HasConstantInitializer = VD->isConstexpr() || VD->hasAttr<ConstInitAttr>();
+  isConstantEvaluatedOverride = HasConstantInitializer;
 }
 
 /// Invoked after we are finished parsing an initializer for the declaration D.
@@ -17054,6 +17059,7 @@
 
   if (S && D->isOutOfLine())
     ExitDeclaratorContext(S);
+  isConstantEvaluatedOverride = false;
 }
 
 /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -1023,6 +1023,8 @@
   DiagnoseUnterminatedPragmaPack();
   DiagnoseUnterminatedPragmaAttribute();
 
+  HandleImmediateInvocations(ExprEvalContexts.back());
+
   // All delayed member exception specs should be checked or we end up accepting
   // incompatible declarations.
   assert(DelayedOverridingExceptionSpecChecks.empty());
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6455,8 +6455,9 @@
     ProhibitAttributes(FnAttrs);
   } else {
     if (Tok.isNot(tok::r_paren))
-      ParseParameterDeclarationClause(D.getContext(), FirstArgAttrs, ParamInfo,
-                                      EllipsisLoc);
+      ParseParameterDeclarationClause(
+          D.getContext(), FirstArgAttrs, ParamInfo, EllipsisLoc,
+          D.getDeclSpec().getConstexprSpecifier() == CSK_consteval);
     else if (RequiresArg)
       Diag(Tok, diag::err_argument_required_after_attribute);
 
@@ -6705,10 +6706,9 @@
 /// [C++11] attribute-specifier-seq parameter-declaration
 ///
 void Parser::ParseParameterDeclarationClause(
-       DeclaratorContext DeclaratorCtx,
-       ParsedAttributes &FirstArgAttrs,
-       SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
-       SourceLocation &EllipsisLoc) {
+    DeclaratorContext DeclaratorCtx, ParsedAttributes &FirstArgAttrs,
+    SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+    SourceLocation &EllipsisLoc, bool InConstantConstext) {
 
   // Avoid exceeding the maximum function scope depth.
   // See https://bugs.llvm.org/show_bug.cgi?id=19607
@@ -6859,8 +6859,13 @@
           // used.
           EnterExpressionEvaluationContext Eval(
               Actions,
-              Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed,
-              Param);
+              InConstantConstext
+                  ? Sema::ExpressionEvaluationContext::ConstantEvaluated
+                  : Sema::ExpressionEvaluationContext::
+                        PotentiallyEvaluatedIfUsed,
+              Param, Sema::ExpressionEvaluationContextRecord::EK_Other,
+              /*ShouldEnter*/ true,
+              DeclaratorCtx == DeclaratorContext::LambdaExprContext);
 
           ExprResult DefArgResult;
           if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1141,6 +1141,16 @@
     /// Whether we are in a decltype expression.
     bool IsDecltype;
 
+    enum ImmediateInvocationEndScopeAction {
+      IIESA_Handle, ///< Immediate invocation can and should be handeled at the
+                    ///< end of the scope.
+      IIESA_Propagate, ///< Immediate invocation cannot be handeled at the end
+                       ///< of the scope and should be propagated to the outer
+                       ///< scope.
+      IIESA_Drop, ///< Immediate invocation should be dropped at the end of the
+                  ///< scope.
+    } IIEndScopeAction = IIESA_Handle;
+
     /// The number of active cleanup objects when we entered
     /// this expression evaluation context.
     unsigned NumCleanupObjects;
@@ -2414,6 +2424,8 @@
                                      bool &AddToScope);
   bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
 
+  void HandleImmediateInvocations(Sema::ExpressionEvaluationContextRecord &Rec);
+
   enum class CheckConstexprKind {
     /// Diagnose issues that are non-constant or that are extensions.
     Diagnose,
@@ -4674,7 +4686,8 @@
   void PushExpressionEvaluationContext(
       ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr,
       ExpressionEvaluationContextRecord::ExpressionKind Type =
-          ExpressionEvaluationContextRecord::EK_Other);
+          ExpressionEvaluationContextRecord::EK_Other,
+      bool IsLambdaParamScope = false);
   enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
   void PushExpressionEvaluationContext(
       ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t,
@@ -12620,11 +12633,11 @@
       Decl *LambdaContextDecl = nullptr,
       Sema::ExpressionEvaluationContextRecord::ExpressionKind ExprContext =
           Sema::ExpressionEvaluationContextRecord::EK_Other,
-      bool ShouldEnter = true)
+      bool ShouldEnter = true, bool IsLambdaParamScope = false)
       : Actions(Actions), Entered(ShouldEnter) {
     if (Entered)
       Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
-                                              ExprContext);
+                                              ExprContext, IsLambdaParamScope);
   }
   EnterExpressionEvaluationContext(
       Sema &Actions, Sema::ExpressionEvaluationContext NewContext,
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -2923,10 +2923,9 @@
          Declarator &D,
          SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo);
   void ParseParameterDeclarationClause(
-         DeclaratorContext DeclaratorContext,
-         ParsedAttributes &attrs,
-         SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
-         SourceLocation &EllipsisLoc);
+      DeclaratorContext DeclaratorContext, ParsedAttributes &attrs,
+      SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
+      SourceLocation &EllipsisLoc, bool InConstantConstext = false);
   void ParseBracketDeclarator(Declarator &D);
   void ParseMisplacedBracketDeclarator(Declarator &D);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D74130: [clang] fix ... Tyker via Phabricator via cfe-commits

Reply via email to