[llvm-branch-commits] [clang] 57f70e3 - [Concepts] Fix ConceptSpecializationExpr profiling crash

2020-01-23 Thread Saar Raz via llvm-branch-commits

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.

2020-01-23 Thread Saar Raz via llvm-branch-commits

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

2020-01-25 Thread Saar Raz via llvm-branch-commits

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

2020-01-26 Thread Saar Raz via llvm-branch-commits

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

2020-01-26 Thread Saar Raz via llvm-branch-commits

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

2020-01-26 Thread Saar Raz via llvm-branch-commits

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

2020-01-30 Thread Saar Raz via llvm-branch-commits

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

2020-01-30 Thread Saar Raz via llvm-branch-commits

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

2020-01-30 Thread Saar Raz via llvm-branch-commits

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

2020-01-31 Thread Saar Raz via llvm-branch-commits

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

2020-01-31 Thread Saar Raz via llvm-branch-commits

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

2020-02-03 Thread Saar Raz via llvm-branch-commits

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"

2020-02-03 Thread Saar Raz via llvm-branch-commits

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

2020-02-03 Thread Saar Raz via llvm-branch-commits

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

2020-02-04 Thread Saar Raz via llvm-branch-commits

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

2020-02-06 Thread Saar Raz via llvm-branch-commits

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

2020-02-12 Thread Saar Raz via llvm-branch-commits

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

2020-02-12 Thread Saar Raz via llvm-branch-commits

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

2020-03-06 Thread Saar Raz via llvm-branch-commits

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

2020-03-10 Thread Saar Raz via llvm-branch-commits

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

2020-03-10 Thread Saar Raz via llvm-branch-commits

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

2020-03-16 Thread Saar Raz via llvm-branch-commits

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

2020-03-16 Thread Saar Raz via llvm-branch-commits

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