usaxena95 created this revision.
Herald added a project: All.
usaxena95 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D137712

Files:
  clang/include/clang/AST/ExprConcepts.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/AST/ExprConcepts.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===================================================================
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -764,3 +764,53 @@
   __iterator_traits_member_pointer_or_arrow_or_void<counted_iterator<int>> f;
 }
 }// namespace InheritedFromPartialSpec
+
+namespace nested_requirements {
+template<class T>  concept True = true;
+
+struct S { double value; };
+
+template <class T>
+concept Pipes = requires (T x) {
+   requires True<decltype(x.value)> || True<T>;
+   requires True<T> || True<decltype(x.value)>;
+};
+template <class T>
+concept Amps1 = requires (T x) {
+   requires True<decltype(x.value)> && True<T>;
+   // expected-note@-1{{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
+};
+template <class T>
+concept Amps2 = requires (T x) {
+   requires True<T> && True<decltype(x.value)>;
+};
+
+static_assert(Pipes<S>);
+static_assert(Pipes<double>);
+
+static_assert(Amps1<S>);
+static_assert(!Amps1<double>);
+
+static_assert(Amps2<S>);
+static_assert(!Amps2<double>);
+
+template<class T>
+void foo1() requires requires (T x) { // expected-note {{candidate template ignored: constraints not satisfied [with T = int]}}
+  requires 
+  True<decltype(x.value)> // expected-note {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
+  && True<T>;
+} {}
+template<class T> void fooPipes() requires Pipes<T> {}
+template<class T> void fooAmps1() requires Amps1<T> {}
+// expected-note@-1 {{candidate template ignored: constraints not satisfied [with T = int]}} \
+// expected-note@-1 {{because 'int' does not satisfy 'Amps1'}}
+
+void foo() {
+  foo1<S>();
+  foo1<int>(); // expected-error {{no matching function for call to 'foo1'}}
+  fooPipes<S>();
+  fooPipes<int>();
+  fooAmps1<S>();
+  fooAmps1<int>(); // expected-error {{no matching function for call to 'fooAmps1'}}
+}
+}
\ No newline at end of file
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -3477,6 +3477,22 @@
     return Result;
   }
 
+  ExprResult RebuildConceptSpecializationExprWithSFINAE(
+      ConceptSpecializationExpr *E, NestedNameSpecifierLoc NNS,
+      SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+      NamedDecl *FoundDecl, ConceptDecl *NamedConcept) {
+    ConstraintSatisfaction Satisfaction;
+    Satisfaction.IsSatisfied = false;
+    Satisfaction.ContainsErrors = true;
+    CXXScopeSpec SS;
+    SS.Adopt(NNS);
+    return ConceptSpecializationExpr::CreateWithSFINAE(
+        SemaRef.Context,
+        SS.isSet() ? SS.getWithLocInContext(SemaRef.Context)
+                   : NestedNameSpecifierLoc{},
+        TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, &Satisfaction);
+  }
+
   /// \brief Build a new requires expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -12617,9 +12633,20 @@
                                                  ConceptSpecializationExpr *E) {
   const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
   TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
-  if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
-                                              Old->NumTemplateArgs, TransArgs))
-    return ExprError();
+  {
+    Sema::SFINAETrap Trap(getSema());
+    if (getDerived().TransformTemplateArguments(
+            Old->getTemplateArgs(), Old->NumTemplateArgs, TransArgs) &&
+        !Trap.hasErrorOccurred())
+      return ExprError();
+
+    if (Trap.hasErrorOccurred()) {
+      // FIXME: Propogate detailed subtitution falilure diagnostics.
+      return getDerived().RebuildConceptSpecializationExprWithSFINAE(
+          E, E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
+          E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept());
+    }
+  }
 
   return getDerived().RebuildConceptSpecializationExpr(
       E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
Index: clang/lib/AST/ExprConcepts.cpp
===================================================================
--- clang/lib/AST/ExprConcepts.cpp
+++ clang/lib/AST/ExprConcepts.cpp
@@ -103,6 +103,16 @@
                                 Dependent, ContainsUnexpandedParameterPack);
 }
 
+ConceptSpecializationExpr *ConceptSpecializationExpr::CreateWithSFINAE(
+    const ASTContext &C, NestedNameSpecifierLoc NNS,
+    SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+    NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+    const ConstraintSatisfaction *Satisfaction) {
+  return ConceptSpecializationExpr::Create(
+      C, NNS, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, nullptr,
+      nullptr, Satisfaction);
+}
+
 const TypeConstraint *
 concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
   assert(isTypeConstraint());
Index: clang/lib/AST/ComputeDependence.cpp
===================================================================
--- clang/lib/AST/ComputeDependence.cpp
+++ clang/lib/AST/ComputeDependence.cpp
@@ -844,12 +844,13 @@
   auto TA = TemplateArgumentDependence::None;
   const auto InterestingDeps = TemplateArgumentDependence::Instantiation |
                                TemplateArgumentDependence::UnexpandedPack;
-  for (const TemplateArgumentLoc &ArgLoc :
-       E->getTemplateArgsAsWritten()->arguments()) {
-    TA |= ArgLoc.getArgument().getDependence() & InterestingDeps;
-    if (TA == InterestingDeps)
-      break;
-  }
+  if (E->getTemplateArgsAsWritten())
+    for (const TemplateArgumentLoc &ArgLoc :
+         E->getTemplateArgsAsWritten()->arguments()) {
+      TA |= ArgLoc.getArgument().getDependence() & InterestingDeps;
+      if (TA == InterestingDeps)
+        break;
+    }
 
   ExprDependence D =
       ValueDependent ? ExprDependence::Value : ExprDependence::None;
Index: clang/include/clang/AST/ExprConcepts.h
===================================================================
--- clang/include/clang/AST/ExprConcepts.h
+++ clang/include/clang/AST/ExprConcepts.h
@@ -84,6 +84,13 @@
          const ConstraintSatisfaction *Satisfaction, bool Dependent,
          bool ContainsUnexpandedParameterPack);
 
+  static ConceptSpecializationExpr *
+  CreateWithSFINAE(const ASTContext &C, NestedNameSpecifierLoc NNS,
+                   SourceLocation TemplateKWLoc,
+                   DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
+                   ConceptDecl *NamedConcept,
+                   const ConstraintSatisfaction *Satisfaction);
+
   ArrayRef<TemplateArgument> getTemplateArguments() const {
     return SpecDecl->getTemplateArguments();
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to