diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 43 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 6 |
8 files changed, 42 insertions, 33 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index d1f87c9df07..c580d1777db 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -309,9 +309,7 @@ unsigned Parser::ParseAttributeArgsCommon( EnterExpressionEvaluationContext Unevaluated( Actions, Uneval ? Sema::ExpressionEvaluationContext::Unevaluated - : Sema::ExpressionEvaluationContext::ConstantEvaluated, - /*LambdaContextDecl=*/nullptr, - /*IsDecltype=*/false); + : Sema::ExpressionEvaluationContext::ConstantEvaluated); ExprResult ArgExpr( Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression())); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index de759c8c945..a969a0f8497 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -942,7 +942,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) { // The operand of the decltype specifier is an unevaluated operand. EnterExpressionEvaluationContext Unevaluated( Actions, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, - /*IsDecltype=*/true); + Sema::ExpressionEvaluationContextRecord::EK_Decltype); Result = Actions.CorrectDelayedTyposInExpr(ParseExpression(), [](Expr *E) { return E->hasPlaceholderType() ? ExprError() : E; diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 107fa556372..8dba6386d0a 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1196,7 +1196,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { { EnterExpressionEvaluationContext PotentiallyDiscarded( Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr, - false, + Sema::ExpressionEvaluationContextRecord::EK_Other, /*ShouldEnter=*/ConstexprCondition && !*ConstexprCondition); ThenStmt = ParseStatement(&InnerStatementTrailingElseLoc); } @@ -1230,7 +1230,7 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) { EnterExpressionEvaluationContext PotentiallyDiscarded( Actions, Sema::ExpressionEvaluationContext::DiscardedStatement, nullptr, - false, + Sema::ExpressionEvaluationContextRecord::EK_Other, /*ShouldEnter=*/ConstexprCondition && *ConstexprCondition); ElseStmt = ParseStatement(); diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 5d47161ff57..f701f4639c2 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1235,7 +1235,9 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { // argument before trying to disambiguate. EnterExpressionEvaluationContext EnterConstantEvaluated( - Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated); + Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated, + /*LambdaContextDecl=*/nullptr, + /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument); if (isCXXTypeId(TypeIdAsTemplateArgument)) { TypeResult TypeArg = ParseTypeName( /*Range=*/nullptr, DeclaratorContext::TemplateArgContext); diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index d6d105c3b04..b26cf3c0432 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -163,7 +163,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, ExprEvalContexts.emplace_back( ExpressionEvaluationContext::PotentiallyEvaluated, 0, CleanupInfo{}, - nullptr, false); + nullptr, ExpressionEvaluationContextRecord::EK_Other); PreallocatedFunctionScope.reset(new FunctionScopeInfo(Diags)); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 820e5a95531..51c1c84c273 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14132,22 +14132,22 @@ ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) { } void -Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, - Decl *LambdaContextDecl, - bool IsDecltype) { +Sema::PushExpressionEvaluationContext( + ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl, + ExpressionEvaluationContextRecord::ExpressionKind ExprContext) { ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup, - LambdaContextDecl, IsDecltype); + LambdaContextDecl, ExprContext); Cleanup.reset(); if (!MaybeODRUseExprs.empty()) std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs); } void -Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, - ReuseLambdaContextDecl_t, - bool IsDecltype) { +Sema::PushExpressionEvaluationContext( + ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t, + ExpressionEvaluationContextRecord::ExpressionKind ExprContext) { Decl *ClosureContextDecl = ExprEvalContexts.back().ManglingContextDecl; - PushExpressionEvaluationContext(NewContext, ClosureContextDecl, IsDecltype); + PushExpressionEvaluationContext(NewContext, ClosureContextDecl, ExprContext); } void Sema::PopExpressionEvaluationContext() { @@ -14155,30 +14155,30 @@ void Sema::PopExpressionEvaluationContext() { unsigned NumTypos = Rec.NumTypos; if (!Rec.Lambdas.empty()) { - if (Rec.isUnevaluated() || Rec.isConstantEvaluated()) { + using ExpressionKind = ExpressionEvaluationContextRecord::ExpressionKind; + if (Rec.ExprContext == ExpressionKind::EK_TemplateArgument || Rec.isUnevaluated() || + (Rec.isConstantEvaluated() && !getLangOpts().CPlusPlus17)) { unsigned D; if (Rec.isUnevaluated()) { // C++11 [expr.prim.lambda]p2: // A lambda-expression shall not appear in an unevaluated operand // (Clause 5). D = diag::err_lambda_unevaluated_operand; - } else { + } else if (Rec.isConstantEvaluated() && !getLangOpts().CPlusPlus17) { // C++1y [expr.const]p2: // A conditional-expression e is a core constant expression unless the // evaluation of e, following the rules of the abstract machine, would // evaluate [...] a lambda-expression. D = diag::err_lambda_in_constant_expression; - } + } else if (Rec.ExprContext == ExpressionKind::EK_TemplateArgument) { + // C++17 [expr.prim.lamda]p2: + // A lambda-expression shall not appear [...] in a template-argument. + D = diag::err_lambda_in_invalid_context; + } else + llvm_unreachable("Couldn't infer lambda error message."); - // C++1z allows lambda expressions as core constant expressions. - // FIXME: In C++1z, reinstate the restrictions on lambda expressions (CWG - // 1607) from appearing within template-arguments and array-bounds that - // are part of function-signatures. Be mindful that P0315 (Lambdas in - // unevaluated contexts) might lift some of these restrictions in a - // future version. - if (!Rec.isConstantEvaluated() || !getLangOpts().CPlusPlus17) - for (const auto *L : Rec.Lambdas) - Diag(L->getLocStart(), D); + for (const auto *L : Rec.Lambdas) + Diag(L->getLocStart(), D); } else { // Mark the capture expressions odr-used. This was deferred // during lambda expression creation. @@ -15637,7 +15637,8 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc, // If we're inside a decltype's expression, don't check for a valid return // type or construct temporaries until we know whether this is the last call. - if (ExprEvalContexts.back().IsDecltype) { + if (ExprEvalContexts.back().ExprContext == + ExpressionEvaluationContextRecord::EK_Decltype) { ExprEvalContexts.back().DelayedDecltypeCalls.push_back(CE); return false; } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8dd9c19bd37..8ed795abbb7 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -6434,7 +6434,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { if (RD->isInvalidDecl() || RD->isDependentContext()) return E; - bool IsDecltype = ExprEvalContexts.back().IsDecltype; + bool IsDecltype = ExprEvalContexts.back().ExprContext == + ExpressionEvaluationContextRecord::EK_Decltype; CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD); if (Destructor) { @@ -6516,7 +6517,9 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) { /// are omitted for the 'topmost' call in the decltype expression. If the /// topmost call bound a temporary, strip that temporary off the expression. ExprResult Sema::ActOnDecltypeExpression(Expr *E) { - assert(ExprEvalContexts.back().IsDecltype && "not in a decltype expression"); + assert(ExprEvalContexts.back().ExprContext == + ExpressionEvaluationContextRecord::EK_Decltype && + "not in a decltype expression"); // C++11 [expr.call]p11: // If a function call is a prvalue of object type, @@ -6558,7 +6561,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { TopBind = nullptr; // Disable the special decltype handling now. - ExprEvalContexts.back().IsDecltype = false; + ExprEvalContexts.back().ExprContext = + ExpressionEvaluationContextRecord::EK_Other; // In MS mode, don't perform any extra checking of call return types within a // decltype expression. diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 66c947abb31..6ee5eca75c9 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3859,6 +3859,10 @@ template<typename Derived> bool TreeTransform<Derived>::TransformTemplateArgument( const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output, bool Uneval) { + EnterExpressionEvaluationContext EEEC( + SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated, + /*LambdaContextDecl=*/nullptr, /*ExprContext=*/ + Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument); const TemplateArgument &Arg = Input.getArgument(); switch (Arg.getKind()) { case TemplateArgument::Null: @@ -5494,7 +5498,7 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, // decltype expressions are not potentially evaluated contexts EnterExpressionEvaluationContext Unevaluated( SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, - /*IsDecltype=*/true); + Sema::ExpressionEvaluationContextRecord::EK_Decltype); ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); if (E.isInvalid()) |