[llvm-branch-commits] [cfe-branch] r369361 - Merging r369043:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 20 03:00:41 PDT 2019


Author: hans
Date: Tue Aug 20 03:00:41 2019
New Revision: 369361

URL: http://llvm.org/viewvc/llvm-project?rev=369361&view=rev
Log:
Merging r369043:
------------------------------------------------------------------------
r369043 | rnk | 2019-08-15 21:45:28 +0200 (Thu, 15 Aug 2019) | 15 lines

[Sema] Implement DR2386 for C++17 structured binding

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

Reviewers: rsmith

Differential Revision: https://reviews.llvm.org/D66040
------------------------------------------------------------------------

Modified:
    cfe/branches/release_90/   (props changed)
    cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp
    cfe/branches/release_90/test/CXX/dcl.decl/dcl.decomp/p3.cpp
    cfe/branches/release_90/test/CXX/drs/dr23xx.cpp

Propchange: cfe/branches/release_90/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Aug 20 03:00:41 2019
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:366429,366448,366457,366474,366480,366483,366511,366670,366694,366699,366878,367008,367039,367055,367103,367134,367301,367305,367323,367387,367403,367520,367530,367661,367675,367802,367823,367906,368104,368202,368552,368561,368874,368940
+/cfe/trunk:366429,366448,366457,366474,366480,366483,366511,366670,366694,366699,366878,367008,367039,367055,367103,367134,367301,367305,367323,367387,367403,367520,367530,367661,367675,367802,367823,367906,368104,368202,368552,368561,368874,368940,369043
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp?rev=369361&r1=369360&r2=369361&view=diff
==============================================================================
--- cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp Tue Aug 20 03:00:41 2019
@@ -1030,8 +1030,10 @@ static IsTupleLike isTupleLike(Sema &S,
   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 @@ static IsTupleLike isTupleLike(Sema &S,
     }
   } 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())

Modified: cfe/branches/release_90/test/CXX/dcl.decl/dcl.decomp/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/test/CXX/dcl.decl/dcl.decomp/p3.cpp?rev=369361&r1=369360&r2=369361&view=diff
==============================================================================
--- cfe/branches/release_90/test/CXX/dcl.decl/dcl.decomp/p3.cpp (original)
+++ cfe/branches/release_90/test/CXX/dcl.decl/dcl.decomp/p3.cpp Tue Aug 20 03:00:41 2019
@@ -12,7 +12,7 @@ void no_tuple_size_2() { auto [x, y] = A
 
 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; };

Modified: cfe/branches/release_90/test/CXX/drs/dr23xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/test/CXX/drs/dr23xx.cpp?rev=369361&r1=369360&r2=369361&view=diff
==============================================================================
--- cfe/branches/release_90/test/CXX/drs/dr23xx.cpp (original)
+++ cfe/branches/release_90/test/CXX/drs/dr23xx.cpp Tue Aug 20 03:00:41 2019
@@ -40,6 +40,27 @@ namespace dr2353 { // dr2353: 9
 #pragma clang __debug dump not_use_2
 }
 
+#if __cplusplus >= 201707L
+// Otherwise, if the qualified-id std::tuple_size<E> names a complete class
+// type **with a member value**, the expression std::tuple_size<E>::value shall
+// be a well-formed integral constant expression
+namespace dr2386 { // dr2386: 9
+struct Bad1 { int a, b; };
+struct Bad2 { int a, b; };
+} // namespace dr2386
+namespace std {
+template <typename T> struct tuple_size;
+template <> struct std::tuple_size<dr2386::Bad1> {};
+template <> struct std::tuple_size<dr2386::Bad2> {
+  static const int value = 42;
+};
+} // namespace std
+namespace dr2386 {
+void no_value() { auto [x, y] = Bad1(); }
+void wrong_value() { auto [x, y] = Bad2(); } // expected-error {{decomposes into 42 elements}}
+} // namespace dr2386
+#endif
+
 namespace dr2387 { // dr2387: 9
 #if __cplusplus >= 201402L
   template<int> int a = 0;




More information about the llvm-branch-commits mailing list