diff options
author | Faisal Vali <faisalv@yahoo.com> | 2016-08-16 02:11:53 +0000 |
---|---|---|
committer | Faisal Vali <faisalv@yahoo.com> | 2016-08-16 02:11:53 +0000 |
commit | f95bed858efd9fa2a63c15a8edf21e84a2560a4d (patch) | |
tree | f262c85250f532cab72362712cd78b2b835e7ef9 | |
parent | 18a55edb0878d9bcb38a90c4ae4ade3f63d8f998 (diff) | |
download | clang-f95bed858efd9fa2a63c15a8edf21e84a2560a4d.tar.gz |
[Branch 3.9] Remove any traces of partial constexpr lambda implementation
This patch essentially reverses all the changes from the following commit: https://reviews.llvm.org/rL264513 for branch 3.9.
Requested by Richard and Approved by Hans here: https://reviews.llvm.org/D23485
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@278771 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticASTKinds.td | 6 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticParseKinds.td | 11 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 18 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 65 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 4 | ||||
-rw-r--r-- | test/Parser/cxx1z-constexpr-lambdas.cpp | 31 | ||||
-rw-r--r-- | test/SemaCXX/cxx1z-constexpr-lambdas.cpp | 36 |
9 files changed, 12 insertions, 183 deletions
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 03ed8aa745..039888ba66 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -158,12 +158,6 @@ def warn_integer_constant_overflow : Warning< "overflow in expression; result is %0 with type %1">, InGroup<DiagGroup<"integer-overflow">>; -// This is a temporary diagnostic, and shall be removed once our -// implementation is complete, and like the preceding constexpr notes belongs -// in Sema. -def note_unimplemented_constexpr_lambda_feature_ast : Note< - "unimplemented constexpr lambda feature: %0 (coming soon!)">; - // inline asm related. let CategoryName = "Inline Assembly Issue" in { def err_asm_invalid_escape : Error< diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index e5c64681e4..45044e6267 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -780,20 +780,11 @@ def warn_cxx98_compat_lambda : Warning< InGroup<CXX98Compat>, DefaultIgnore; def err_lambda_missing_parens : Error< "lambda requires '()' before %select{'mutable'|return type|" - "attribute specifier|'constexpr'}0">; -def err_lambda_decl_specifier_repeated : Error< - "%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">; + "attribute specifier}0">; // C++1z lambda expressions
def err_expected_star_this_capture : Error< "expected 'this' following '*' in lambda capture list">; -// C++1z constexpr lambda expressions -def warn_cxx14_compat_constexpr_on_lambda : Warning< - "constexpr on lambda expressions is incompatible with C++ standards before C++1z">, - InGroup<CXXPre1zCompat>, DefaultIgnore; -def ext_constexpr_on_lambda_cxx1z : ExtWarn< - "'constexpr' on lambda expressions is a C++1z extension">, InGroup<CXX1z>; - // Availability attribute def err_expected_version : Error< "expected a version of the form 'major[.minor[.subminor]]'">; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 25aa805dac..10a8a5ac53 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5111,8 +5111,7 @@ public: SourceRange IntroducerRange, TypeSourceInfo *MethodType, SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params, - bool IsConstexprSpecified); + ArrayRef<ParmVarDecl *> Params); /// \brief Endow the lambda scope info with the relevant properties. void buildLambdaScope(sema::LambdaScopeInfo *LSI, diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index a25a6c7e51..df944e8f25 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -36,7 +36,6 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" -#include "clang/AST/ASTLambda.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Expr.h" #include "clang/AST/RecordLayout.h" @@ -2126,22 +2125,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // If this is a local variable, dig out its value. if (Frame) { Result = Frame->getTemporary(VD); - if (!Result) { - // Assume variables referenced within a lambda's call operator that were - // not declared within the call operator are captures and during checking - // of a potential constant expression, assume they are unknown constant - // expressions. - assert(isLambdaCallOperator(Frame->Callee) && - (VD->getDeclContext() != Frame->Callee || VD->isInitCapture()) && - "missing value for local variable"); - if (Info.checkingPotentialConstantExpression()) - return false; - // FIXME: implement capture evaluation during constant expr evaluation. - Info.FFDiag(E->getLocStart(), - diag::note_unimplemented_constexpr_lambda_feature_ast) - << "captures not currently allowed"; - return false; - } + assert(Result && "missing value for local variable"); return true; } diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index b09d7dbc12..85c1301fc9 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -1053,58 +1053,6 @@ bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { return false; } -static void -tryConsumeMutableOrConstexprToken(Parser &P, SourceLocation &MutableLoc, - SourceLocation &ConstexprLoc, - SourceLocation &DeclEndLoc) { - assert(MutableLoc.isInvalid()); - assert(ConstexprLoc.isInvalid()); - // Consume constexpr-opt mutable-opt in any sequence, and set the DeclEndLoc - // to the final of those locations. Emit an error if we have multiple - // copies of those keywords and recover. - - while (true) { - switch (P.getCurToken().getKind()) { - case tok::kw_mutable: { - if (MutableLoc.isValid()) { - P.Diag(P.getCurToken().getLocation(), - diag::err_lambda_decl_specifier_repeated) - << 0 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); - } - MutableLoc = P.ConsumeToken(); - DeclEndLoc = MutableLoc; - break /*switch*/; - } - case tok::kw_constexpr: - if (ConstexprLoc.isValid()) { - P.Diag(P.getCurToken().getLocation(), - diag::err_lambda_decl_specifier_repeated) - << 1 << FixItHint::CreateRemoval(P.getCurToken().getLocation()); - } - ConstexprLoc = P.ConsumeToken(); - DeclEndLoc = ConstexprLoc; - break /*switch*/; - default: - return; - } - } -} - -static void -addConstexprToLambdaDeclSpecifier(Parser &P, SourceLocation ConstexprLoc, - DeclSpec &DS) { - if (ConstexprLoc.isValid()) { - P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus1z - ? diag::ext_constexpr_on_lambda_cxx1z - : diag::warn_cxx14_compat_constexpr_on_lambda); - const char *PrevSpec = nullptr; - unsigned DiagID = 0; - DS.SetConstexprSpec(ConstexprLoc, PrevSpec, DiagID); - assert(PrevSpec == nullptr && DiagID == 0 && - "Constexpr cannot have been set previously!"); - } -} - /// ParseLambdaExpressionAfterIntroducer - Parse the rest of a lambda /// expression. ExprResult Parser::ParseLambdaExpressionAfterIntroducer( @@ -1163,13 +1111,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( // compatible with MSVC. MaybeParseMicrosoftDeclSpecs(Attr, &DeclEndLoc); - // Parse mutable-opt and/or constexpr-opt, and update the DeclEndLoc. + // Parse 'mutable'[opt]. SourceLocation MutableLoc; - SourceLocation ConstexprLoc; - tryConsumeMutableOrConstexprToken(*this, MutableLoc, ConstexprLoc, - DeclEndLoc); - - addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS); + if (TryConsumeToken(tok::kw_mutable, MutableLoc)) + DeclEndLoc = MutableLoc; // Parse exception-specification[opt]. ExceptionSpecificationType ESpecType = EST_None; @@ -1227,8 +1172,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( LParenLoc, FunLocalRangeEnd, D, TrailingReturnType), Attr, DeclEndLoc); - } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute, - tok::kw_constexpr) || + } else if (Tok.isOneOf(tok::kw_mutable, tok::arrow, tok::kw___attribute) || (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) { // It's common to forget that one needs '()' before 'mutable', an attribute // specifier, or the result type. Deal with this. @@ -1238,7 +1182,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer( case tok::arrow: TokKind = 1; break; case tok::kw___attribute: case tok::l_square: TokKind = 2; break; - case tok::kw_constexpr: TokKind = 3; break; default: llvm_unreachable("Unknown token kind"); } diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 1b8410d7f4..8a2bf929df 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -355,8 +355,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params, - const bool IsConstexprSpecified) { + ArrayRef<ParmVarDecl *> Params) { QualType MethodType = MethodTypeInfo->getType(); TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(getCurLambda(), *this); @@ -393,7 +392,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, MethodType, MethodTypeInfo, SC_None, /*isInline=*/true, - IsConstexprSpecified, + /*isConstExpr=*/false, EndLoc); Method->setAccess(AS_public); @@ -878,9 +877,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, KnownDependent, Intro.Default); - CXXMethodDecl *Method = - startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params, - ParamInfo.getDeclSpec().isConstexprSpecified()); + CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, + MethodTyInfo, EndLoc, Params); if (ExplicitParams) CheckCXXDefaultArguments(Method); @@ -1599,17 +1597,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, CaptureInits, ArrayIndexVars, ArrayIndexStarts, EndLoc, ContainsUnexpandedParameterPack); - // If the lambda expression's call operator is not explicitly marked constexpr - // and we are not in a dependent context, analyze the call operator to infer - // its constexpr-ness, supressing diagnostics while doing so. - if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() && - !CallOperator->isConstexpr() && - !Class->getDeclContext()->isDependentContext()) { - TentativeAnalysisScope DiagnosticScopeGuard(*this); - CallOperator->setConstexpr( - CheckConstexprFunctionDecl(CallOperator) && - CheckConstexprFunctionBody(CallOperator, CallOperator->getBody())); - } if (!CurContext->isDependentContext()) { switch (ExprEvalContexts.back().Context) { diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 36859f61d3..7224eef848 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -10222,9 +10222,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition( Class, E->getIntroducerRange(), NewCallOpTSI, E->getCallOperator()->getLocEnd(), - NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(), - E->getCallOperator()->isConstexpr()); - + NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams()); LSI->CallOperator = NewCallOperator; getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); diff --git a/test/Parser/cxx1z-constexpr-lambdas.cpp b/test/Parser/cxx1z-constexpr-lambdas.cpp deleted file mode 100644 index ea000e361c..0000000000 --- a/test/Parser/cxx1z-constexpr-lambdas.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -std=c++1z %s -verify -// RUN: %clang_cc1 -std=c++14 %s -verify -// RUN: %clang_cc1 -std=c++11 %s -verify - - -auto XL0 = [] constexpr { }; //expected-error{{requires '()'}} expected-error{{expected body}} -auto XL1 = [] () mutable - mutable //expected-error{{cannot appear multiple times}} - mutable { }; //expected-error{{cannot appear multiple times}} - -#if __cplusplus > 201402L -auto XL2 = [] () constexpr mutable constexpr { }; //expected-error{{cannot appear multiple times}} -auto L = []() mutable constexpr { }; -auto L2 = []() constexpr { }; -auto L4 = []() constexpr mutable { }; -auto XL16 = [] () constexpr - mutable - constexpr //expected-error{{cannot appear multiple times}} - mutable //expected-error{{cannot appear multiple times}} - mutable //expected-error{{cannot appear multiple times}} - constexpr //expected-error{{cannot appear multiple times}} - constexpr //expected-error{{cannot appear multiple times}} - { }; - -#else -auto L = []() mutable constexpr {return 0; }; //expected-warning{{is a C++1z extension}} -auto L2 = []() constexpr { return 0;};//expected-warning{{is a C++1z extension}} -auto L4 = []() constexpr mutable { return 0; }; //expected-warning{{is a C++1z extension}} -#endif - - diff --git a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/test/SemaCXX/cxx1z-constexpr-lambdas.cpp deleted file mode 100644 index 8e7657fb6e..0000000000 --- a/test/SemaCXX/cxx1z-constexpr-lambdas.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks %s -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fms-extensions %s -// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s - -namespace test_constexpr_checking { - -namespace ns1 { - struct NonLit { ~NonLit(); }; //expected-note{{not literal}} - auto L = [](NonLit NL) constexpr { }; //expected-error{{not a literal type}} -} // end ns1 - -namespace ns2 { - auto L = [](int I) constexpr { asm("non-constexpr"); }; //expected-error{{not allowed in constexpr function}} -} // end ns1 - -} // end ns test_constexpr_checking - -namespace test_constexpr_call { - -namespace ns1 { - auto L = [](int I) { return I; }; - static_assert(L(3) == 3); -} // end ns1 -namespace ns2 { - auto L = [](auto a) { return a; }; - static_assert(L(3) == 3); - static_assert(L(3.14) == 3.14); -} -namespace ns3 { - auto L = [](auto a) { asm("non-constexpr"); return a; }; //expected-note{{declared here}} - constexpr int I = //expected-error{{must be initialized by a constant expression}} - L(3); //expected-note{{non-constexpr function}} -} - -} // end ns test_constexpr_call
\ No newline at end of file |