rnk created this revision.
rnk added a reviewer: rsmith.
Herald added a project: clang.

Allow implementations to provide complete definitions of
std::tuple_size<T>, but to omit the 'value' member to signal that T is
not tuple-like. The Microsoft standard library implements
std::tuple_size<const T> this way.

If the value member exists, clang still validates that it is an ICE, but
if it does not, then the type is considered to not be tuple-like.

Fixes PR33236


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D66040

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp


Index: clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
===================================================================
--- clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
+++ clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
@@ -12,7 +12,7 @@
 
 struct Bad1 { int a, b; };
 template<> struct std::tuple_size<Bad1> {};
-void no_tuple_size_3() { auto [x, y] = Bad1(); } // expected-error {{cannot 
decompose this type; 'std::tuple_size<Bad1>::value' is not a valid integral 
constant expression}}
+void no_tuple_size_3() { auto [x, y] = Bad1(); } // ok, omitting value is 
valid after DR2386
 
 struct Bad2 {};
 template<> struct std::tuple_size<Bad2> { const int value = 5; };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1030,8 +1030,10 @@
   TemplateArgumentListInfo Args(Loc, Loc);
   Args.addArgument(getTrivialTypeTemplateArgument(S, Loc, T));
 
-  // If there's no tuple_size specialization, it's not tuple-like.
-  if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, /*DiagID*/0))
+  // If there's no tuple_size specialization or the lookup of 'value' is empty,
+  // it's not tuple-like.
+  if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, /*DiagID*/ 0) ||
+      R.empty())
     return IsTupleLike::NotTupleLike;
 
   // If we get this far, we've committed to the tuple interpretation, but
@@ -1048,11 +1050,6 @@
     }
   } Diagnoser(R, Args);
 
-  if (R.empty()) {
-    Diagnoser.diagnoseNotICE(S, Loc, SourceRange());
-    return IsTupleLike::Error;
-  }
-
   ExprResult E =
       S.BuildDeclarationNameExpr(CXXScopeSpec(), R, /*NeedsADL*/false);
   if (E.isInvalid())


Index: clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
===================================================================
--- clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
+++ clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
@@ -12,7 +12,7 @@
 
 struct Bad1 { int a, b; };
 template<> struct std::tuple_size<Bad1> {};
-void no_tuple_size_3() { auto [x, y] = Bad1(); } // expected-error {{cannot decompose this type; 'std::tuple_size<Bad1>::value' is not a valid integral constant expression}}
+void no_tuple_size_3() { auto [x, y] = Bad1(); } // ok, omitting value is valid after DR2386
 
 struct Bad2 {};
 template<> struct std::tuple_size<Bad2> { const int value = 5; };
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -1030,8 +1030,10 @@
   TemplateArgumentListInfo Args(Loc, Loc);
   Args.addArgument(getTrivialTypeTemplateArgument(S, Loc, T));
 
-  // If there's no tuple_size specialization, it's not tuple-like.
-  if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, /*DiagID*/0))
+  // If there's no tuple_size specialization or the lookup of 'value' is empty,
+  // it's not tuple-like.
+  if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, /*DiagID*/ 0) ||
+      R.empty())
     return IsTupleLike::NotTupleLike;
 
   // If we get this far, we've committed to the tuple interpretation, but
@@ -1048,11 +1050,6 @@
     }
   } Diagnoser(R, Args);
 
-  if (R.empty()) {
-    Diagnoser.diagnoseNotICE(S, Loc, SourceRange());
-    return IsTupleLike::Error;
-  }
-
   ExprResult E =
       S.BuildDeclarationNameExpr(CXXScopeSpec(), R, /*NeedsADL*/false);
   if (E.isInvalid())
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D66040: [... Reid Kleckner via Phabricator via cfe-commits

Reply via email to