This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG703038b35a86: [Sema] Fix volatile check when testing if a return object can be implicitly… (authored by nullptr.cpp, committed by arthur.j.odwyer).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D88295/new/ https://reviews.llvm.org/D88295 Files: clang/lib/Sema/SemaStmt.cpp clang/test/CXX/class/class.init/class.copy.elision/p1.cpp Index: clang/test/CXX/class/class.init/class.copy.elision/p1.cpp =================================================================== --- /dev/null +++ clang/test/CXX/class/class.init/class.copy.elision/p1.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++20 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s + +// - volatile object in return statement don't match the rule for using move +// operation instead of copy operation. Thus should call the copy constructor +// A(const volatile A &). +// +// - volatile object in return statement also don't match the rule for copy +// elision. Thus the copy constructor A(const volatile A &) cannot be elided. +namespace test_volatile { +class A { +public: + A() {} + ~A() {} + A(const volatile A &); + A(volatile A &&); +}; + +A test() { + volatile A a_copy; + // CHECK: call void @_ZN13test_volatile1AC1ERVKS0_ + return a_copy; +} +} // namespace test_volatile Index: clang/lib/Sema/SemaStmt.cpp =================================================================== --- clang/lib/Sema/SemaStmt.cpp +++ clang/lib/Sema/SemaStmt.cpp @@ -3074,12 +3074,13 @@ // variable will no longer be used. if (VD->hasAttr<BlocksAttr>()) return false; + // ...non-volatile... + if (VD->getType().isVolatileQualified()) + return false; + if (CESK & CES_AllowDifferentTypes) return true; - // ...non-volatile... - if (VD->getType().isVolatileQualified()) return false; - // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
Index: clang/test/CXX/class/class.init/class.copy.elision/p1.cpp =================================================================== --- /dev/null +++ clang/test/CXX/class/class.init/class.copy.elision/p1.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++20 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++17 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple x86_64-unknown-linux-gnu -o - %s | FileCheck %s + +// - volatile object in return statement don't match the rule for using move +// operation instead of copy operation. Thus should call the copy constructor +// A(const volatile A &). +// +// - volatile object in return statement also don't match the rule for copy +// elision. Thus the copy constructor A(const volatile A &) cannot be elided. +namespace test_volatile { +class A { +public: + A() {} + ~A() {} + A(const volatile A &); + A(volatile A &&); +}; + +A test() { + volatile A a_copy; + // CHECK: call void @_ZN13test_volatile1AC1ERVKS0_ + return a_copy; +} +} // namespace test_volatile Index: clang/lib/Sema/SemaStmt.cpp =================================================================== --- clang/lib/Sema/SemaStmt.cpp +++ clang/lib/Sema/SemaStmt.cpp @@ -3074,12 +3074,13 @@ // variable will no longer be used. if (VD->hasAttr<BlocksAttr>()) return false; + // ...non-volatile... + if (VD->getType().isVolatileQualified()) + return false; + if (CESK & CES_AllowDifferentTypes) return true; - // ...non-volatile... - if (VD->getType().isVolatileQualified()) return false; - // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits