[llvm-branch-commits] [clang] 57f70e3 - [Concepts] Fix ConceptSpecializationExpr profiling crash
Author: Saar Raz Date: 2020-01-24T02:28:20+02:00 New Revision: 57f70e387e362d988937b6627461d781ecf09e50 URL: https://github.com/llvm/llvm-project/commit/57f70e387e362d988937b6627461d781ecf09e50 DIFF: https://github.com/llvm/llvm-project/commit/57f70e387e362d988937b6627461d781ecf09e50.diff LOG: [Concepts] Fix ConceptSpecializationExpr profiling crash ConceptSpecializationExprs (CSEs) were being created with nullptr TemplateArgsAsWritten during TemplateTemplateParmDecl canonicalization, and we were relying on them during profiling which caused sporadic crashes in test/CXX/.../temp.arg.template/p3-2a.cpp introduced in D44352. Change profiling of CSEs to instead rely on the actual converted template arguments and concept named. (cherry picked from commit 8a3446746098ba29348bb8f85357dd0b466a6d6e) Added: Modified: clang/lib/AST/StmtProfile.cpp Removed: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 2aa5106e90fa..c0b0f3b0b064 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1335,9 +1335,9 @@ void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) { void StmtProfiler::VisitConceptSpecializationExpr( const ConceptSpecializationExpr *S) { VisitExpr(S); - VisitDecl(S->getFoundDecl()); - VisitTemplateArguments(S->getTemplateArgsAsWritten()->getTemplateArgs(), - S->getTemplateArgsAsWritten()->NumTemplateArgs); + VisitDecl(S->getNamedConcept()); + for (const TemplateArgument &Arg : S->getTemplateArguments()) +VisitTemplateArgument(Arg); } static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S, ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] ab514b9 - Remove redundant CXXScopeSpec from TemplateIdAnnotation.
Author: Richard Smith Date: 2020-01-24T02:28:20+02:00 New Revision: ab514b91196345ba4c61026e4997871e85ddd97d URL: https://github.com/llvm/llvm-project/commit/ab514b91196345ba4c61026e4997871e85ddd97d DIFF: https://github.com/llvm/llvm-project/commit/ab514b91196345ba4c61026e4997871e85ddd97d.diff LOG: Remove redundant CXXScopeSpec from TemplateIdAnnotation. A TemplateIdAnnotation represents only a template-id, not a nested-name-specifier plus a template-id. Don't make a redundant copy of the CXXScopeSpec and store it on the template-id annotation. This slightly improves error recovery by more properly handling the case where we would form an invalid CXXScopeSpec while parsing a typename specifier, instead of accidentally putting the token stream into a broken "annot_template_id with a scope specifier, but with no preceding annot_cxxscope token" state. (cherry picked from commit a42fd84cff265b7e9faa3fe42885ee171393e4db) Added: Modified: clang/include/clang/Parse/Parser.h clang/include/clang/Sema/ParsedTemplate.h clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseDecl.cpp clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Parse/ParseExprCXX.cpp clang/lib/Parse/ParseTemplate.cpp clang/lib/Parse/ParseTentative.cpp clang/lib/Parse/Parser.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp clang/test/Parser/cxx-decl.cpp clang/test/SemaTemplate/ms-delayed-default-template-args.cpp clang/test/SemaTemplate/rdar9173693.cpp Removed: diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index b7bed4713992..182024ea5108 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3079,13 +3079,13 @@ class Parser : public CodeCompletionHandler { SourceLocation &RAngleLoc); bool ParseTemplateParameterList(unsigned Depth, SmallVectorImpl &TemplateParams); - bool isStartOfTemplateTypeParameter(bool &ScopeError); + TPResult isStartOfTemplateTypeParameter(); NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position); NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position); NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); bool isTypeConstraintAnnotation(); - bool TryAnnotateTypeConstraint(CXXScopeSpec &SS); + bool TryAnnotateTypeConstraint(); NamedDecl * ParseConstrainedTemplateTypeParameter(unsigned Depth, unsigned Position); void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc, @@ -3111,7 +3111,8 @@ class Parser : public CodeCompletionHandler { UnqualifiedId &TemplateName, bool AllowTypeAnnotation = true, bool TypeConstraint = false); - void AnnotateTemplateIdTokenAsType(bool IsClassName = false); + void AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS, + bool IsClassName = false); bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); diff --git a/clang/include/clang/Sema/ParsedTemplate.h b/clang/include/clang/Sema/ParsedTemplate.h index 0874905b38a5..82d00494b0d6 100644 --- a/clang/include/clang/Sema/ParsedTemplate.h +++ b/clang/include/clang/Sema/ParsedTemplate.h @@ -139,9 +139,8 @@ namespace clang { /// Information about a template-id annotation /// token. /// - /// A template-id annotation token contains the template declaration, - /// template arguments, whether those template arguments were types, - /// expressions, or template names, and the source locations for important + /// A template-id annotation token contains the template name, + /// template arguments, and the source locations for important /// tokens. All of the information about template arguments is allocated /// directly after this structure. /// A template-id annotation token can also be generated by a type-constraint @@ -152,9 +151,6 @@ namespace clang { : private llvm::TrailingObjects { friend TrailingObjects; -/// The nested-name-specifier that precedes the template name. -CXXScopeSpec SS; - /// TemplateKWLoc - The location of the template keyword. /// For e.g. typename T::template Y SourceLocation TemplateKWLoc; @@ -195,16 +191,15 @@ namespace clang { /// Creates a new TemplateIdAnnotation with NumArgs arguments and /// appends it to List. static TemplateIdAnnotation * -Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc, - SourceLocation TemplateNameLoc, Id
[llvm-branch-commits] [clang] c21e178 - [Concepts] Transform constraints of non-template functions to ConstantEvaluated
Author: Saar Raz Date: 2020-01-25T23:10:40+02:00 New Revision: c21e178bf22b6b46f087e6aab02a34d11dd98432 URL: https://github.com/llvm/llvm-project/commit/c21e178bf22b6b46f087e6aab02a34d11dd98432 DIFF: https://github.com/llvm/llvm-project/commit/c21e178bf22b6b46f087e6aab02a34d11dd98432.diff LOG: [Concepts] Transform constraints of non-template functions to ConstantEvaluated We would previously try to evaluate atomic constraints of non-template functions as-is, and since they are now unevaluated at first, this would cause incorrect evaluation (bugs #44657, #44656). Substitute into atomic constraints of non-template functions as we would atomic constraints of template functions, in order to rebuild the expressions in a constant-evaluated context. (cherry picked from commit 713562f54858f10bf8998ee21ff2c7e7bad0d177) Added: Modified: clang/include/clang/AST/ASTConcept.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/AST/ASTConcept.cpp clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaTemplate/cxx2a-constraint-exprs.cpp Removed: diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h index 30c4706d2a15..3ebaad4eafdd 100644 --- a/clang/include/clang/AST/ASTConcept.h +++ b/clang/include/clang/AST/ASTConcept.h @@ -29,14 +29,14 @@ class ConceptSpecializationExpr; class ConstraintSatisfaction : public llvm::FoldingSetNode { // The template-like entity that 'owns' the constraint checked here (can be a // constrained entity or a concept). - NamedDecl *ConstraintOwner = nullptr; + const NamedDecl *ConstraintOwner = nullptr; llvm::SmallVector TemplateArgs; public: ConstraintSatisfaction() = default; - ConstraintSatisfaction(NamedDecl *ConstraintOwner, + ConstraintSatisfaction(const NamedDecl *ConstraintOwner, ArrayRef TemplateArgs) : ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(), TemplateArgs.end()) { } @@ -57,7 +57,7 @@ class ConstraintSatisfaction : public llvm::FoldingSetNode { } static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C, - NamedDecl *ConstraintOwner, + const NamedDecl *ConstraintOwner, ArrayRef TemplateArgs); }; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7636d04a34c3..b7b8c5f17c41 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4683,6 +4683,8 @@ def note_checking_constraints_for_var_spec_id_here : Note< def note_checking_constraints_for_class_spec_id_here : Note< "while checking constraint satisfaction for class template partial " "specialization '%0' required here">; +def note_checking_constraints_for_function_here : Note< + "while checking constraint satisfaction for function '%0' required here">; def note_constraint_substitution_here : Note< "while substituting template arguments into constraint expression here">; def note_constraint_normalization_here : Note< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index a88dd2814487..72d49c119e8a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6275,7 +6275,7 @@ class Sema final { /// \returns true if an error occurred and satisfaction could not be checked, /// false otherwise. bool CheckConstraintSatisfaction( - NamedDecl *Template, ArrayRef ConstraintExprs, + const NamedDecl *Template, ArrayRef ConstraintExprs, ArrayRef TemplateArgs, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); @@ -6288,6 +6288,17 @@ class Sema final { bool CheckConstraintSatisfaction(const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction); + /// Check whether the given function decl's trailing requires clause is + /// satisfied, if any. Returns false and updates Satisfaction with the + /// satisfaction verdict if successful, emits a diagnostic and returns true if + /// an error occured and satisfaction could not be determined. + /// + /// \returns true if an error occurred, false otherwise. + bool CheckFunctionConstraints(const FunctionDecl *FD, +ConstraintSatisfaction &Satisfaction, +SourceLocation UsageLoc = SourceLocation()); + + /// \brief Ensure that the given template arguments satisfy the constraints /// associated with the given template, emitting a diagnostic if they do not. /// diff --git
[llvm-branch-commits] [clang] 73a9147 - [Concepts] Fix parsing of scope specifier in compound-requirements, add more tests for scope specifiers in type-constraints
Author: Saar Raz Date: 2020-01-26T20:49:23+02:00 New Revision: 73a91477f7045d1325570f28e349dd87d9bff49c URL: https://github.com/llvm/llvm-project/commit/73a91477f7045d1325570f28e349dd87d9bff49c DIFF: https://github.com/llvm/llvm-project/commit/73a91477f7045d1325570f28e349dd87d9bff49c.diff LOG: [Concepts] Fix parsing of scope specifier in compound-requirements, add more tests for scope specifiers in type-constraints The code for parsing of type-constraints in compound-requirements was not adapted for the new TryAnnotateTypeConstraint which caused compound-requirements with scope specifiers to ignore them. Also add regression tests for scope specifiers in type-constraints in more contexts. (cherry picked from commit 5043962dd3150c6ac72b75174b9460a510d1b5c3) Added: clang/test/Parser/cxx2a-abbreviated-templates.cpp Modified: clang/lib/Parse/ParseExprCXX.cpp clang/test/Parser/cxx2a-concepts-requires-expr.cpp clang/test/Parser/cxx2a-placeholder-type-constraint.cpp Removed: diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 036eabb94dd7..9f94e0dde3bd 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -3374,25 +3374,6 @@ ExprResult Parser::ParseRequiresExpression() { Diag(Tok, diag::err_requires_expr_missing_arrow) << FixItHint::CreateInsertion(Tok.getLocation(), "->"); // Try to parse a 'type-constraint' -CXXScopeSpec SS; -if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), - /*EnteringContext=*/false, - /*MayBePseudoDestructor=*/nullptr, - // If this is not a type-constraint, - // then this scope-spec is part of - // the typename of a non-type - // template parameter - /*IsTypename=*/true, - /*LastII=*/nullptr, - // We won't find concepts in - // non-namespaces anyway, so might as - // well parse this correctly for - // possible type names. - /*OnlyNamespace=*/false, - /*SuppressDiagnostic=*/true)) { - SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); - break; -} if (TryAnnotateTypeConstraint()) { SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); break; @@ -3402,8 +3383,13 @@ ExprResult Parser::ParseRequiresExpression() { SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); break; } -if (Tok.is(tok::annot_cxxscope)) +CXXScopeSpec SS; +if (Tok.is(tok::annot_cxxscope)) { + Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), + Tok.getAnnotationRange(), + SS); ConsumeAnnotationToken(); +} Req = Actions.ActOnCompoundRequirement( Expression.get(), NoexceptLoc, SS, takeTemplateIdAnnotation(Tok), diff --git a/clang/test/Parser/cxx2a-abbreviated-templates.cpp b/clang/test/Parser/cxx2a-abbreviated-templates.cpp new file mode 100644 index ..e2b3803c807e --- /dev/null +++ b/clang/test/Parser/cxx2a-abbreviated-templates.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify +// expected-no-diagnostics + +template +concept C = true; + +namespace ns { + template + concept D = true; +} + +void foo(C auto a, + C auto b, + ns::D auto c, + ns::D auto d, + const C auto e, + const C auto f, + const ns::D auto g, + const ns::D auto h); \ No newline at end of file diff --git a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp index 6b4a5d62b407..fa42b0633850 100644 --- a/clang/test/Parser/cxx2a-concepts-requires-expr.cpp +++ b/clang/test/Parser/cxx2a-concepts-requires-expr.cpp @@ -108,34 +108,38 @@ bool r29 = requires { { 0 } noexcept C1; }; bool r30 = requires { { 0 } noexcept -> C2; }; +namespace ns { template concept C = true; } + +bool r31 = requires { { 0 } noexcept -> ns::C; }; + template T i1 = 0; -bool r31 = requires { requires false, 1; }; +bool r32 = requires { requires false, 1; }; // expected-error@-1 {{expected ';' at end of requirement}} -bool r32 = requires { 0 noexcept; }; +bool r33 = requires { 0 noexce
[llvm-branch-commits] [clang] b07b827 - [Concepts] Add missing null check to transformConstructor
Author: Saar Raz Date: 2020-01-27T00:16:19+02:00 New Revision: b07b82777b9ad19c44c6eb347507f1fdda3ddf34 URL: https://github.com/llvm/llvm-project/commit/b07b82777b9ad19c44c6eb347507f1fdda3ddf34 DIFF: https://github.com/llvm/llvm-project/commit/b07b82777b9ad19c44c6eb347507f1fdda3ddf34.diff LOG: [Concepts] Add missing null check to transformConstructor Caused bug 44671 when transforming a constructor with a type-constraint with no explicit template args. (cherry picked from commit a8d096aff6b1930ad57bd0c30077d2b4920b5025) Added: Modified: clang/lib/Sema/SemaTemplate.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index f961244da072..ad4ea2d2593d 100755 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -2047,12 +2047,14 @@ struct ConvertConstructorToDeductionGuideTransform { if (const auto *TC = TTP->getTypeConstraint()) { TemplateArgumentListInfo TransformedArgs; const auto *ArgsAsWritten = TC->getTemplateArgsAsWritten(); -if (SemaRef.Subst(ArgsAsWritten->getTemplateArgs(), +if (!ArgsAsWritten || +SemaRef.Subst(ArgsAsWritten->getTemplateArgs(), ArgsAsWritten->NumTemplateArgs, TransformedArgs, Args)) SemaRef.AttachTypeConstraint( TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(), - TC->getNamedConcept(), &TransformedArgs, NewTTP, + TC->getNamedConcept(), ArgsAsWritten ? &TransformedArgs : nullptr, + NewTTP, NewTTP->isParameterPack() ? cast(TC->getImmediatelyDeclaredConstraint()) ->getEllipsisLoc() ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] b39efdb - [Concepts] Fix incorrect TemplateArgs for introduction of local parameters
Author: Saar Raz Date: 2020-01-27T01:00:12+02:00 New Revision: b39efdbcfcb7c7a5e867a99c2d3e756c538fbb9f URL: https://github.com/llvm/llvm-project/commit/b39efdbcfcb7c7a5e867a99c2d3e756c538fbb9f DIFF: https://github.com/llvm/llvm-project/commit/b39efdbcfcb7c7a5e867a99c2d3e756c538fbb9f.diff LOG: [Concepts] Fix incorrect TemplateArgs for introduction of local parameters The wrong set of TemplateArgs was being provided to addInstantiatedParametersToScope. Caused bug #44658. (cherry picked from commit 9c24fca2a33fc0fd059e278bb95c84803dfff9ae) Added: Modified: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/SemaTemplate/instantiate-requires-clause.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index fbbab8f00703..2e437cbe44d3 100755 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4246,18 +4246,17 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( Sema::ContextRAII savedContext(*this, Decl); LocalInstantiationScope Scope(*this); - MultiLevelTemplateArgumentList MLTAL = -getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true); - // If this is not an explicit specialization - we need to get the instantiated // version of the template arguments and add them to scope for the // substitution. if (Decl->isTemplateInstantiation()) { InstantiatingTemplate Inst(*this, Decl->getPointOfInstantiation(), InstantiatingTemplate::ConstraintsCheck{}, Decl->getPrimaryTemplate(), -MLTAL.getInnermost(), SourceRange()); +TemplateArgs, SourceRange()); if (Inst.isInvalid()) return true; +MultiLevelTemplateArgumentList MLTAL( +*Decl->getTemplateSpecializationArgs()); if (addInstantiatedParametersToScope( *this, Decl, Decl->getPrimaryTemplate()->getTemplatedDecl(), Scope, MLTAL)) diff --git a/clang/test/SemaTemplate/instantiate-requires-clause.cpp b/clang/test/SemaTemplate/instantiate-requires-clause.cpp index 31cf484d564c..8e9d5bffa906 100644 --- a/clang/test/SemaTemplate/instantiate-requires-clause.cpp +++ b/clang/test/SemaTemplate/instantiate-requires-clause.cpp @@ -51,3 +51,10 @@ struct S2 { static_assert((S2::f(), true)); +template +struct S3 { + template requires true + static constexpr void f(Args...) { } +}; + +static_assert((S3::f(), true)); \ No newline at end of file ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 6c6ea59 - [Concepts] Add check for dependent RC when checking function constraints
Author: Saar Raz Date: 2020-01-30T20:54:12+02:00 New Revision: 6c6ea5995f261f0baa2be8a216ad08186551c622 URL: https://github.com/llvm/llvm-project/commit/6c6ea5995f261f0baa2be8a216ad08186551c622 DIFF: https://github.com/llvm/llvm-project/commit/6c6ea5995f261f0baa2be8a216ad08186551c622.diff LOG: [Concepts] Add check for dependent RC when checking function constraints Do not attempt to check a dependent requires clause in a function constraint (may be triggered by, for example, DiagnoseUseOfDecl). (cherry picked from commit a424ef99e7b9821ec80564af3d3a8f091323a38c) Added: Modified: clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaExpr.cpp Removed: diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index e5c0fa28c11f..8fdc6023040f 100755 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -325,9 +325,10 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, ConstraintSatisfaction &Satisfaction, SourceLocation UsageLoc) { const Expr *RC = FD->getTrailingRequiresClause(); - assert(!RC->isInstantiationDependent() && - "CheckFunctionConstraints can only be used with functions with " - "non-dependent constraints"); + if (RC->isInstantiationDependent()) { +Satisfaction.IsSatisfied = true; +return false; + } // We substitute with empty arguments in order to rebuild the atomic // constraint in a constant-evaluated context. // FIXME: Should this be a dedicated TreeTransform? diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4f777e7b981b..2a8302e9d227 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -333,11 +333,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, // // See if this is a function with constraints that need to be satisfied. if (FunctionDecl *FD = dyn_cast(D)) { -if (Expr *RC = FD->getTrailingRequiresClause()) { +if (FD->getTrailingRequiresClause()) { ConstraintSatisfaction Satisfaction; - bool Failed = CheckConstraintSatisfaction(FD, {RC}, /*TemplateArgs=*/{}, -SourceRange(Loc), Satisfaction); - if (Failed) + if (CheckFunctionConstraints(FD, Satisfaction, Loc)) // A diagnostic will have already been generated (non-constant // constraint expression, for example) return true; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] a360935 - [Concept] Fix incorrect check for containsUnexpandedParameterPack in CSE
Author: Saar Raz Date: 2020-01-30T20:54:02+02:00 New Revision: a3609357f3888685f5d864d5708421b0993650b8 URL: https://github.com/llvm/llvm-project/commit/a3609357f3888685f5d864d5708421b0993650b8 DIFF: https://github.com/llvm/llvm-project/commit/a3609357f3888685f5d864d5708421b0993650b8.diff LOG: [Concept] Fix incorrect check for containsUnexpandedParameterPack in CSE We previously checked for containsUnexpandedParameterPack in CSEs by observing the property in the converted arguments of the CSE. This may not work if the argument is an expanded type-alias that contains a pack-expansion (see added test). Check the as-written arguments when determining containsUnexpandedParameterPack and isInstantiationDependent. (cherry picked from commit c83d9bedc0cc430dc620e7a807daeb985d390325) Added: Modified: clang/include/clang/AST/ExprConcepts.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ExprConcepts.cpp clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp Removed: diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h index 2a64326e8604..271d487e2fc9 100644 --- a/clang/include/clang/AST/ExprConcepts.h +++ b/clang/include/clang/AST/ExprConcepts.h @@ -63,6 +63,12 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference, ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction); + ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept, +ArrayRef ConvertedArgs, +const ConstraintSatisfaction *Satisfaction, +bool Dependent, +bool ContainsUnexpandedParameterPack); + ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs); public: @@ -75,6 +81,13 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference, ArrayRef ConvertedArgs, const ConstraintSatisfaction *Satisfaction); + static ConceptSpecializationExpr * + Create(const ASTContext &C, ConceptDecl *NamedConcept, + ArrayRef ConvertedArgs, + const ConstraintSatisfaction *Satisfaction, + bool Dependent, + bool ContainsUnexpandedParameterPack); + static ConceptSpecializationExpr * Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6d1db38e36cc..1be72efe4de8 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -756,12 +756,8 @@ canonicalizeImmediatelyDeclaredConstraint(const ASTContext &C, Expr *IDC, NewConverted.push_back(Arg); } Expr *NewIDC = ConceptSpecializationExpr::Create( - C, NestedNameSpecifierLoc(), /*TemplateKWLoc=*/SourceLocation(), - CSE->getConceptNameInfo(), /*FoundDecl=*/CSE->getNamedConcept(), - CSE->getNamedConcept(), - // Actually canonicalizing a TemplateArgumentLoc is diff icult so we - // simply omit the ArgsAsWritten - /*ArgsAsWritten=*/nullptr, NewConverted, nullptr); + C, CSE->getNamedConcept(), NewConverted, nullptr, + CSE->isInstantiationDependent(), CSE->containsUnexpandedParameterPack()); if (auto *OrigFold = dyn_cast(IDC)) NewIDC = new (C) CXXFoldExpr(OrigFold->getType(), SourceLocation(), NewIDC, diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp index 76d57ed5d5b1..b5a3686dc99a 100644 --- a/clang/lib/AST/ExprConcepts.cpp +++ b/clang/lib/AST/ExprConcepts.cpp @@ -46,24 +46,12 @@ ConceptSpecializationExpr::ConceptSpecializationExpr(const ASTContext &C, ASTConstraintSatisfaction::Create(C, *Satisfaction) : nullptr) { setTemplateArguments(ConvertedArgs); -} - -ConceptSpecializationExpr::ConceptSpecializationExpr(EmptyShell Empty, -unsigned NumTemplateArgs) -: Expr(ConceptSpecializationExprClass, Empty), ConceptReference(), - NumTemplateArgs(NumTemplateArgs) { } - -void ConceptSpecializationExpr::setTemplateArguments( -ArrayRef Converted) { - assert(Converted.size() == NumTemplateArgs); - std::uninitialized_copy(Converted.begin(), Converted.end(), - getTrailingObjects()); bool IsInstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; - for (const TemplateArgument& Arg : Converted) { -if (Arg.isInstantiationDependent()) + for (const TemplateArgumentLoc& ArgLoc : ArgsAsWritten->arguments()) { +if (ArgLoc.getArgument().isInstantiationDependent()) IsInstantiationDependent = true; -if (Arg.containsUnexpandedParameterPack()) +if (ArgLoc.getArgument().containsUnexpandedParameterPack()) ContainsUnexpandedParameterPack = true; if (ContainsUnexpandedParameterPack && IsInstantiationDependent) break; @@ -80,6 +
[llvm-branch-commits] [clang] cc85862 - [Concepts] Check function constraints before deducing auto return type
Author: Saar Raz Date: 2020-01-31T03:52:53+02:00 New Revision: cc85862c60a566332389bff6abad26e100cede6c URL: https://github.com/llvm/llvm-project/commit/cc85862c60a566332389bff6abad26e100cede6c DIFF: https://github.com/llvm/llvm-project/commit/cc85862c60a566332389bff6abad26e100cede6c.diff LOG: [Concepts] Check function constraints before deducing auto return type A constrained function with an auto return type would have it's definition instantiated in order to deduce the auto return type before the constraints are checked. Move the constraints check after the return type deduction. (cherry picked from commit 980517b3530ffb7faa1a23fdc007d78f5b45ae3c) Added: Modified: clang/lib/Sema/SemaExpr.cpp clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp Removed: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2a8302e9d227..29562615e588 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -245,8 +245,8 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, return true; } - // See if this is a deleted function. if (FunctionDecl *FD = dyn_cast(D)) { +// See if this is a deleted function. if (FD->isDeleted()) { auto *Ctor = dyn_cast(FD); if (Ctor && Ctor->isInheritingConstructor()) @@ -259,6 +259,29 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, return true; } +// [expr.prim.id]p4 +// A program that refers explicitly or implicitly to a function with a +// trailing requires-clause whose constraint-expression is not satisfied, +// other than to declare it, is ill-formed. [...] +// +// See if this is a function with constraints that need to be satisfied. +// Check this before deducing the return type, as it might instantiate the +// definition. +if (FD->getTrailingRequiresClause()) { + ConstraintSatisfaction Satisfaction; + if (CheckFunctionConstraints(FD, Satisfaction, Loc)) +// A diagnostic will have already been generated (non-constant +// constraint expression, for example) +return true; + if (!Satisfaction.IsSatisfied) { +Diag(Loc, + diag::err_reference_to_function_with_unsatisfied_constraints) +<< D; +DiagnoseUnsatisfiedConstraint(Satisfaction); +return true; + } +} + // If the function has a deduced return type, and we can't deduce it, // then we can't use it either. if (getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && @@ -326,29 +349,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, diagnoseUseOfInternalDeclInInlineFunction(*this, D, Loc); - // [expr.prim.id]p4 - // A program that refers explicitly or implicitly to a function with a - // trailing requires-clause whose constraint-expression is not satisfied, - // other than to declare it, is ill-formed. [...] - // - // See if this is a function with constraints that need to be satisfied. - if (FunctionDecl *FD = dyn_cast(D)) { -if (FD->getTrailingRequiresClause()) { - ConstraintSatisfaction Satisfaction; - if (CheckFunctionConstraints(FD, Satisfaction, Loc)) -// A diagnostic will have already been generated (non-constant -// constraint expression, for example) -return true; - if (!Satisfaction.IsSatisfied) { -Diag(Loc, - diag::err_reference_to_function_with_unsatisfied_constraints) -<< D; -DiagnoseUnsatisfiedConstraint(Satisfaction); -return true; - } -} - } - if (isa(D) && isa(D->getDeclContext()) && !isUnevaluatedContext()) { // C++ [expr.prim.req.nested] p3 diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp index f4c38c73d255..d3dde10ff2b2 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp @@ -26,11 +26,14 @@ namespace methods struct A { static void foo(int) requires (sizeof(T) == 1) {} // expected-note 3{{because 'sizeof(char [2]) == 1' (2 == 1) evaluated to false}} static void bar(int) requires (sizeof(T) == 2) {} // expected-note 3{{because 'sizeof(char) == 2' (1 == 2) evaluated to false}} +// Make sure the function body is not instantiated before constraints are checked. +static auto baz(int) requires (sizeof(T) == 2) { return T::foo(); } // expected-note{{because 'sizeof(char) == 2' (1 == 2) evaluated to false}} }; void baz() { A::foo(1); A::bar(1); // expected-error{{invalid reference to function 'bar': constraints not satisfied}} +A::baz(1); // expected-error{{invalid reference to function 'baz': constraints not satisfied}} A::foo(1); // expected-error{{invalid reference to function 'foo': constraints not satisfi
[llvm-branch-commits] [clang] 3b32963 - [Concepts] Correctly form initial parameter mapping for parameter packs, support substitution into SubstNonTypeTemplateParmExpr
Author: Saar Raz Date: 2020-01-31T16:00:41+02:00 New Revision: 3b32963252bc8580ad8237ded3814e2a6a2ba9b6 URL: https://github.com/llvm/llvm-project/commit/3b32963252bc8580ad8237ded3814e2a6a2ba9b6 DIFF: https://github.com/llvm/llvm-project/commit/3b32963252bc8580ad8237ded3814e2a6a2ba9b6.diff LOG: [Concepts] Correctly form initial parameter mapping for parameter packs, support substitution into SubstNonTypeTemplateParmExpr We previously would not correctly for the initial parameter mapping for variadic template parameters in Concepts. Testing this lead to the discovery that with the normalization process we would need to substitute into already-substituted-into template arguments, which means we need to add NonTypeTemplateParmExpr support to TemplateInstantiator. We do that by substituting into the replacement and the type separately, and then re-checking the expression against the NTTP with the new type, in order to form any new required implicit casts (for cases where the type of the NTTP was dependent). (cherry picked from commit ba1f3db4b0729ad932aa4f091e9578132d98a0c8) Added: clang/test/SemaTemplate/instantiate-template-argument.cpp Modified: clang/include/clang/Sema/Sema.h clang/include/clang/Sema/SemaConcept.h clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp Removed: diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 72d49c119e8a..697d1911be8f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6997,7 +6997,7 @@ class Sema final { /// Get a template argument mapping the given template parameter to itself, /// e.g. for X in \c template, this would return an expression template /// argument referencing X. - TemplateArgumentLoc getIdentityTemplateArgumentLoc(Decl *Param, + TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location); void translateTemplateArguments(const ASTTemplateArgsPtr &In, diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h index 7fc42a4816ec..c5f9fc45612a 100644 --- a/clang/include/clang/Sema/SemaConcept.h +++ b/clang/include/clang/Sema/SemaConcept.h @@ -43,11 +43,15 @@ struct AtomicConstraint { if (ParameterMapping->size() != Other.ParameterMapping->size()) return false; -for (unsigned I = 0, S = ParameterMapping->size(); I < S; ++I) - if (!C.getCanonicalTemplateArgument((*ParameterMapping)[I].getArgument()) - .structurallyEquals(C.getCanonicalTemplateArgument( - (*Other.ParameterMapping)[I].getArgument( +for (unsigned I = 0, S = ParameterMapping->size(); I < S; ++I) { + llvm::FoldingSetNodeID IDA, IDB; + C.getCanonicalTemplateArgument((*ParameterMapping)[I].getArgument()) + .Profile(IDA, C); + C.getCanonicalTemplateArgument((*Other.ParameterMapping)[I].getArgument()) + .Profile(IDB, C); + if (IDA != IDB) return false; +} return true; } diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 8fdc6023040f..39169664dad5 100755 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -676,6 +676,10 @@ static bool substituteParameterMappings(Sema &S, NormalizedConstraint &N, ArgsAsWritten->arguments().back().getSourceRange().getEnd())); if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs)) return true; + Atomic.ParameterMapping.emplace( +MutableArrayRef( +new (S.Context) TemplateArgumentLoc[SubstArgs.size()], +SubstArgs.size())); std::copy(SubstArgs.arguments().begin(), SubstArgs.arguments().end(), N.getAtomicConstraint()->ParameterMapping->begin()); return false; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 394c81c82794..1a71f270679d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2488,7 +2488,7 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: { NestedNameSpecifierLocBuilder Builder; - TemplateName Template = Arg.getAsTemplate(); + TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) Builder.MakeTrivial(Context, DTN->getQualifier(), Loc); else if (QualifiedTemplateName *QTN = @@ -2514,27 +2514,10 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, } TemplateArgumentLoc -Sema::getIdentityTemp
[llvm-branch-commits] [clang] 8be1162 - [Concepts] Fix isDeclarationSpecifier to detect type-constraints correctly
Author: Saar Raz Date: 2020-01-31T20:10:43+02:00 New Revision: 8be11623043c54cc42d7d0a7fac7408efce4ef41 URL: https://github.com/llvm/llvm-project/commit/8be11623043c54cc42d7d0a7fac7408efce4ef41 DIFF: https://github.com/llvm/llvm-project/commit/8be11623043c54cc42d7d0a7fac7408efce4ef41.diff LOG: [Concepts] Fix isDeclarationSpecifier to detect type-constraints correctly isDeclarationSpecifiers did not handle some cases of placeholder-type-specifiers with type-constraints, causing parsing bugs in abbreviated constructor templates. Add comprehensive handling of type-constraints to isDeclarationSpecifier. (cherry picked from commit b7ce85a130789d23c69156f4b899962458d1f05d) Added: Modified: clang/lib/Parse/ParseDecl.cpp clang/test/Parser/cxx2a-abbreviated-templates.cpp Removed: diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 4af993c4527f..cdc3506d5c68 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5060,6 +5060,8 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) return true; +if (TryAnnotateTypeConstraint()) + return true; if (Tok.is(tok::identifier)) return false; @@ -5192,11 +5194,14 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { // placeholder-type-specifier case tok::annot_template_id: { -TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); -return TemplateId->Kind == TNK_Concept_template && +return isTypeConstraintAnnotation() && (NextToken().is(tok::kw_auto) || NextToken().is(tok::kw_decltype)); } - + case tok::annot_cxxscope: +if (NextToken().is(tok::identifier) && TryAnnotateTypeConstraint()) + return true; +return isTypeConstraintAnnotation() && +GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype); case tok::kw___declspec: case tok::kw___cdecl: case tok::kw___stdcall: diff --git a/clang/test/Parser/cxx2a-abbreviated-templates.cpp b/clang/test/Parser/cxx2a-abbreviated-templates.cpp index e2b3803c807e..6562389f7676 100644 --- a/clang/test/Parser/cxx2a-abbreviated-templates.cpp +++ b/clang/test/Parser/cxx2a-abbreviated-templates.cpp @@ -9,11 +9,36 @@ namespace ns { concept D = true; } -void foo(C auto a, - C auto b, - ns::D auto c, - ns::D auto d, - const C auto e, - const C auto f, - const ns::D auto g, - const ns::D auto h); \ No newline at end of file +void foo1(C auto a, + C auto b, + ns::D auto c, + ns::D auto d, + const C auto e, + const C auto f, + const ns::D auto g, + const ns::D auto h); +void foo2(C auto a); +void foo3(C auto b); +void foo4(ns::D auto c); +void foo5(ns::D auto d); +void foo6(const C auto e); +void foo7(const C auto f); +void foo8(const ns::D auto g); +void foo9(const ns::D auto h); + +struct S1 { S1(C auto a, + C auto b, + ns::D auto c, + ns::D auto d, + const C auto e, + const C auto f, + const ns::D auto g, + const ns::D auto h); }; +struct S2 { S2(C auto a); }; +struct S3 { S3(C auto b); }; +struct S4 { S4(ns::D auto c); }; +struct S5 { S5(ns::D auto d); }; +struct S6 { S6(const C auto e); }; +struct S7 { S7(const C auto f); }; +struct S8 { S8(const ns::D auto g); }; +struct S9 { S9(const ns::D auto h); }; \ No newline at end of file ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 2b54b8b - [Concepts] Instantiate invented template type parameter type-constraint along with function parameters
Author: Saar Raz Date: 2020-02-03T15:48:27+02:00 New Revision: 2b54b8b994b45d4e0a72f36dfb91dc9662543234 URL: https://github.com/llvm/llvm-project/commit/2b54b8b994b45d4e0a72f36dfb91dc9662543234 DIFF: https://github.com/llvm/llvm-project/commit/2b54b8b994b45d4e0a72f36dfb91dc9662543234.diff LOG: [Concepts] Instantiate invented template type parameter type-constraint along with function parameters We previously instantiated type-constraints of template type parameters along with the type parameter itself, this caused problems when the type-constraints created by abbreviated templates refreneced other parameters in the abbreviated templates. When encountering a template type parameter with a type constraint, if it is implicit, delay instantiation of the type-constraint until the function parameter which created the invented template type parameter is instantiated. (cherry picked from commit eacca4824463d8b96e2e1c9f8bbf886055218a16) Added: clang/test/SemaTemplate/instantiate-abbreviated-template.cpp Modified: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index dff336f2ff2d..8c312c9d2c5a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/PrettyDeclStackTrace.h" +#include "clang/AST/TypeVisitor.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/Stack.h" #include "clang/Sema/DeclSpec.h" @@ -2145,6 +2146,94 @@ void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, UpdateExceptionSpec(New, ESI); } +namespace { + + struct GetContainedInventedTypeParmVisitor : +public TypeVisitor { +using TypeVisitor::Visit; + +TemplateTypeParmDecl *Visit(QualType T) { + if (T.isNull()) +return nullptr; + return Visit(T.getTypePtr()); +} +// The deduced type itself. +TemplateTypeParmDecl *VisitTemplateTypeParmType( +const TemplateTypeParmType *T) { + if (!T->getDecl()->isImplicit()) +return nullptr; + return T->getDecl(); +} + +// Only these types can contain 'auto' types, and subsequently be replaced +// by references to invented parameters. + +TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) { + return Visit(T->getNamedType()); +} + +TemplateTypeParmDecl *VisitPointerType(const PointerType *T) { + return Visit(T->getPointeeType()); +} + +TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) { + return Visit(T->getPointeeType()); +} + +TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) { + return Visit(T->getPointeeTypeAsWritten()); +} + +TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) { + return Visit(T->getPointeeType()); +} + +TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) { + return Visit(T->getElementType()); +} + +TemplateTypeParmDecl *VisitDependentSizedExtVectorType( + const DependentSizedExtVectorType *T) { + return Visit(T->getElementType()); +} + +TemplateTypeParmDecl *VisitVectorType(const VectorType *T) { + return Visit(T->getElementType()); +} + +TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) { + return VisitFunctionType(T); +} + +TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) { + return Visit(T->getReturnType()); +} + +TemplateTypeParmDecl *VisitParenType(const ParenType *T) { + return Visit(T->getInnerType()); +} + +TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) { + return Visit(T->getModifiedType()); +} + +TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) { + return Visit(T->getUnderlyingType()); +} + +TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) { + return Visit(T->getOriginalType()); +} + +TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) { + return Visit(T->getPattern()); +} + }; + +} // namespace + ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, @@ -2192,6 +2281,41 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, return nullptr; } + // In abbreviated templates, TemplateTypeParmDecls with possible + // TypeConstraints are created when the parameter list is originally parsed. + // The TypeConstraints can therefore reference other functions parameters in + // the abbreviated function te
[llvm-branch-commits] [clang] c822edc - Revert "[Concepts] Instantiate invented template type parameter type-constraint along with function parameters"
Author: Saar Raz Date: 2020-02-03T16:05:29+02:00 New Revision: c822edc11bf0583f0d4e0f6458ca60f57bc621ed URL: https://github.com/llvm/llvm-project/commit/c822edc11bf0583f0d4e0f6458ca60f57bc621ed DIFF: https://github.com/llvm/llvm-project/commit/c822edc11bf0583f0d4e0f6458ca60f57bc621ed.diff LOG: Revert "[Concepts] Instantiate invented template type parameter type-constraint along with function parameters" This temporarily reverts commit 2b54b8b994b45d4e0a72f36dfb91dc9662543234 which caused some test failures. Added: Modified: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Removed: clang/test/SemaTemplate/instantiate-abbreviated-template.cpp diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 8c312c9d2c5a..dff336f2ff2d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -18,7 +18,6 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/PrettyDeclStackTrace.h" -#include "clang/AST/TypeVisitor.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/Stack.h" #include "clang/Sema/DeclSpec.h" @@ -2146,94 +2145,6 @@ void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, UpdateExceptionSpec(New, ESI); } -namespace { - - struct GetContainedInventedTypeParmVisitor : -public TypeVisitor { -using TypeVisitor::Visit; - -TemplateTypeParmDecl *Visit(QualType T) { - if (T.isNull()) -return nullptr; - return Visit(T.getTypePtr()); -} -// The deduced type itself. -TemplateTypeParmDecl *VisitTemplateTypeParmType( -const TemplateTypeParmType *T) { - if (!T->getDecl()->isImplicit()) -return nullptr; - return T->getDecl(); -} - -// Only these types can contain 'auto' types, and subsequently be replaced -// by references to invented parameters. - -TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) { - return Visit(T->getNamedType()); -} - -TemplateTypeParmDecl *VisitPointerType(const PointerType *T) { - return Visit(T->getPointeeType()); -} - -TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) { - return Visit(T->getPointeeType()); -} - -TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) { - return Visit(T->getPointeeTypeAsWritten()); -} - -TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) { - return Visit(T->getPointeeType()); -} - -TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) { - return Visit(T->getElementType()); -} - -TemplateTypeParmDecl *VisitDependentSizedExtVectorType( - const DependentSizedExtVectorType *T) { - return Visit(T->getElementType()); -} - -TemplateTypeParmDecl *VisitVectorType(const VectorType *T) { - return Visit(T->getElementType()); -} - -TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) { - return VisitFunctionType(T); -} - -TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) { - return Visit(T->getReturnType()); -} - -TemplateTypeParmDecl *VisitParenType(const ParenType *T) { - return Visit(T->getInnerType()); -} - -TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) { - return Visit(T->getModifiedType()); -} - -TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) { - return Visit(T->getUnderlyingType()); -} - -TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) { - return Visit(T->getOriginalType()); -} - -TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) { - return Visit(T->getPattern()); -} - }; - -} // namespace - ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, @@ -2281,41 +2192,6 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, return nullptr; } - // In abbreviated templates, TemplateTypeParmDecls with possible - // TypeConstraints are created when the parameter list is originally parsed. - // The TypeConstraints can therefore reference other functions parameters in - // the abbreviated function template, which is why we must instantiate them - // here, when the instantiated versions of those referenced parameters are in - // scope. - if (TemplateTypeParmDecl *TTP = - GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) { -if (const TypeConstraint *TC = TTP->getTypeConstraint()) { - // TODO: Concepts: do not instantiate the constraint (delayed constraint - // substitution) - const AS
[llvm-branch-commits] [clang] 1ac1c4b - [Concepts] Instantiate invented template type parameter type-constraint along with function parameters
Author: Saar Raz Date: 2020-02-03T16:53:14+02:00 New Revision: 1ac1c4b4850c1a507caa7da068f44a45ef4ba3c7 URL: https://github.com/llvm/llvm-project/commit/1ac1c4b4850c1a507caa7da068f44a45ef4ba3c7 DIFF: https://github.com/llvm/llvm-project/commit/1ac1c4b4850c1a507caa7da068f44a45ef4ba3c7.diff LOG: [Concepts] Instantiate invented template type parameter type-constraint along with function parameters We previously instantiated type-constraints of template type parameters along with the type parameter itself, this caused problems when the type-constraints created by abbreviated templates refreneced other parameters in the abbreviated templates. When encountering a template type parameter with a type constraint, if it is implicit, delay instantiation of the type-constraint until the function parameter which created the invented template type parameter is instantiated. Reland after fixing bug caused by another flow reaching SubstParmVarDecl and instantiating the TypeConstraint a second time. (cherry picked from commit 84959ae47f447fca9d56a9c61e8c46e993d0387a) Added: clang/test/SemaTemplate/instantiate-abbreviated-template.cpp Modified: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index dff336f2ff2d..a9357ede700e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/PrettyDeclStackTrace.h" +#include "clang/AST/TypeVisitor.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/Stack.h" #include "clang/Sema/DeclSpec.h" @@ -2145,6 +2146,94 @@ void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto, UpdateExceptionSpec(New, ESI); } +namespace { + + struct GetContainedInventedTypeParmVisitor : +public TypeVisitor { +using TypeVisitor::Visit; + +TemplateTypeParmDecl *Visit(QualType T) { + if (T.isNull()) +return nullptr; + return Visit(T.getTypePtr()); +} +// The deduced type itself. +TemplateTypeParmDecl *VisitTemplateTypeParmType( +const TemplateTypeParmType *T) { + if (!T->getDecl()->isImplicit()) +return nullptr; + return T->getDecl(); +} + +// Only these types can contain 'auto' types, and subsequently be replaced +// by references to invented parameters. + +TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) { + return Visit(T->getNamedType()); +} + +TemplateTypeParmDecl *VisitPointerType(const PointerType *T) { + return Visit(T->getPointeeType()); +} + +TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) { + return Visit(T->getPointeeType()); +} + +TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) { + return Visit(T->getPointeeTypeAsWritten()); +} + +TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) { + return Visit(T->getPointeeType()); +} + +TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) { + return Visit(T->getElementType()); +} + +TemplateTypeParmDecl *VisitDependentSizedExtVectorType( + const DependentSizedExtVectorType *T) { + return Visit(T->getElementType()); +} + +TemplateTypeParmDecl *VisitVectorType(const VectorType *T) { + return Visit(T->getElementType()); +} + +TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) { + return VisitFunctionType(T); +} + +TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) { + return Visit(T->getReturnType()); +} + +TemplateTypeParmDecl *VisitParenType(const ParenType *T) { + return Visit(T->getInnerType()); +} + +TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) { + return Visit(T->getModifiedType()); +} + +TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) { + return Visit(T->getUnderlyingType()); +} + +TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) { + return Visit(T->getOriginalType()); +} + +TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) { + return Visit(T->getPattern()); +} + }; + +} // namespace + ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs, int indexAdjustment, @@ -2192,6 +2281,46 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, return nullptr; } + // In abbreviated templates, TemplateTypeParmDecls with possible + // TypeConstraints are created when the parameter list is origi
[llvm-branch-commits] [clang] 8f19f98 - [Concepts] Add missing CXXThisScope to function template constraint substitution
Author: Saar Raz Date: 2020-02-05T01:11:08+02:00 New Revision: 8f19f984f296c8ddbb16dc1623e8a4bd6bfed111 URL: https://github.com/llvm/llvm-project/commit/8f19f984f296c8ddbb16dc1623e8a4bd6bfed111 DIFF: https://github.com/llvm/llvm-project/commit/8f19f984f296c8ddbb16dc1623e8a4bd6bfed111.diff LOG: [Concepts] Add missing CXXThisScope to function template constraint substitution We did not have a CXXThisScope around constraint checking of functions and function template specializations, causing a crash when checking a constraint that had a 'this' (bug 44689). Recommit after fixing test. (cherry picked from commit 6c232441564f8934477e418347bf0c217abb0a00) Added: Modified: clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/SemaTemplate/instantiate-requires-clause.cpp Removed: diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 39169664dad5..290e4cbff4fd 100755 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -329,6 +329,13 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, Satisfaction.IsSatisfied = true; return false; } + Qualifiers ThisQuals; + CXXRecordDecl *Record = nullptr; + if (auto *Method = dyn_cast(FD)) { +ThisQuals = Method->getMethodQualifiers(); +Record = const_cast(Method->getParent()); + } + CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); // We substitute with empty arguments in order to rebuild the atomic // constraint in a constant-evaluated context. // FIXME: Should this be a dedicated TreeTransform? diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0e1d5fa77c69..7094462e74c9 100755 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4271,7 +4271,13 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( Scope, MLTAL)) return true; } - + Qualifiers ThisQuals; + CXXRecordDecl *Record = nullptr; + if (auto *Method = dyn_cast(Decl)) { +ThisQuals = Method->getMethodQualifiers(); +Record = Method->getParent(); + } + CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs, PointOfInstantiation, Satisfaction); } diff --git a/clang/test/SemaTemplate/instantiate-requires-clause.cpp b/clang/test/SemaTemplate/instantiate-requires-clause.cpp index 8e9d5bffa906..a4d1b6597201 100644 --- a/clang/test/SemaTemplate/instantiate-requires-clause.cpp +++ b/clang/test/SemaTemplate/instantiate-requires-clause.cpp @@ -57,4 +57,13 @@ struct S3 { static constexpr void f(Args...) { } }; -static_assert((S3::f(), true)); \ No newline at end of file +static_assert((S3::f(), true)); + +template +struct S4 { +template +constexpr void foo() requires (*this, true) { } +constexpr void goo() requires (*this, true) { } +}; + +static_assert((S4{}.foo(), S4{}.goo(), true)); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 96ed02d - [Concepts] Fix incorrect check when instantiating abbreviated template type-constraints
Author: Saar Raz Date: 2020-02-06T23:30:34+02:00 New Revision: 96ed02ddeebfd18265ef687fce80e7e148ec261c URL: https://github.com/llvm/llvm-project/commit/96ed02ddeebfd18265ef687fce80e7e148ec261c DIFF: https://github.com/llvm/llvm-project/commit/96ed02ddeebfd18265ef687fce80e7e148ec261c.diff LOG: [Concepts] Fix incorrect check when instantiating abbreviated template type-constraints We would incorrectly check whether the type-constraint had already been initialized, causing us to ignore the invented template type constraints entirely. Also, TemplateParameterList would store incorrect information about invented type parameters when it observed them before their type-constraint was initialized, so we recreate it after initializing the function type of an abbreviated template. (cherry picked from commit 38fd69995fc5a6f16e0aa132a46e5ccdbc2eebb3) Added: Modified: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/test/SemaTemplate/instantiate-abbreviated-template.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index a9357ede700e..568f5404dc0b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2290,12 +2290,12 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm, if (TemplateTypeParmDecl *TTP = GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) { if (const TypeConstraint *TC = TTP->getTypeConstraint()) { - auto *Inst = cast( + auto *Inst = cast_or_null( FindInstantiatedDecl(TTP->getLocation(), TTP, TemplateArgs)); // We will first get here when instantiating the abbreviated function // template's described function, but we might also get here later. // Make sure we do not instantiate the TypeConstraint more than once. - if (Inst && !Inst->hasTypeConstraint()) { + if (Inst && !Inst->getTypeConstraint()) { // TODO: Concepts: do not instantiate the constraint (delayed constraint // substitution) const ASTTemplateArgumentListInfo *TemplArgInfo diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 7094462e74c9..37dace3bee7f 100755 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1837,6 +1837,23 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( return nullptr; QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); + if (TemplateParams && TemplateParams->size()) { +auto *LastParam = +dyn_cast(TemplateParams->asArray().back()); +if (LastParam && LastParam->isImplicit() && +LastParam->hasTypeConstraint()) { + // In abbreviated templates, the type-constraints of invented template + // type parameters are instantiated with the function type, invalidating + // the TemplateParameterList which relied on the template type parameter + // not having a type constraint. Recreate the TemplateParameterList with + // the updated parameter list. + TemplateParams = TemplateParameterList::Create( + SemaRef.Context, TemplateParams->getTemplateLoc(), + TemplateParams->getLAngleLoc(), TemplateParams->asArray(), + TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause()); +} + } + NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); if (QualifierLoc) { QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, @@ -2177,6 +2194,23 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( return nullptr; QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); + if (TemplateParams && TemplateParams->size()) { +auto *LastParam = +dyn_cast(TemplateParams->asArray().back()); +if (LastParam && LastParam->isImplicit() && +LastParam->hasTypeConstraint()) { + // In abbreviated templates, the type-constraints of invented template + // type parameters are instantiated with the function type, invalidating + // the TemplateParameterList which relied on the template type parameter + // not having a type constraint. Recreate the TemplateParameterList with + // the updated parameter list. + TemplateParams = TemplateParameterList::Create( + SemaRef.Context, TemplateParams->getTemplateLoc(), + TemplateParams->getLAngleLoc(), TemplateParams->asArray(), + TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause()); +} + } + NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); if (QualifierLoc) { QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, diff --git a/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp b/clang/t
[llvm-branch-commits] [clang] 9fbd4ab - [Concepts] Do not check constraints if not all template arguments have been deduced
Author: Saar Raz Date: 2020-02-12T16:03:13+02:00 New Revision: 9fbd4ab395f73209d09d821f6e5d49150c1e36ab URL: https://github.com/llvm/llvm-project/commit/9fbd4ab395f73209d09d821f6e5d49150c1e36ab DIFF: https://github.com/llvm/llvm-project/commit/9fbd4ab395f73209d09d821f6e5d49150c1e36ab.diff LOG: [Concepts] Do not check constraints if not all template arguments have been deduced We previously checked the constraints of instantiated function templates even in cases where PartialOverloading was true and not all template arguments have been deduced, which caused crashes in clangd (bug 44714). We now check if all arguments have been deduced before checking constraints in partial overloading scenarios. (cherry picked from commit 5fef14d932fe602bf998b8fb8a809ff85ca1e245) Added: clang/test/CXX/temp/temp.deduct/p5.cpp Modified: clang/lib/Sema/SemaTemplateDeduction.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 1a71f270679d..6b865a601f9d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3439,13 +3439,16 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // ([temp.constr.decl]), those constraints are checked for satisfaction // ([temp.constr.constr]). If the constraints are not satisfied, type // deduction fails. - if (CheckInstantiatedFunctionTemplateConstraints(Info.getLocation(), - Specialization, Builder, Info.AssociatedConstraintsSatisfaction)) -return TDK_MiscellaneousDeductionFailure; + if (!PartialOverloading || + (Builder.size() == FunctionTemplate->getTemplateParameters()->size())) { +if (CheckInstantiatedFunctionTemplateConstraints(Info.getLocation(), +Specialization, Builder, Info.AssociatedConstraintsSatisfaction)) + return TDK_MiscellaneousDeductionFailure; - if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) { -Info.reset(TemplateArgumentList::CreateCopy(Context, Builder)); -return TDK_ConstraintsNotSatisfied; +if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) { + Info.reset(TemplateArgumentList::CreateCopy(Context, Builder)); + return TDK_ConstraintsNotSatisfied; +} } if (OriginalCallArgs) { diff --git a/clang/test/CXX/temp/temp.deduct/p5.cpp b/clang/test/CXX/temp/temp.deduct/p5.cpp new file mode 100644 index ..0c998b19f181 --- /dev/null +++ b/clang/test/CXX/temp/temp.deduct/p5.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -std=c++2a -verify %s -code-completion-at=%s:6:16 +// expected-no-diagnostics + +template concept C = true; +void bar(C auto foo); +int y = bar( \ No newline at end of file ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 6f69240 - [Concepts] Add missing TPA commit to requires expression parsing
Author: Saar Raz Date: 2020-02-12T16:27:14+02:00 New Revision: 6f692404a30d7f58b20d40f7a6ceaf826320b145 URL: https://github.com/llvm/llvm-project/commit/6f692404a30d7f58b20d40f7a6ceaf826320b145 DIFF: https://github.com/llvm/llvm-project/commit/6f692404a30d7f58b20d40f7a6ceaf826320b145.diff LOG: [Concepts] Add missing TPA commit to requires expression parsing If an error had occurred when annotating a scope spec during the tentative parse for a type-requirement, we would not revert nor commit the tentative parse, triggerring an assertion failure. Commit the TPA in this case and then do error recovery. (cherry picked from commit 271e495399170d69627c1acd591c9298cb0b5b4b) Added: Modified: clang/lib/Parse/ParseExprCXX.cpp Removed: diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 9f94e0dde3bd..17f81ec96c1f 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -3476,6 +3476,7 @@ ExprResult Parser::ParseRequiresExpression() { // We need to consume the typename to allow 'requires { typename a; }' SourceLocation TypenameKWLoc = ConsumeToken(); if (TryAnnotateCXXScopeToken()) { +TPA.Commit(); SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch); break; } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 7c18c2f - [Concepts] Add null check for TemplateTypeParmType::getDecl() in GetContainedInventedTypeParmVisitor
Author: Saar Raz Date: 2020-03-06T19:34:43+02:00 New Revision: 7c18c2f709e9a1009c120ff31863799a1279c3b1 URL: https://github.com/llvm/llvm-project/commit/7c18c2f709e9a1009c120ff31863799a1279c3b1 DIFF: https://github.com/llvm/llvm-project/commit/7c18c2f709e9a1009c120ff31863799a1279c3b1.diff LOG: [Concepts] Add null check for TemplateTypeParmType::getDecl() in GetContainedInventedTypeParmVisitor GetContainedInventedTypeParmVisitor would not account for the case where TemplateTypeParmType::getDecl() is nullptr, causing bug #45102. Add the nullptr check. (cherry picked from commit 865456d589e093582acaafd17d58ad1c0cce66af) Added: Modified: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaTemplate/instantiate-abbreviated-template.cpp Removed: diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 568f5404dc0b..ce9a0263bd50 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2162,7 +2162,7 @@ namespace { // The deduced type itself. TemplateTypeParmDecl *VisitTemplateTypeParmType( const TemplateTypeParmType *T) { - if (!T->getDecl()->isImplicit()) + if (!T->getDecl() || !T->getDecl()->isImplicit()) return nullptr; return T->getDecl(); } diff --git a/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp b/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp index 99801115626f..1f2171a25ebb 100644 --- a/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp +++ b/clang/test/SemaTemplate/instantiate-abbreviated-template.cpp @@ -31,3 +31,15 @@ struct G { using gf1 = decltype(G::foo1('a', 1, 2, 3, 4)); // expected-error{{no matching function}} using gf2 = decltype(G::foo2('a', 1, 2)); // expected-error{{no matching function}} + + +// Regression (bug #45102): check that instantiation works where there is no +// TemplateTypeParmDecl +template using id = T; + +template +constexpr void g() { + id f; +} + +static_assert((g(), true)); \ No newline at end of file ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 4e41127 - [Concepts] Add constraints checks to isSameEntity
Author: Saar Raz Date: 2020-03-10T22:13:50+02:00 New Revision: 4e41127f04d7d7c6536f78ccdc7e4841a06102ba URL: https://github.com/llvm/llvm-project/commit/4e41127f04d7d7c6536f78ccdc7e4841a06102ba DIFF: https://github.com/llvm/llvm-project/commit/4e41127f04d7d7c6536f78ccdc7e4841a06102ba.diff LOG: [Concepts] Add constraints checks to isSameEntity isSameEntity was missing constraints checking, causing constrained overloads to not travel well accross serialization. (bug #45115) Add constraints checking to isSameEntity. (cherry picked from commit 7fb562c1ab373a3d4e14003e40556791ec032bab) Added: clang/test/PCH/cxx2a-constraints.cpp Modified: clang/lib/Serialization/ASTReaderDecl.cpp Removed: diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index b7000a6956d9..e3eea3c6f860 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2867,7 +2867,8 @@ uint64_t ASTReader::getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset) { return LocalOffset + M.GlobalBitOffset; } -static bool isSameTemplateParameterList(const TemplateParameterList *X, +static bool isSameTemplateParameterList(const ASTContext &C, +const TemplateParameterList *X, const TemplateParameterList *Y); /// Determine whether two template parameters are similar enough @@ -2879,7 +2880,32 @@ static bool isSameTemplateParameter(const NamedDecl *X, if (const auto *TX = dyn_cast(X)) { const auto *TY = cast(Y); -return TX->isParameterPack() == TY->isParameterPack(); +if (TX->isParameterPack() != TY->isParameterPack()) + return false; +if (TX->hasTypeConstraint() != TY->hasTypeConstraint()) + return false; +if (TX->hasTypeConstraint()) { + const TypeConstraint *TXTC = TX->getTypeConstraint(); + const TypeConstraint *TYTC = TY->getTypeConstraint(); + if (TXTC->getNamedConcept() != TYTC->getNamedConcept()) +return false; + if (TXTC->hasExplicitTemplateArgs() != TYTC->hasExplicitTemplateArgs()) +return false; + if (TXTC->hasExplicitTemplateArgs()) { +const auto *TXTCArgs = TXTC->getTemplateArgsAsWritten(); +const auto *TYTCArgs = TYTC->getTemplateArgsAsWritten(); +if (TXTCArgs->NumTemplateArgs != TYTCArgs->NumTemplateArgs) + return false; +llvm::FoldingSetNodeID XID, YID; +for (const auto &ArgLoc : TXTCArgs->arguments()) + ArgLoc.getArgument().Profile(XID, X->getASTContext()); +for (const auto &ArgLoc : TYTCArgs->arguments()) + ArgLoc.getArgument().Profile(YID, Y->getASTContext()); +if (XID != YID) + return false; + } +} +return true; } if (const auto *TX = dyn_cast(X)) { @@ -2891,7 +2917,8 @@ static bool isSameTemplateParameter(const NamedDecl *X, const auto *TX = cast(X); const auto *TY = cast(Y); return TX->isParameterPack() == TY->isParameterPack() && - isSameTemplateParameterList(TX->getTemplateParameters(), + isSameTemplateParameterList(TX->getASTContext(), + TX->getTemplateParameters(), TY->getTemplateParameters()); } @@ -2944,7 +2971,8 @@ static bool isSameQualifier(const NestedNameSpecifier *X, /// Determine whether two template parameter lists are similar enough /// that they may be used in declarations of the same template. -static bool isSameTemplateParameterList(const TemplateParameterList *X, +static bool isSameTemplateParameterList(const ASTContext &C, +const TemplateParameterList *X, const TemplateParameterList *Y) { if (X->size() != Y->size()) return false; @@ -2953,6 +2981,18 @@ static bool isSameTemplateParameterList(const TemplateParameterList *X, if (!isSameTemplateParameter(X->getParam(I), Y->getParam(I))) return false; + const Expr *XRC = X->getRequiresClause(); + const Expr *YRC = Y->getRequiresClause(); + if (!XRC != !YRC) +return false; + if (XRC) { +llvm::FoldingSetNodeID XRCID, YRCID; +XRC->Profile(XRCID, C, /*Canonical=*/true); +YRC->Profile(YRCID, C, /*Canonical=*/true); +if (XRCID != YRCID) + return false; + } + return true; } @@ -2989,7 +3029,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A, return true; } -/// Determine whether the two declarations refer to the same entity. +/// Determine whether the two declarations refer to the same entity.pr static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { assert(X->getDeclName() == Y->getDeclName() && "Declaration name mismatch!"); @@ -3064,6 +3104,19 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { } ASTContext &C = F
[llvm-branch-commits] [clang] 52cebc4 - [Concepts] Add FoundDecl to ConceptSpecializationExpr serialization
Author: Saar Raz Date: 2020-03-10T22:13:31+02:00 New Revision: 52cebc452d1805c274f0ffd56f76e5a7bbb37fdd URL: https://github.com/llvm/llvm-project/commit/52cebc452d1805c274f0ffd56f76e5a7bbb37fdd DIFF: https://github.com/llvm/llvm-project/commit/52cebc452d1805c274f0ffd56f76e5a7bbb37fdd.diff LOG: [Concepts] Add FoundDecl to ConceptSpecializationExpr serialization FoundDecl was missing from ConceptSpecializationExpr serialization - add it. (cherry picked from commit f9e63891597630405a4655298f06b193e4ceb384) Added: Modified: clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp Removed: diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 5dd0ef9d43c3..db879f3004f9 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -754,6 +754,7 @@ void ASTStmtReader::VisitConceptSpecializationExpr( E->TemplateKWLoc = Record.readSourceLocation(); E->ConceptName = Record.readDeclarationNameInfo(); E->NamedConcept = readDeclAs(); + E->FoundDecl = Record.readDeclAs(); E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); llvm::SmallVector Args; for (unsigned I = 0; I < NumTemplateArgs; ++I) diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 1b118c257a4c..f81e940a6dbc 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -429,6 +429,7 @@ void ASTStmtWriter::VisitConceptSpecializationExpr( Record.AddSourceLocation(E->getTemplateKWLoc()); Record.AddDeclarationNameInfo(E->getConceptNameInfo()); Record.AddDeclRef(E->getNamedConcept()); + Record.AddDeclRef(E->getFoundDecl()); Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten()); for (const TemplateArgument &Arg : TemplateArgs) Record.AddTemplateArgument(Arg); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 9e0bd5e - [Concepts] Fix incorrect DeclContext for transformed RequiresExprBodyDecl
Author: Saar Raz Date: 2020-03-17T07:49:16+02:00 New Revision: 9e0bd5ec03cbc8d53048e92ddf7fd25bca17e912 URL: https://github.com/llvm/llvm-project/commit/9e0bd5ec03cbc8d53048e92ddf7fd25bca17e912 DIFF: https://github.com/llvm/llvm-project/commit/9e0bd5ec03cbc8d53048e92ddf7fd25bca17e912.diff LOG: [Concepts] Fix incorrect DeclContext for transformed RequiresExprBodyDecl We would assign the incorrect DeclContext when transforming the RequiresExprBodyDecl, causing incorrect handling of 'this' inside RequiresExprBodyDecls (bug #45162). Assign the current context as the DeclContext of the transformed decl. (cherry picked from commit 9769e1ee9acc33638449b50ac394b5ee2d4efb60) Added: Modified: clang/lib/Sema/TreeTransform.h clang/test/SemaTemplate/instantiate-requires-expr.cpp Removed: diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 805fe6684205..0305954a278e 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -11303,7 +11303,7 @@ TreeTransform::TransformRequiresExpr(RequiresExpr *E) { SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create( - getSema().Context, E->getBody()->getDeclContext(), + getSema().Context, getSema().CurContext, E->getBody()->getBeginLoc()); Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false); diff --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp index 927bc1bf8f12..ba82fc1313fc 100644 --- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp +++ b/clang/test/SemaTemplate/instantiate-requires-expr.cpp @@ -164,6 +164,19 @@ namespace expr_requirement { struct r3 {}; using r3i = r3; // expected-error{{constraints not satisfied for class template 'r3' [with Ts = ]}} + + template + struct r4 { + constexpr int foo() { +if constexpr (requires { this->invalid(); }) + return 1; +else + return 0; + } + + constexpr void invalid() requires false { } + }; + static_assert(r4{}.foo() == 0); } namespace nested_requirement { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 135744c - [Concepts] Fix incorrect control flow when TryAnnotateTypeConstraint annotates an invalid template-id
Author: Saar Raz Date: 2020-03-17T07:49:42+02:00 New Revision: 135744ce689569e7c64033bb5812572d3000239b URL: https://github.com/llvm/llvm-project/commit/135744ce689569e7c64033bb5812572d3000239b DIFF: https://github.com/llvm/llvm-project/commit/135744ce689569e7c64033bb5812572d3000239b.diff LOG: [Concepts] Fix incorrect control flow when TryAnnotateTypeConstraint annotates an invalid template-id TryAnnotateTypeConstraint could annotate a template-id which doesn't end up being a type-constraint, in which case control flow would incorrectly flow into ParseImplicitInt. Reenter the loop in this case. Enable relevant tests for C++20. This required disabling typo-correction during TryAnnotateTypeConstraint and changing a test case which is broken due to a separate bug (will be reported and handled separately). (cherry picked from commit 19fccc52ff2c1da1f93d9317c34769bd9bab8ac8) Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseDecl.cpp clang/lib/Parse/ParseTemplate.cpp clang/lib/Sema/SemaTemplate.cpp clang/test/SemaCXX/invalid-member-expr.cpp clang/test/SemaCXX/typo-correction.cpp clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp Removed: diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 033f7af6f2f3..842e49602274 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6885,7 +6885,8 @@ class Sema final { QualType ObjectType, bool EnteringContext, bool &MemberOfUnknownSpecialization, SourceLocation TemplateKWLoc = SourceLocation(), - AssumedTemplateKind *ATK = nullptr); + AssumedTemplateKind *ATK = nullptr, + bool Disambiguation = false); TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, @@ -6894,7 +6895,8 @@ class Sema final { ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, - bool &MemberOfUnknownSpecialization); + bool &MemberOfUnknownSpecialization, + bool Disambiguation = false); /// Try to resolve an undeclared template name as a type template. /// diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index cdc3506d5c68..6353e14bc41a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3252,6 +3252,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; if (isTypeConstraintAnnotation()) continue; +if (NextToken().is(tok::annot_template_id)) + // Might have been annotated by TryAnnotateTypeConstraint. + continue; // Eat the scope spec so the identifier is current. ConsumeAnnotationToken(); ParsedAttributesWithRange Attrs(AttrFactory); @@ -3405,6 +3408,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; if (isTypeConstraintAnnotation()) continue; +if (Tok.is(tok::annot_template_id)) + // Might have been annotated by TryAnnotateTypeConstraint. + continue; ParsedAttributesWithRange Attrs(AttrFactory); if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) { if (!Attrs.empty()) { diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 3bc4e3596f12..609640576e9e 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -710,7 +710,8 @@ bool Parser::TryAnnotateTypeConstraint() { /*ObjectType=*/ParsedType(), /*EnteringContext=*/false, PossibleConcept, - MemberOfUnknownSpecialization); + MemberOfUnknownSpecialization, + /*Disambiguation=*/true); if (MemberOfUnknownSpecialization || !PossibleConcept || TNK != TNK_Concept_template) { if (SS.isNotEmpty()) diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4f577a3cf748..c38c724ed9b0 100755 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -174,7 +174,8 @@ TemplateNameKind Sema::isTemplateName(Scope *S, ParsedType ObjectTypePtr, bool EnteringContext, TemplateTy &TemplateResult, - bool &MemberOfUnk