mizvekov updated this revision to Diff 358488.
mizvekov added a comment.
.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D105951/new/
https://reviews.llvm.org/D105951
Files:
clang/lib/Frontend/InitPreprocessor.cpp
clang/lib/Sema/SemaStmt.cpp
clang/test/SemaCXX/Inputs/sys/cxx2b-p2266-disable-with-msvc-compat-sys.hpp
clang/test/SemaCXX/Inputs/usr/cxx2b-p2266-disable-with-msvc-compat-usr.hpp
clang/test/SemaCXX/cxx2b-p2266-disable-with-msvc-compat.cpp
Index: clang/test/SemaCXX/cxx2b-p2266-disable-with-msvc-compat.cpp
===================================================================
--- clang/test/SemaCXX/cxx2b-p2266-disable-with-msvc-compat.cpp
+++ clang/test/SemaCXX/cxx2b-p2266-disable-with-msvc-compat.cpp
@@ -1,50 +1,48 @@
-// RUN: %clang_cc1 -std=c++2b -fsyntax-only -fcxx-exceptions -verify=new %s
-// RUN: %clang_cc1 -std=c++2b -fsyntax-only -fcxx-exceptions -fms-compatibility -verify=old %s
-// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=old %s
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -I %S/Inputs/usr -isystem %S/Inputs/sys -verify=cxx2b,new %s
+// RUN: %clang_cc1 -std=c++2b -fsyntax-only -I %S/Inputs/usr -isystem %S/Inputs/sys -fms-compatibility -verify=cxx2b,old %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -I %S/Inputs/usr -isystem %S/Inputs/sys -verify=cxx20,old %s
// FIXME: This is a test for a temporary workaround where we disable simpler implicit moves
-// when compiling with -fms-compatibility, because the MSVC STL does not compile.
-// A better workaround is under discussion.
-// The test cases here are just a copy from `CXX/class/class.init/class.copy.elision/p3.cpp`,
-// so feel free to delete this file when the workaround is not needed anymore.
-
-struct CopyOnly {
- CopyOnly(); // new-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
- // new-note@-1 {{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
- CopyOnly(CopyOnly &); // new-note {{candidate constructor not viable: expects an lvalue for 1st argument}}
- // new-note@-1 {{candidate constructor not viable: expects an lvalue for 1st argument}}
-};
-struct MoveOnly {
- MoveOnly();
- MoveOnly(MoveOnly &&);
-};
-MoveOnly &&rref();
-
-MoveOnly &&test1(MoveOnly &&w) {
- return w; // old-error {{cannot bind to lvalue of type}}
-}
-
-CopyOnly test2(bool b) {
- static CopyOnly w1;
- CopyOnly w2;
- if (b) {
- return w1;
- } else {
- return w2; // new-error {{no matching constructor for initialization}}
- }
-}
-
-template <class T> T &&test3(T &&x) { return x; } // old-error {{cannot bind to lvalue of type}}
-template MoveOnly &test3<MoveOnly &>(MoveOnly &);
-template MoveOnly &&test3<MoveOnly>(MoveOnly &&); // old-note {{in instantiation of function template specialization}}
-
-MoveOnly &&test4() {
- MoveOnly &&x = rref();
- return x; // old-error {{cannot bind to lvalue of type}}
-}
-
-void test5() try {
- CopyOnly x;
- throw x; // new-error {{no matching constructor for initialization}}
-} catch (...) {
-}
+// in the STL when compiling with -fms-compatibility, because of issues with the
+// implementation there.
+// Feel free to delete this file when the workaround is not needed anymore.
+
+#if __cpluscplus > 202002L && __cpp_implicit_move < 202011L
+#error "__cpp_implicit_move not defined correctly"
+#endif
+
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+
+namespace {
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace
+
+namespace foo {
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+namespace std {
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace std
+} // namespace foo
+
+namespace std {
+
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+
+namespace {
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace
+
+namespace foo {
+int &&mt1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &mt2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace foo
+
+} // namespace std
+#include <cxx2b-p2266-disable-with-msvc-compat-usr.hpp>
+#include <cxx2b-p2266-disable-with-msvc-compat-sys.hpp>
Index: clang/test/SemaCXX/Inputs/usr/cxx2b-p2266-disable-with-msvc-compat-usr.hpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/Inputs/usr/cxx2b-p2266-disable-with-msvc-compat-usr.hpp
@@ -0,0 +1,33 @@
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+
+namespace {
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace
+
+namespace foo {
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+namespace std {
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace std
+} // namespace foo
+
+namespace std {
+
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+
+namespace {
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace
+
+namespace foo {
+int &&ut1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &ut2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace foo
+
+} // namespace std
Index: clang/test/SemaCXX/Inputs/sys/cxx2b-p2266-disable-with-msvc-compat-sys.hpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/Inputs/sys/cxx2b-p2266-disable-with-msvc-compat-sys.hpp
@@ -0,0 +1,33 @@
+int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+
+namespace {
+int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace
+
+namespace foo {
+int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+namespace std {
+int &&st1(int &&x) { return x; } // cxx20-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // cxx2b-error {{cannot bind to a temporary}}
+} // namespace std
+} // namespace foo
+
+namespace std {
+
+int &&st1(int &&x) { return x; } // old-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // new-error {{cannot bind to a temporary}}
+
+namespace {
+int &&st1(int &&x) { return x; } // old-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // new-error {{cannot bind to a temporary}}
+} // namespace
+
+namespace foo {
+int &&st1(int &&x) { return x; } // old-error {{cannot bind to lvalue}}
+int &st2(int &&x) { return x; } // new-error {{cannot bind to a temporary}}
+} // namespace foo
+
+} // namespace std
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -3307,6 +3307,21 @@
return new (Context) BreakStmt(BreakLoc);
}
+static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S,
+ const Expr &E) {
+ if (!S.getLangOpts().MSVCCompat)
+ return false;
+ const Decl *D = E.getReferencedDeclOfCallee();
+ if (!S.SourceMgr.isInSystemHeader(D->getLocation()))
+ return false;
+ for (const DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) {
+ if (const auto *NS = dyn_cast<NamespaceDecl>(DC))
+ if (NS->isStdNamespace())
+ return true;
+ }
+ return false;
+}
+
/// Determine whether the given expression might be move-eligible or
/// copy-elidable in either a (co_)return statement or throw expression,
/// without considering function return type, if applicable.
@@ -3338,8 +3353,8 @@
// as the MSVC STL has issues with this change.
// We will come back later with a more targeted approach.
if (Res.Candidate && !E->isXValue() &&
- (ForceCXX2b ||
- (getLangOpts().CPlusPlus2b && !getLangOpts().MSVCCompat))) {
+ (ForceCXX2b || (getLangOpts().CPlusPlus2b &&
+ !CheckSimplerImplicitMovesMSVCWorkaround(*this, *E)))) {
E = ImplicitCastExpr::Create(Context, VD->getType().getNonReferenceType(),
CK_NoOp, E, nullptr, VK_XValue,
FPOptionsOverride());
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -598,8 +598,7 @@
}
// C++2b features.
if (LangOpts.CPlusPlus2b) {
- if (!LangOpts.MSVCCompat)
- Builder.defineMacro("__cpp_implicit_move", "202011L");
+ Builder.defineMacro("__cpp_implicit_move", "202011L");
Builder.defineMacro("__cpp_size_t_suffix", "202011L");
}
if (LangOpts.Char8)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits