mizvekov updated this revision to Diff 330775.
mizvekov added a comment.

broken bot rebuild repush


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98160/new/

https://reviews.llvm.org/D98160

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp

Index: clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
===================================================================
--- clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
+++ clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
@@ -79,19 +79,23 @@
 template<typename T>
 constexpr bool is_same_v<T, T> = true;
 
+template<typename T> struct remove_reference { using type = T; };
+template<typename T> struct remove_reference<T&> { using type = T; };
+
 template<typename T, typename U>
 concept Same = is_same_v<T, U>;
 
 template<typename T>
-concept Large = sizeof(T) >= 4; // expected-note{{because 'sizeof(short) >= 4' (2 >= 4) evaluated to false}}
+concept Large = sizeof(typename remove_reference<T>::type) >= 4;
+// expected-note@-1{{because 'sizeof(typename remove_reference<short &>::type) >= 4' (2 >= 4) evaluated to false}}
 
-template<typename T> requires requires (T t) { { t } -> Large; } // expected-note{{because 'decltype(t)' (aka 'short') does not satisfy 'Large':}}
+template<typename T> requires requires (T t) { { t } -> Large; } // expected-note{{because 'decltype((t))' (aka 'short &') does not satisfy 'Large':}}
 struct r7 {};
 
 using r7i1 = r7<int>;
 using r7i2 = r7<short>; // expected-error{{constraints not satisfied for class template 'r7' [with T = short]}}
 
-template<typename T> requires requires (T t) { { t } -> Same<T>; }
+template<typename T> requires requires (T t) { { t } -> Same<T&>; }
 struct r8 {};
 
 using r8i1 = r8<int>;
@@ -99,7 +103,8 @@
 
 // Substitution failure in type constraint
 
-template<typename T> requires requires (T t) { { t } -> Same<typename T::type>; } // expected-note{{because 'Same<expr-type, typename T::type>' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
+template<typename T> requires requires (T t) { { t } -> Same<typename T::type&>; }
+// expected-note@-1{{because 'Same<expr-type, typename T::type &>' would be invalid: type 'int' cannot be used prior to '::' because it has no members}}
 struct r9 {};
 
 struct M { using type = M; };
@@ -122,6 +127,17 @@
 template<typename T> requires requires (T t) { { t } -> IsEven; } // expected-error{{concept named in type constraint is not a type concept}}
 struct r11 {};
 
+// Value categories
+
+template<auto a = 0>
+requires requires (int b) {
+  { a } -> Same<int>;
+  { b } -> Same<int&>;
+  { 0 } -> Same<int>;
+  { static_cast<int&&>(a) } -> Same<int&&>;
+} void f1() {}
+template void f1<>();
+
 // C++ [expr.prim.req.compound] Example
 namespace std_example {
   template<typename T> concept C1 =
@@ -172,4 +188,4 @@
   static_assert(C5<char>);
   template<C5 T> struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}}
   using c5 = C5_check<short>; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}}
-}
\ No newline at end of file
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -8832,6 +8832,28 @@
   return Context.getTypeOfExprType(E);
 }
 
+/// getDecltypeForParenthesizedExpr - Given an expr, will return the type for
+/// that expression, as in [dcl.type.simple]p4 but without taking id-expressions
+/// and class member access into account.
+static QualType getDecltypeForParenthesizedExpr(Sema &S, Expr *E) {
+  // C++11 [dcl.type.simple]p4:
+  //   [...]
+  QualType T = E->getType();
+  switch (E->getValueKind()) {
+  //     - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the
+  //       type of e;
+  case VK_XValue:
+    return S.Context.getRValueReferenceType(T);
+  //     - otherwise, if e is an lvalue, decltype(e) is T&, where T is the
+  //       type of e;
+  case VK_LValue:
+    return S.Context.getLValueReferenceType(T);
+  //  - otherwise, decltype(e) is the type of e.
+  case VK_RValue:
+    return T;
+  }
+}
+
 /// getDecltypeForExpr - Given an expr, will return the decltype for
 /// that expression, according to the rules in C++11
 /// [dcl.type.simple]p4 and C++11 [expr.lambda.prim]p18.
@@ -8896,22 +8918,7 @@
     }
   }
 
-
-  // C++11 [dcl.type.simple]p4:
-  //   [...]
-  QualType T = E->getType();
-  switch (E->getValueKind()) {
-  //     - otherwise, if e is an xvalue, decltype(e) is T&&, where T is the
-  //       type of e;
-  case VK_XValue: T = S.Context.getRValueReferenceType(T); break;
-  //     - otherwise, if e is an lvalue, decltype(e) is T&, where T is the
-  //       type of e;
-  case VK_LValue: T = S.Context.getLValueReferenceType(T); break;
-  //  - otherwise, decltype(e) is the type of e.
-  case VK_RValue: break;
-  }
-
-  return T;
+  return getDecltypeForParenthesizedExpr(S, E);
 }
 
 QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc,
@@ -8930,6 +8937,11 @@
   return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
 }
 
+QualType Sema::getCanonicalTypeForParenthesizedExpr(Expr *E) {
+  assert(!E->isInstantiationDependent() && "expression must be non-dependant");
+  return getDecltypeForParenthesizedExpr(*this, E).getCanonicalType();
+}
+
 QualType Sema::BuildUnaryTransformType(QualType BaseType,
                                        UnaryTransformType::UTTKind UKind,
                                        SourceLocation Loc) {
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -8662,10 +8662,8 @@
     //     be satisfied.
     TemplateParameterList *TPL =
         ReturnTypeRequirement.getTypeConstraintTemplateParameterList();
-    QualType MatchedType =
-        BuildDecltypeType(E, E->getBeginLoc()).getCanonicalType();
     llvm::SmallVector<TemplateArgument, 1> Args;
-    Args.push_back(TemplateArgument(MatchedType));
+    Args.push_back(TemplateArgument(getCanonicalTypeForParenthesizedExpr(E)));
     TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args);
     MultiLevelTemplateArgumentList MLTAL(TAL);
     for (unsigned I = 0; I < TPL->getDepth(); ++I)
Index: clang/lib/Sema/SemaConcept.cpp
===================================================================
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -439,18 +439,19 @@
     case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
       ConceptSpecializationExpr *ConstraintExpr =
           Req->getReturnTypeRequirementSubstitutedConstraintExpr();
-      if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1)
+      if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
         // A simple case - expr type is the type being constrained and the concept
         // was not provided arguments.
+        Expr *e = Req->getExpr();
         S.Diag(ConstraintExpr->getBeginLoc(),
                diag::note_expr_requirement_constraints_not_satisfied_simple)
-            << (int)First << S.BuildDecltypeType(Req->getExpr(),
-                                                 Req->getExpr()->getBeginLoc())
+            << (int)First << e << S.getCanonicalTypeForParenthesizedExpr(e)
             << ConstraintExpr->getNamedConcept();
-      else
+      } else {
         S.Diag(ConstraintExpr->getBeginLoc(),
                diag::note_expr_requirement_constraints_not_satisfied)
             << (int)First << ConstraintExpr;
+      }
       S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
       break;
     }
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -2284,6 +2284,7 @@
                              const CXXScopeSpec &SS, QualType T,
                              TagDecl *OwnedTagDecl = nullptr);
 
+  QualType getCanonicalTypeForParenthesizedExpr(Expr *E);
   QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
   /// If AsUnevaluated is false, E is treated as though it were an evaluated
   /// context, such as when building a type for decltype(auto).
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2758,7 +2758,7 @@
 def note_expr_requirement_constraints_not_satisfied : Note<
   "%select{and|because}0 type constraint '%1' was not satisfied:">;
 def note_expr_requirement_constraints_not_satisfied_simple : Note<
-  "%select{and|because}0 %1 does not satisfy %2:">;
+  "%select{and|because}0 'decltype((%1))' (aka %2) does not satisfy %3:">;
 def note_type_requirement_substitution_error : Note<
   "%select{and|because}0 '%1' would be invalid: %2">;
 def note_type_requirement_unknown_substitution_error : Note<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to