[PATCH] D41655: [clang-tidy] New check bugprone-unused-return-value
khuttun added a comment. > From what I can tell of these reports, they almost all boil down to ignoring > the call to `release()` because the pointer is no longer owned by the > `unique_ptr`. This is a pretty reasonable code pattern, but it also seems > reasonable to expect users to cast the result to `void` to silence the > warning, so I think this is fine. Have you checked any other large C++ code > bases, like Qt or boost? Yep, there's already code also in LLVM where the release() return value is cast to void, for example in lib/Bitcode/Reader/BitReader.cpp. I haven't run the checker on other large code bases yet, but I can test also that. Comment at: clang-tidy/bugprone/UnusedReturnValueCheck.cpp:45-48 +"^::std::async$|" +"^::std::launder$|" +"^::std::remove$|" +"^::std::remove_if$|" alexfh wrote: > alexfh wrote: > > I strongly suspect that we could get away without regexs here. hasAnyName > > supports inline namespaces, so at least the first five entries here are > > covered. The main problem with std::unique_ptr<.*>::release is the need to > > match any template parameters. I *think*, we could adjust hasName to allow > > omitting template parameters (so that `std::unique_ptr::release` would > > match specializations of unique_ptr as well). The `empty` and `allocate` > > would need some research. Can we just list all specific classes where we > > care about `empty`? (Alternatively, can we match `empty` unqualified and > > check that it's somewhere inside `std`, but I don't like that much, since > > it would add inconsistency in how this check is configured.) > A clarification: we could go with your current version and optimize this part > later. But the option may start being used by someone and then will change - > that would be nice to avoid. > > Alternatively, we could switch to hasAnyName right away and leave only the > functions that can be easily supported, and then figure out what to do with > `release`, `allocate` and `empty`. > > I'd probably prefer the latter. If the ultimate goal would be to have this checker working without regexes, then I agree that we shouldn't introduce a version that uses them in the config string, as changing that later would break things. About creating a version of hasName that ignores template arguments: as I understand it we'd need a new PrintingPolicy to suppress printing the template argument list in NamedDecl::printQualifiedName. Is this correct? WG21 P0600R1 lists 8 allocate() and 24 empty() functions in std that should be marked with [[nodiscard]]. We could list all of them separately in the checker config, but the config string would get quite long. Regex matching handles these nicely, but if the performance is unacceptable, we have to look for other ways or just skip checking these. https://reviews.llvm.org/D41655 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
r324170 - [RISCV] Create a LinuxTargetInfo when targeting Linux
Author: asb Date: Sat Feb 3 03:56:11 2018 New Revision: 324170 URL: http://llvm.org/viewvc/llvm-project?rev=324170&view=rev Log: [RISCV] Create a LinuxTargetInfo when targeting Linux Previously, RISCV32TargetInfo or RISCV64TargetInfo were created unconditionally. Use LinuxTargetInfo to ensure that the proper OS-specific defines are present. This patch only adds logic to instantiate LinuxTargetInfo and leaves a TODO, as I'm reluctant to add logic for other targets (e.g. FreeBSD, RTEMS) until I've produced and tested at least one binary for that OS+target combo. Thanks to @mgrang to reporting the issue. Modified: cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/test/Preprocessor/init.c Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=324170&r1=324169&r2=324170&view=diff == --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Sat Feb 3 03:56:11 2018 @@ -372,8 +372,14 @@ TargetInfo *AllocateTarget(const llvm::T return new AMDGPUTargetInfo(Triple, Opts); case llvm::Triple::riscv32: +// TODO: add cases for FreeBSD, NetBSD, RTEMS once tested. +if (os == llvm::Triple::Linux) + return new LinuxTargetInfo(Triple, Opts); return new RISCV32TargetInfo(Triple, Opts); case llvm::Triple::riscv64: +// TODO: add cases for FreeBSD, NetBSD, RTEMS once tested. +if (os == llvm::Triple::Linux) + return new LinuxTargetInfo(Triple, Opts); return new RISCV64TargetInfo(Triple, Opts); case llvm::Triple::sparc: Modified: cfe/trunk/test/Preprocessor/init.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/init.c?rev=324170&r1=324169&r2=324170&view=diff == --- cfe/trunk/test/Preprocessor/init.c (original) +++ cfe/trunk/test/Preprocessor/init.c Sat Feb 3 03:56:11 2018 @@ -10005,6 +10005,8 @@ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv32 < /dev/null \ // RUN: | FileCheck -match-full-lines -check-prefix=RISCV32 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv32-unknown-linux < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=RISCV32,RISCV32-LINUX %s // RISCV32: #define _ILP32 1 // RISCV32: #define __ATOMIC_ACQUIRE 2 // RISCV32: #define __ATOMIC_ACQ_REL 4 @@ -10196,13 +10198,22 @@ // RISCV32: #define __WINT_TYPE__ unsigned int // RISCV32: #define __WINT_UNSIGNED__ 1 // RISCV32: #define __WINT_WIDTH__ 32 +// RISCV32-LINUX: #define __gnu_linux__ 1 +// RISCV32-LINUX: #define __linux 1 +// RISCV32-LINUX: #define __linux__ 1 // RISCV32: #define __riscv 1 // RISCV32: #define __riscv_cmodel_medlow 1 // RISCV32: #define __riscv_float_abi_soft 1 // RISCV32: #define __riscv_xlen 32 +// RISCV32-LINUX: #define __unix 1 +// RISCV32-LINUX: #define __unix__ 1 +// RISCV32-LINUX: #define linux 1 +// RISCV32-LINUX: #define unix 1 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv64 < /dev/null \ // RUN: | FileCheck -match-full-lines -check-prefix=RISCV64 %s +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=riscv64-unknown-linux < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefixes=RISCV64,RISCV64-LINUX %s // RISCV64: #define _LP64 1 // RISCV64: #define __ATOMIC_ACQUIRE 2 // RISCV64: #define __ATOMIC_ACQ_REL 4 @@ -10394,7 +10405,14 @@ // RISCV64: #define __WINT_TYPE__ unsigned int // RISCV64: #define __WINT_UNSIGNED__ 1 // RISCV64: #define __WINT_WIDTH__ 32 +// RISCV64-LINUX: #define __gnu_linux__ 1 +// RISCV64-LINUX: #define __linux 1 +// RISCV64-LINUX: #define __linux__ 1 // RISCV64: #define __riscv 1 // RISCV64: #define __riscv_cmodel_medlow 1 // RISCV64: #define __riscv_float_abi_soft 1 // RISCV64: #define __riscv_xlen 64 +// RISCV64-LINUX: #define __unix 1 +// RISCV64-LINUX: #define __unix__ 1 +// RISCV64-LINUX: #define linux 1 +// RISCV64-LINUX: #define unix 1 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42745: [analyzer] Add support for __builtin_constant_p to BuiltinFunctionChecker
sp4r74n-117 updated this revision to Diff 132738. sp4r74n-117 added a comment. Thanks for the feedback. I've added two additional tests to 'test_constant_p' for the case where an expression evaluating to a constant 0 is passed to the builtin. The existing tests have been refactored to check explicitly for 0 or 1 instead of relying on the implicit boolean conversion. https://reviews.llvm.org/D42745 Files: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp test/Analysis/builtin-functions.cpp Index: test/Analysis/builtin-functions.cpp === --- test/Analysis/builtin-functions.cpp +++ test/Analysis/builtin-functions.cpp @@ -64,3 +64,20 @@ // We give up the analysis on this path. } } + +void test_constant_p() { + int i = 1; + const int j = 2; + constexpr int k = 3; + clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}} + clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}} +} Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp === --- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -113,6 +113,24 @@ C.addTransition(state->BindExpr(CE, LCtx, V)); return true; } + + case Builtin::BI__builtin_constant_p: { +SVal V; +SValBuilder& SVB = C.getSValBuilder(); + +llvm::APSInt Result; +// Model semantics as 'A return of 0 does not indicate that the value is +// not a constant, but merely that GCC cannot prove it is a constant [...]' +if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) { + SVB.getBasicValueFactory().getAPSIntType(CE->getType()).apply(Result); + V = SVB.makeIntVal(Result); +} +else + V = SVB.makeZeroVal(CE->getType()); + +C.addTransition(state->BindExpr(CE, LCtx, V)); +return true; + } } } Index: test/Analysis/builtin-functions.cpp === --- test/Analysis/builtin-functions.cpp +++ test/Analysis/builtin-functions.cpp @@ -64,3 +64,20 @@ // We give up the analysis on this path. } } + +void test_constant_p() { + int i = 1; + const int j = 2; + constexpr int k = 3; + clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}} + clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}} +} Index: lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp === --- lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp +++ lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp @@ -113,6 +113,24 @@ C.addTransition(state->BindExpr(CE, LCtx, V)); return true; } + + case Builtin::BI__builtin_constant_p: { +SVal V; +SValBuilder& SVB = C.getSValBuilder(); + +llvm::APSInt Result; +// Model semantics as 'A return of 0 does not indicate that the value is +// not a constant, but merely that GCC cannot prove it is a constant [...]' +if (CE->EvaluateAsInt(Result, C.getASTContext(), Expr::SE_NoSideEffects)) { + SVB.getBasicValueFactory().getAPSIntType(CE->getType()).apply(Result); + V = SVB.makeIntVal(Resul
r324173 - Recommit rL323952: [DebugInfo] Enable debug information for C99 VLA types.
Author: s.desmalen Date: Sat Feb 3 05:55:59 2018 New Revision: 324173 URL: http://llvm.org/viewvc/llvm-project?rev=324173&view=rev Log: Recommit rL323952: [DebugInfo] Enable debug information for C99 VLA types. Fixed build issue when building with g++-4.8 (specialization after instantiation). Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/CodeGen/CGOpenMPRuntime.cpp cfe/trunk/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/CodeGen/debug-info-vla.c cfe/trunk/test/CodeGenCXX/debug-info-vla.cpp cfe/trunk/test/CodeGenCXX/vla-consruct.cpp cfe/trunk/test/CodeGenObjC/arc.m cfe/trunk/test/OpenMP/target_codegen.cpp cfe/trunk/test/OpenMP/target_parallel_codegen.cpp cfe/trunk/test/OpenMP/target_parallel_for_codegen.cpp cfe/trunk/test/OpenMP/target_parallel_for_simd_codegen.cpp cfe/trunk/test/OpenMP/target_simd_codegen.cpp cfe/trunk/test/OpenMP/target_teams_codegen.cpp cfe/trunk/test/OpenMP/target_teams_distribute_codegen.cpp cfe/trunk/test/OpenMP/target_teams_distribute_simd_codegen.cpp Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=324173&r1=324172&r2=324173&view=diff == --- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Sat Feb 3 05:55:59 2018 @@ -1479,8 +1479,8 @@ CodeGenFunction::GenerateBlockFunction(G const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable); if (capture.isConstant()) { auto addr = LocalDeclMap.find(variable)->second; - DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(), -Builder); + (void)DI->EmitDeclareOfAutoVariable(variable, addr.getPointer(), + Builder); continue; } Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=324173&r1=324172&r2=324173&view=diff == --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sat Feb 3 05:55:59 2018 @@ -2292,12 +2292,14 @@ llvm::DIType *CGDebugInfo::CreateType(co llvm::DIFile *Unit) { llvm::DIType *ElementTy = getOrCreateType(Ty->getElementType(), Unit); int64_t Count = Ty->getNumElements(); - if (Count == 0) -// If number of elements are not known then this is an unbounded array. -// Use Count == -1 to express such arrays. -Count = -1; - llvm::Metadata *Subscript = DBuilder.getOrCreateSubrange(0, Count); + llvm::Metadata *Subscript; + QualType QTy(Ty, 0); + auto SizeExpr = SizeExprCache.find(QTy); + if (SizeExpr != SizeExprCache.end()) +Subscript = DBuilder.getOrCreateSubrange(0, SizeExpr->getSecond()); + else +Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1); llvm::DINodeArray SubscriptArray = DBuilder.getOrCreateArray(Subscript); uint64_t Size = CGM.getContext().getTypeSize(Ty); @@ -2354,8 +2356,12 @@ llvm::DIType *CGDebugInfo::CreateType(co } } -// FIXME: Verify this is right for VLAs. -Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count)); +auto SizeNode = SizeExprCache.find(EltTy); +if (SizeNode != SizeExprCache.end()) + Subscripts.push_back( + DBuilder.getOrCreateSubrange(0, SizeNode->getSecond())); +else + Subscripts.push_back(DBuilder.getOrCreateSubrange(0, Count)); EltTy = Ty->getElementType(); } @@ -3473,13 +3479,14 @@ llvm::DIType *CGDebugInfo::EmitTypeForVa nullptr, Elements); } -void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::Value *Storage, - llvm::Optional ArgNo, - CGBuilderTy &Builder) { +llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD, +llvm::Value *Storage, +llvm::Optional ArgNo, +CGBuilderTy &Builder) { assert(DebugKind >= codegenoptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); if (VD->hasAttr()) -return; +return nullptr; bool Unwritten = VD->isImplicit() || (isa(VD->getDeclContext()) && @@ -3497,7 +3504,7 @@ void CGDebugInfo::EmitDeclare(const VarD // If there is
[PATCH] D40787: [clang-tidy] Replace the usage of std::uncaught_exception with std::uncaught_exceptions
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. This LGTM with a few minor nits to fix. Comment at: clang-tidy/modernize/ModernizeTidyModule.cpp:80-81 CheckFactories.registerCheck("modernize-use-override"); +CheckFactories.registerCheck( +"modernize-use-uncaught-exceptions"); CheckFactories.registerCheck( Please keep this list alphabetized. Comment at: docs/clang-tidy/checks/modernize-use-uncaught-exceptions.rst:19 +int uncaught_exception() { +return 0; +} The indentation of the code examples (here and below) is incorrect. https://reviews.llvm.org/D40787 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41217: [Concepts] Concept Specialization Expressions
saar.raz updated this revision to Diff 132743. saar.raz added a comment. Herald added subscribers: hintonda, mgorny. - Moved general concepts-related function into SemaConcept.cpp Repository: rC Clang https://reviews.llvm.org/D41217 Files: include/clang/AST/DeclTemplate.h include/clang/AST/ExprCXX.h include/clang/AST/RecursiveASTVisitor.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/StmtNodes.td include/clang/Sema/Sema.h include/clang/Serialization/ASTBitCodes.h lib/AST/Expr.cpp lib/AST/ExprCXX.cpp lib/AST/ExprClassification.cpp lib/AST/ExprConstant.cpp lib/AST/ItaniumMangle.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtProfile.cpp lib/CodeGen/CGExprScalar.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseTemplate.cpp lib/Sema/CMakeLists.txt lib/Sema/SemaConcept.cpp lib/Sema/SemaExceptionSpec.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplate.cpp lib/Sema/TreeTransform.h lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp test/Parser/cxx-concept-declaration.cpp tools/libclang/CXCursor.cpp Index: tools/libclang/CXCursor.cpp === --- tools/libclang/CXCursor.cpp +++ tools/libclang/CXCursor.cpp @@ -231,6 +231,7 @@ case Stmt::TypeTraitExprClass: case Stmt::CoroutineBodyStmtClass: case Stmt::CoawaitExprClass: + case Stmt::ConceptSpecializationExprClass: case Stmt::DependentCoawaitExprClass: case Stmt::CoreturnStmtClass: case Stmt::CoyieldExprClass: Index: test/Parser/cxx-concept-declaration.cpp === --- test/Parser/cxx-concept-declaration.cpp +++ test/Parser/cxx-concept-declaration.cpp @@ -9,8 +9,6 @@ template concept D1 = true; // expected-error {{expected template parameter}} -template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}} - struct S1 { template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}} }; @@ -29,3 +27,12 @@ // TODO: Add test to prevent explicit specialization, partial specialization // and explicit instantiation of concepts. + +template concept C7 = 2; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}} +template concept C8 = 2 && x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}} +template concept C9 = x || 2 || x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}} +template concept C10 = 8ull && x || x; // expected-error {{atomic constraint '8ULL' must be of type 'bool' (found 'unsigned long long')}} +template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}} +template concept C12 = T{}; +template concept C13 = (bool&&)true; +template concept C14 = (const bool&)true; Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp === --- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp +++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp @@ -1,5 +1,52 @@ // RUN: %clang_cc1 -std=c++2a -fconcepts-ts -verify %s -// expected-no-diagnostics -template concept C = true; -static_assert(C); +template concept C1 = true; +static_assert(C1); + +template concept C2 = sizeof(T) == 4; +static_assert(C2); +static_assert(!C2); +static_assert(C2); +static_assert(!C2); + +template concept C3 = sizeof(*T{}) == 4; +static_assert(C3); +static_assert(!C3); + +struct A { +static constexpr int add(int a, int b) { +return a + b; +} +}; +struct B { +static int add(int a, int b) { +return a + b; +} +}; +template +concept C4 = U::add(1, 2) == 3; +static_assert(C4); +static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}} + +template +constexpr bool is_same_v = false; + +template +constexpr bool is_same_v = true; + +template +concept Same = is_same_v; + +static_assert(Same); +static_assert(Same); +static_assert(!Same); +static_assert(!Same); +static_assert(Same); + +static_assert(Same)>); +static_assert(Same)>); +static_assert(Same)>); +static_assert(Same)>); + +template concept C5 = T{}; // expected-error {{atomic constraint 'int{}' must be of type 'bool' (found 'int')}} +constexpr bool x = C5; // expected-note {{in concept specialization 'C5'}} Index: lib/StaticAnalyzer/Core/ExprEngine.cpp === --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1018,6 +1018,7 @@ case Stmt::CUDAKernelCallExprClass: case Stmt::OpaqueValueExprClass: case Stmt::AsTypeExprClass: +case Stmt::ConceptSpecializationExprClass: // Fall through.
[PATCH] D41889: [libcxxabi][demangler] Clean up and llvm-ify the type parser
erik.pilkington updated this revision to Diff 132747. erik.pilkington added a comment. Rebase and remove the qualifier substitution bug fix. https://reviews.llvm.org/D41889 Files: src/cxa_demangle.cpp Index: src/cxa_demangle.cpp === --- src/cxa_demangle.cpp +++ src/cxa_demangle.cpp @@ -340,20 +340,17 @@ class VendorExtQualType final : public Node { const Node *Ty; - const Node *Ext; + StringView Ext; public: - VendorExtQualType(Node *Ty_, Node *Ext_) - : Node(KVendorExtQualType, - std::min(Ty_->ParameterPackSize, Ext_->ParameterPackSize)), + VendorExtQualType(Node *Ty_, StringView Ext_) + : Node(KVendorExtQualType, Ty_->ParameterPackSize), Ty(Ty_), Ext(Ext_) {} - const Node* getQual() const { return Ext; } - void printLeft(OutputStream &S) const override { Ty->print(S); S += " "; -Ext->print(S); +S += Ext; } }; @@ -465,12 +462,12 @@ class ObjCProtoName : public Node { Node *Ty; - Node *Protocol; + StringView Protocol; friend class PointerType; public: - ObjCProtoName(Node *Ty_, Node *Protocol_) + ObjCProtoName(Node *Ty_, StringView Protocol_) : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {} bool isObjCObject() const { @@ -481,7 +478,7 @@ void printLeft(OutputStream &S) const override { Ty->print(S); S += "<"; -Protocol->print(S); +S += Protocol; S += ">"; } }; @@ -512,7 +509,7 @@ } else { const auto *objcProto = static_cast(Pointee); s += "id<"; - objcProto->Protocol->print(s); + s += objcProto->Protocol; s += ">"; } } @@ -1958,6 +1955,8 @@ StringView parseNumber(bool AllowNegative = false); Qualifiers parseCVQualifiers(); + bool parsePositiveInteger(size_t *Out); + StringView parseBareSourceName(); /// Parse the production. Node *parseExpr(); @@ -1970,6 +1969,15 @@ Node *parseNewExpr(); Node *parseConversionExpr(); + /// Parse the production. + Node *parseType(); + Node *parseFunctionType(); + Node *parseVectorType(); + Node *parseDecltype(); + Node *parseArrayType(); + Node *parsePointerToMemberType(); + Node *parseClassEnumType(); + // FIXME: remove this when all the parse_* functions have been rewritten. template Node *legacyParse() { @@ -1983,6 +1991,18 @@ Names.pop_back(); return R; } + template + Node *legacyParse() { +size_t BeforeType = Names.size(); +const char *OrigFirst = First; +const char *T = parse_fn(First, Last, *this, nullptr); +if (T == OrigFirst || BeforeType + 1 != Names.size()) + return nullptr; +First = T; +Node *R = Names.back(); +Names.pop_back(); +return R; + } }; const char *parse_expression(const char *first, const char *last, Db &db) { @@ -2005,6 +2025,26 @@ return db.First; } +const char *parse_type(const char *first, const char *last, Db &db) { + db.First = first; + db.Last = last; + Node *R = db.parseType(); + if (R == nullptr) +return first; + db.Names.push_back(R); + return db.First; +} + +const char *parse_decltype(const char *first, const char *last, Db &db) { + db.First = first; + db.Last = last; + Node *R = db.parseDecltype(); + if (R == nullptr) +return first; + db.Names.push_back(R); + return db.First; +} + const char *parse_type(const char *first, const char *last, Db &db); const char *parse_encoding(const char *first, const char *last, Db &db); const char *parse_name(const char *first, const char *last, Db &db, @@ -2015,6 +2055,7 @@ const char *parse_unqualified_name(const char *first, const char *last, Db &db); const char *parse_decltype(const char *first, const char *last, Db &db); const char *parse_unresolved_name(const char *, const char *, Db &); +const char *parse_substitution(const char *, const char *, Db &); // ::= [n] StringView Db::parseNumber(bool AllowNegative) { @@ -2028,6 +2069,541 @@ return StringView(Tmp, First); } +// ::= [0-9]* +bool Db::parsePositiveInteger(size_t *Out) { + *Out = 0; + if (look() < '0' || look() > '9') +return true; + while (look() >= '0' && look() <= '9') { +*Out *= 10; +*Out += static_cast(consume() - '0'); + } + return false; +} + +StringView Db::parseBareSourceName() { + size_t Int = 0; + if (parsePositiveInteger(&Int) || numLeft() < Int) +return StringView(); + StringView R(First, First + Int); + First += Int; + return R; +} + +// ::= F [Y] [] E +// +// ::= R # & ref-qualifier +// ::= O # && ref-qualifier +Node *Db::parseFunctionType() { + if (!consumeIf('F')) +return nullptr; + consumeIf('Y'); // extern "C" + Node *ReturnType = parseType(); + if (ReturnType == nullptr) +return nullptr; + + FunctionRefQual ReferenceQualifier = FrefQualNone; + size_t ParamsBegin = Names.size(); + while (true) { +if (consumeIf('E')) + break; +if (cons
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 132748. saar.raz added a comment. Moved function into SemaConcept.cpp. Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} + template class TT> requires TT::happy // expected-note {
[PATCH] D41217: [Concepts] Concept Specialization Expressions
Quuxplusone added inline comments. Comment at: include/clang/Basic/DiagnosticSemaKinds.td:2404 +def err_concept_non_constant_constraint_expression : Error< + "concept specialization '%0' resulted in a non-constant expression '%1'.">; +def err_non_bool_atomic_constraint : Error< Extra period `.` here Comment at: lib/Serialization/ASTReaderStmt.cpp:4053 +case EXPR_CONCEPT_SPECIALIZATION: + S = new (Context) ConceptSpecializationExpr(Context); + break; Peanut gallery says: All the other cases look like S = new (Context) FooExpr(Context, Empty); or S = new (Context) FooExpr::CreateEmpty(Context); not S = new (Context) FooExpr(Context); Is the visual difference in this case significant? Comment at: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp:12 + +template concept C3 = sizeof(*T{}) == 4; +static_assert(C3); "test/Parser/cxx-concept-declaration.cpp" has some syntax tests for "value-concepts" of the form `template concept...`. Would it make sense to add some semantic tests for `template concept...` in or near this test file? (This could plausibly be "out of scope." I merely mention it.) Comment at: test/Parser/cxx-concept-declaration.cpp:36 +template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}} +template concept C12 = T{}; +template concept C13 = (bool&&)true; Peanut gallery says: IIUC, C12 is satisfied whenever T has a constexpr constructor and a constexpr implicit conversion to `bool` that returns `true`? Or (because this is an atomic constraint and atomic constraints don't do conversions, as we can see on line 31 above) is C12 *actually* never satisfiable (but there's no diagnostic expected here because `T{}` is dependent)? Repository: rC Clang https://reviews.llvm.org/D41217 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41217: [Concepts] Concept Specialization Expressions
saar.raz added inline comments. Comment at: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp:12 + +template concept C3 = sizeof(*T{}) == 4; +static_assert(C3); Quuxplusone wrote: > "test/Parser/cxx-concept-declaration.cpp" has some syntax tests for > "value-concepts" of the form `template concept...`. Would it make > sense to add some semantic tests for `template concept...` in or near > this test file? > (This could plausibly be "out of scope." I merely mention it.) Good idea, I'll add some of those. Comment at: test/Parser/cxx-concept-declaration.cpp:36 +template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}} +template concept C12 = T{}; +template concept C13 = (bool&&)true; Quuxplusone wrote: > Peanut gallery says: IIUC, C12 is satisfied whenever T has a constexpr > constructor and a constexpr implicit conversion to `bool` that returns > `true`? Or (because this is an atomic constraint and atomic constraints > don't do conversions, as we can see on line 31 above) is C12 *actually* > never satisfiable (but there's no diagnostic expected here because `T{}` is > dependent)? C12 will only accept bool, and there's no diagnostic because it's dependent is correct. Repository: rC Clang https://reviews.llvm.org/D41217 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.
EricWF created this revision. EricWF added reviewers: erichkeane, aaron.ballman, lebedev.ri. Currently, assertion-disabled Clang builds emit value names when generating LLVM IR. This is controlled by the `NDEBUG` macro, and is not easily overridable. In order to get IR output containing names from a release build of Clang, the user must manually construct the CC1 invocation w/o the `-discard-value-names` option. This is less than ideal. For example, Godbolt uses a release build of Clang, and so when asked to emit LLVM IR the result lacks names, making it harder to read. Manually invoking CC1 on Compiler Explorer is not feasible. This patch adds the driver options `-fdiscard-value-names` and `-fno-discard-value-names` which allow the user to override the default behavior. If neither is specified, the old behavior remains. https://reviews.llvm.org/D42887 Files: docs/UsersManual.rst include/clang/Driver/Options.td lib/Driver/ToolChains/Clang.cpp test/Driver/clang_f_opts.c Index: test/Driver/clang_f_opts.c === --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -517,3 +517,8 @@ // RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s // CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch // CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch + +// RUN: %clang -### -S -fdiscard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-DISCARD-NAMES %s +// RUN: %clang -### -S -fno-discard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-NO-DISCARD-NAMES %s +// CHECK-DISCARD-NAMES: "-discard-value-names" +// CHECK-NO-DISCARD-NAMES-NOT: "-discard-value-names" Index: lib/Driver/ToolChains/Clang.cpp === --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3266,12 +3266,23 @@ if (!C.isForDiagnostics()) CmdArgs.push_back("-disable-free"); -// Disable the verification pass in -asserts builds. + const bool IsAssertBuild = #ifdef NDEBUG - CmdArgs.push_back("-disable-llvm-verifier"); - // Discard LLVM value names in -asserts builds. - CmdArgs.push_back("-discard-value-names"); + true; +#else + false; #endif + // Disable the verification pass in -asserts builds. + if (IsAssertBuild) +CmdArgs.push_back("disable-llvm-verifier"); + + // Discard value names in assert builds unless otherwise specified. + if (const Arg *A = Args.getLastArg(options::OPT_fdiscard_value_names, + options::OPT_fno_discard_value_names)) { +if (A->getOption().matches(options::OPT_fdiscard_value_names)) + CmdArgs.push_back("-discard-value-names"); + } else if (IsAssertBuild) +CmdArgs.push_back("-discard-value-names"); // Set the main file name, so that debug info works even with // -save-temps. Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -790,6 +790,10 @@ HelpText<"Print a template comparison tree for differing templates">; def fdeclspec : Flag<["-"], "fdeclspec">, Group, HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>; +def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, Group, + HelpText<"Discard value names in LLVM IR">, Flags<[DriverOption]>; +def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">, Group, + HelpText<"Do not discard value names in LLVM IR">, Flags<[DriverOption]>; def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group, HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group; Index: docs/UsersManual.rst === --- docs/UsersManual.rst +++ docs/UsersManual.rst @@ -1855,6 +1855,27 @@ must come first.) +Controlling LLVM IR Output +--- + +Controlling Values Names in LLVM IR + + +Emitting value names in LLVM IR increases the size and verbosity of the IR. +By default value names are only emitted in assertion enabled builds of Clang. +However, when reading IR it can be useful to re-enable the emission of value +names to improve readability. + +.. option:: -fdiscard-value-names + + Discard value names when generating LLVM IR. + +.. option:: -fno-discard-value-names + + Do not discard value names when generating LLVM IR. This option can be used + to re-enable names for release builds of Clang. + + Comment Parsing Options --- Index: test/Driver/clang_f_opts.c === --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -517,3 +517,8 @@ // RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s //
[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.
lebedev.ri added inline comments. Comment at: lib/Driver/ToolChains/Clang.cpp:3269 -// Disable the verification pass in -asserts builds. + const bool IsAssertBuild = #ifdef NDEBUG This logic seems sidewards. If `NDEBUG` is specified, then it is `assert()`-less build. If `NDEBUG` is *not* specified, then `assert()`'s are actually functional. Comment at: lib/Driver/ToolChains/Clang.cpp:3270 -// Disable the verification pass in -asserts builds. + const bool IsAssertBuild = #ifdef NDEBUG - CmdArgs.push_back("-disable-llvm-verifier"); `-assert` is `assert()`-less build https://reviews.llvm.org/D42887 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.
EricWF marked an inline comment as done. EricWF added inline comments. Comment at: lib/Driver/ToolChains/Clang.cpp:3269 -// Disable the verification pass in -asserts builds. + const bool IsAssertBuild = #ifdef NDEBUG lebedev.ri wrote: > This logic seems sidewards. > If `NDEBUG` is specified, then it is `assert()`-less build. > If `NDEBUG` is *not* specified, then `assert()`'s are actually functional. > Woops! Silly me. Thats a dumb mistake and I feel dumb having made it. https://reviews.llvm.org/D42887 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42887: [Driver] Add option to manually control discarding value names in LLVM IR.
EricWF updated this revision to Diff 132752. EricWF marked an inline comment as done. EricWF added a comment. - Address really really really dumb mistake. https://reviews.llvm.org/D42887 Files: docs/UsersManual.rst include/clang/Driver/Options.td lib/Driver/ToolChains/Clang.cpp test/Driver/clang_f_opts.c Index: test/Driver/clang_f_opts.c === --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -517,3 +517,8 @@ // RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s // CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch // CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch + +// RUN: %clang -### -S -fdiscard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-DISCARD-NAMES %s +// RUN: %clang -### -S -fno-discard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-NO-DISCARD-NAMES %s +// CHECK-DISCARD-NAMES: "-discard-value-names" +// CHECK-NO-DISCARD-NAMES-NOT: "-discard-value-names" Index: lib/Driver/ToolChains/Clang.cpp === --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3266,12 +3266,23 @@ if (!C.isForDiagnostics()) CmdArgs.push_back("-disable-free"); -// Disable the verification pass in -asserts builds. + const bool IsAssertBuild = #ifdef NDEBUG - CmdArgs.push_back("-disable-llvm-verifier"); - // Discard LLVM value names in -asserts builds. - CmdArgs.push_back("-discard-value-names"); + false; +#else + true; #endif + // Disable the verification pass in -asserts builds. + if (!IsAssertBuild) +CmdArgs.push_back("disable-llvm-verifier"); + + // Discard value names in assert builds unless otherwise specified. + if (const Arg *A = Args.getLastArg(options::OPT_fdiscard_value_names, + options::OPT_fno_discard_value_names)) { +if (A->getOption().matches(options::OPT_fdiscard_value_names)) + CmdArgs.push_back("-discard-value-names"); + } else if (!IsAssertBuild) +CmdArgs.push_back("-discard-value-names"); // Set the main file name, so that debug info works even with // -save-temps. Index: include/clang/Driver/Options.td === --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -790,6 +790,10 @@ HelpText<"Print a template comparison tree for differing templates">; def fdeclspec : Flag<["-"], "fdeclspec">, Group, HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>; +def fdiscard_value_names : Flag<["-"], "fdiscard-value-names">, Group, + HelpText<"Discard value names in LLVM IR">, Flags<[DriverOption]>; +def fno_discard_value_names : Flag<["-"], "fno-discard-value-names">, Group, + HelpText<"Do not discard value names in LLVM IR">, Flags<[DriverOption]>; def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group, HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group; Index: docs/UsersManual.rst === --- docs/UsersManual.rst +++ docs/UsersManual.rst @@ -1855,6 +1855,27 @@ must come first.) +Controlling LLVM IR Output +--- + +Controlling Values Names in LLVM IR + + +Emitting value names in LLVM IR increases the size and verbosity of the IR. +By default value names are only emitted in assertion enabled builds of Clang. +However, when reading IR it can be useful to re-enable the emission of value +names to improve readability. + +.. option:: -fdiscard-value-names + + Discard value names when generating LLVM IR. + +.. option:: -fno-discard-value-names + + Do not discard value names when generating LLVM IR. This option can be used + to re-enable names for release builds of Clang. + + Comment Parsing Options --- Index: test/Driver/clang_f_opts.c === --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -517,3 +517,8 @@ // RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-CF-PROTECTION-BRANCH %s // CHECK-CF-PROTECTION-BRANCH: -fcf-protection=branch // CHECK-NO-CF-PROTECTION-BRANCH-NOT: -fcf-protection=branch + +// RUN: %clang -### -S -fdiscard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-DISCARD-NAMES %s +// RUN: %clang -### -S -fno-discard-value-names %s 2>&1 | FileCheck -check-prefix=CHECK-NO-DISCARD-NAMES %s +// CHECK-DISCARD-NAMES: "-discard-value-names" +// CHECK-NO-DISCARD-NAMES-NOT: "-discard-value-names" Index: lib/Driver/ToolChains/Clang.cpp === --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3266,12 +3266,23 @@ if (!C.isForDiagnostics()) CmdArgs.push_back(
[PATCH] D41223: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.
EricWF added a comment. In https://reviews.llvm.org/D41223#957308, @mclow.lists wrote: > I'm wondering if it's not a better idea to have an explicit specialization > for size == 0 > > template > class array { > // and so on. > }; I think that's probably more work than it's worth. I think we should change the primary template to support the bare minimum number of operations, and then let the rest of the operations blow up if users attempt to use them. In https://reviews.llvm.org/D41223#957334, @lichray wrote: > BTW, this is https://cplusplus.github.io/LWG/issue2157 , so please update > `www` accordingly, The `www` pages will get updated when the issue is actually accepted, which it currently isn't. There is no place to put that information now. > and also test `{{}}` cases. I don't agree those cases are valid. That initialization syntax suggests there is something in the zero-sized array which is default constructible - or that users should be able to control construction of. I disagree with that. Comment at: include/array:135 + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT& __lhs, _StorageT& __rhs) { +std::swap_ranges(__lhs, __lhs + _Size, __rhs); lichray wrote: > Just asking: no compiler is dumb enough to not inline this entirely trivial > wrapper so that it's okay to not to propagate `noexcept` here to avoid > try...capture...terminate codegen in its caller side? `_LIBCPP_INLINE_VISIBILITY` should force inlining. https://reviews.llvm.org/D41223 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41223: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.
EricWF added a comment. In https://reviews.llvm.org/D41223#997264, @EricWF wrote: > > and also test `{{}}` cases. > > I don't agree those cases are valid. That initialization syntax suggests > there is something in the zero-sized array which is default constructible - > or that users should be able to control construction of. I disagree with that. Nevermind, I see STL is insisting that case be handled. I'll add tests and then complain to him later. https://reviews.llvm.org/D41223 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41223: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.
This revision was automatically updated to reflect the committed changes. Closed by commit rCXX324182: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default… (authored by EricWF, committed by ). Repository: rCXX libc++ https://reviews.llvm.org/D41223 Files: include/array test/std/containers/sequences/array/array.cons/default.pass.cpp test/std/containers/sequences/array/array.data/data.pass.cpp test/std/containers/sequences/array/array.data/data_const.pass.cpp test/std/containers/sequences/array/begin.pass.cpp Index: include/array === --- include/array +++ include/array @@ -118,6 +118,55 @@ _LIBCPP_BEGIN_NAMESPACE_STD template +struct __array_traits { + typedef _Tp _StorageT[_Size]; + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) { +return __store; + } + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& __store) { +return __store; + } + + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT& __lhs, _StorageT& __rhs) { +std::swap_ranges(__lhs, __lhs + _Size, __rhs); + } + + _LIBCPP_INLINE_VISIBILITY + static void __fill(_StorageT& __arr, _Tp const& __val) { +_VSTD::fill_n(__arr, _Size, __val); + } +}; + +template +struct __array_traits<_Tp, 0> { + typedef typename aligned_storage::value>::type _StorageT; + + _LIBCPP_INLINE_VISIBILITY + static _Tp* __data(_StorageT& __store) { +_StorageT *__ptr = std::addressof(__store); +return reinterpret_cast<_Tp*>(__ptr); + } + + _LIBCPP_INLINE_VISIBILITY + static const _Tp* __data(const _StorageT& __store) { +const _StorageT *__ptr = std::addressof(__store); +return reinterpret_cast(__ptr); + } + + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT&, _StorageT&) {} + + _LIBCPP_INLINE_VISIBILITY + static void __fill(_StorageT&, _Tp const&) { + } +}; + +template struct _LIBCPP_TEMPLATE_VIS array { // types: @@ -134,31 +183,26 @@ typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; -value_type __elems_[_Size > 0 ? _Size : 1]; +typedef __array_traits<_Tp, _Size> _Traits; +typename _Traits::_StorageT __elems_; // No explicit construct/copy/destroy for aggregate type _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) -{_VSTD::fill_n(__elems_, _Size, __u);} -_LIBCPP_INLINE_VISIBILITY -void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) -{ __swap_dispatch((std::integral_constant()), __a); } +{_Traits::__fill(__elems_, __u);} _LIBCPP_INLINE_VISIBILITY -void __swap_dispatch(std::true_type, array&) {} - -_LIBCPP_INLINE_VISIBILITY -void __swap_dispatch(std::false_type, array& __a) -{ _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} +void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) +{ _Traits::__swap(__elems_, __a.__elems_); } // iterators: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -iterator begin() _NOEXCEPT {return iterator(__elems_);} +iterator begin() _NOEXCEPT {return iterator(data());} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} +const_iterator begin() const _NOEXCEPT {return const_iterator(data());} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} +iterator end() _NOEXCEPT {return iterator(data() + _Size);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} +const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} @@ -201,9 +245,9 @@ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -value_type* data() _NOEXCEPT {return __elems_;} +value_type* data() _NOEXCEPT {return _Traits::__data(__elems_);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -const value_type* data() const _NOEXCEPT {return __elems_;} +const value_type* data() const _NOEXCEPT {return _Traits::__data(__elems_);} }; template Index: test/std/containers/sequences/array/begin.pass.cpp === --- test/std/containers/sequences/array/begin.pass.cpp +++ test/std/containers/sequences/array/begin.pass.cpp @@ -31,4 +31,13 @@ *i = 5.5; assert(c[0] == 5.5); } +{ +
[libcxx] r324182 - [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.
Author: ericwf Date: Sat Feb 3 17:03:08 2018 New Revision: 324182 URL: http://llvm.org/viewvc/llvm-project?rev=324182&view=rev Log: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types. Summary: This patch fixes llvm.org/PR35491 and LWG2157 (https://cplusplus.github.io/LWG/issue2157) The fix attempts to maintain ABI compatibility by replacing the array with a instance of `aligned_storage`. Reviewers: mclow.lists, EricWF Reviewed By: EricWF Subscribers: lichray, cfe-commits Differential Revision: https://reviews.llvm.org/D41223 Modified: libcxx/trunk/include/array libcxx/trunk/test/std/containers/sequences/array/array.cons/default.pass.cpp libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp libcxx/trunk/test/std/containers/sequences/array/array.data/data_const.pass.cpp libcxx/trunk/test/std/containers/sequences/array/begin.pass.cpp Modified: libcxx/trunk/include/array URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=324182&r1=324181&r2=324182&view=diff == --- libcxx/trunk/include/array (original) +++ libcxx/trunk/include/array Sat Feb 3 17:03:08 2018 @@ -118,6 +118,55 @@ template c _LIBCPP_BEGIN_NAMESPACE_STD template +struct __array_traits { + typedef _Tp _StorageT[_Size]; + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) { +return __store; + } + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& __store) { +return __store; + } + + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT& __lhs, _StorageT& __rhs) { +std::swap_ranges(__lhs, __lhs + _Size, __rhs); + } + + _LIBCPP_INLINE_VISIBILITY + static void __fill(_StorageT& __arr, _Tp const& __val) { +_VSTD::fill_n(__arr, _Size, __val); + } +}; + +template +struct __array_traits<_Tp, 0> { + typedef typename aligned_storage::value>::type _StorageT; + + _LIBCPP_INLINE_VISIBILITY + static _Tp* __data(_StorageT& __store) { +_StorageT *__ptr = std::addressof(__store); +return reinterpret_cast<_Tp*>(__ptr); + } + + _LIBCPP_INLINE_VISIBILITY + static const _Tp* __data(const _StorageT& __store) { +const _StorageT *__ptr = std::addressof(__store); +return reinterpret_cast(__ptr); + } + + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT&, _StorageT&) {} + + _LIBCPP_INLINE_VISIBILITY + static void __fill(_StorageT&, _Tp const&) { + } +}; + +template struct _LIBCPP_TEMPLATE_VIS array { // types: @@ -134,31 +183,26 @@ struct _LIBCPP_TEMPLATE_VIS array typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; -value_type __elems_[_Size > 0 ? _Size : 1]; +typedef __array_traits<_Tp, _Size> _Traits; +typename _Traits::_StorageT __elems_; // No explicit construct/copy/destroy for aggregate type _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) -{_VSTD::fill_n(__elems_, _Size, __u);} -_LIBCPP_INLINE_VISIBILITY -void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) -{ __swap_dispatch((std::integral_constant()), __a); } +{_Traits::__fill(__elems_, __u);} _LIBCPP_INLINE_VISIBILITY -void __swap_dispatch(std::true_type, array&) {} - -_LIBCPP_INLINE_VISIBILITY -void __swap_dispatch(std::false_type, array& __a) -{ _VSTD::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);} +void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) +{ _Traits::__swap(__elems_, __a.__elems_); } // iterators: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -iterator begin() _NOEXCEPT {return iterator(__elems_);} +iterator begin() _NOEXCEPT {return iterator(data());} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -const_iterator begin() const _NOEXCEPT {return const_iterator(__elems_);} +const_iterator begin() const _NOEXCEPT {return const_iterator(data());} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -iterator end() _NOEXCEPT {return iterator(__elems_ + _Size);} +iterator end() _NOEXCEPT {return iterator(data() + _Size);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 -const_iterator end() const _NOEXCEPT {return const_iterator(__elems_ + _Size);} +const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());} @@ -201,9 +245,9 @@ struct _LIBCPP_TEMPLATE_VIS array _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const {return __elems_[_Size > 0 ? _Size-1 : 0];} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER
[PATCH] D41223: [libc++] Fix PR35491 - std::array of zero-size doesn't work with non-default constructible types.
EricWF updated this revision to Diff 132758. EricWF added a comment. - Address review comments. - Add initialization tests. https://reviews.llvm.org/D41223 Files: include/array test/std/containers/sequences/array/array.cons/default.pass.cpp test/std/containers/sequences/array/array.data/data.pass.cpp test/std/containers/sequences/array/array.data/data_const.pass.cpp test/std/containers/sequences/array/begin.pass.cpp Index: test/std/containers/sequences/array/begin.pass.cpp === --- test/std/containers/sequences/array/begin.pass.cpp +++ test/std/containers/sequences/array/begin.pass.cpp @@ -31,4 +31,13 @@ *i = 5.5; assert(c[0] == 5.5); } +{ + struct NoDefault { +NoDefault(int) {} + }; + typedef NoDefault T; + typedef std::array C; + C c = {}; + assert(c.begin() == c.end()); +} } Index: test/std/containers/sequences/array/array.data/data_const.pass.cpp === --- test/std/containers/sequences/array/array.data/data_const.pass.cpp +++ test/std/containers/sequences/array/array.data/data_const.pass.cpp @@ -38,6 +38,16 @@ const T* p = c.data(); (void)p; // to placate scan-build } +{ + struct NoDefault { +NoDefault(int) {} + }; + typedef NoDefault T; + typedef std::array C; + const C c = {}; + const T* p = c.data(); + assert(p != nullptr); +} #if TEST_STD_VER > 14 { typedef std::array C; Index: test/std/containers/sequences/array/array.data/data.pass.cpp === --- test/std/containers/sequences/array/array.data/data.pass.cpp +++ test/std/containers/sequences/array/array.data/data.pass.cpp @@ -36,4 +36,14 @@ T* p = c.data(); (void)p; // to placate scan-build } +{ + struct NoDefault { +NoDefault(int) {} + }; + typedef NoDefault T; + typedef std::array C; + C c = {}; + T* p = c.data(); + assert(p != nullptr); +} } Index: test/std/containers/sequences/array/array.cons/default.pass.cpp === --- test/std/containers/sequences/array/array.cons/default.pass.cpp +++ test/std/containers/sequences/array/array.cons/default.pass.cpp @@ -14,6 +14,14 @@ #include #include +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + +struct NoDefault { + NoDefault(int) {} +}; + int main() { { @@ -28,4 +36,13 @@ C c; assert(c.size() == 0); } +{ + typedef std::array C; + C c; + assert(c.size() == 0); + C c1 = {}; + assert(c1.size() == 0); + C c2 = {{}}; + assert(c2.size() == 0); +} } Index: include/array === --- include/array +++ include/array @@ -118,6 +118,55 @@ _LIBCPP_BEGIN_NAMESPACE_STD template +struct __array_traits { + typedef _Tp _StorageT[_Size]; + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) { +return __store; + } + + _LIBCPP_INLINE_VISIBILITY + static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp const* __data(const _StorageT& __store) { +return __store; + } + + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT& __lhs, _StorageT& __rhs) { +std::swap_ranges(__lhs, __lhs + _Size, __rhs); + } + + _LIBCPP_INLINE_VISIBILITY + static void __fill(_StorageT& __arr, _Tp const& __val) { +_VSTD::fill_n(__arr, _Size, __val); + } +}; + +template +struct __array_traits<_Tp, 0> { + typedef typename aligned_storage::value>::type _StorageT; + + _LIBCPP_INLINE_VISIBILITY + static _Tp* __data(_StorageT& __store) { +_StorageT *__ptr = std::addressof(__store); +return reinterpret_cast<_Tp*>(__ptr); + } + + _LIBCPP_INLINE_VISIBILITY + static const _Tp* __data(const _StorageT& __store) { +const _StorageT *__ptr = std::addressof(__store); +return reinterpret_cast(__ptr); + } + + _LIBCPP_INLINE_VISIBILITY + static void __swap(_StorageT&, _StorageT&) {} + + _LIBCPP_INLINE_VISIBILITY + static void __fill(_StorageT&, _Tp const&) { + } +}; + +template struct _LIBCPP_TEMPLATE_VIS array { // types: @@ -134,31 +183,26 @@ typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; -value_type __elems_[_Size > 0 ? _Size : 1]; +typedef __array_traits<_Tp, _Size> _Traits; +typename _Traits::_StorageT __elems_; // No explicit construct/copy/destroy for aggregate type _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) -{_VSTD::fill_n(__elems_, _Size, __u);} -_LIBCPP_INLINE_VISIBILITY -
[libcxx] r324185 - Make array non-CopyAssignable and make swap and fill ill-formed.
Author: ericwf Date: Sat Feb 3 18:17:02 2018 New Revision: 324185 URL: http://llvm.org/viewvc/llvm-project?rev=324185&view=rev Log: Make array non-CopyAssignable and make swap and fill ill-formed. The standard isn't exactly clear how std::array should handle zero-sized arrays with const element types. In particular W.R.T. copy assignment, swap, and fill. This patch takes the position that those operations should be ill-formed, and makes changes to libc++ to make it so. This follows up on commit r324182. Added: libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp libcxx/trunk/test/std/containers/sequences/array/array.fill/fill.fail.cpp libcxx/trunk/test/std/containers/sequences/array/array.swap/swap.fail.cpp Modified: libcxx/trunk/include/array libcxx/trunk/test/std/containers/sequences/array/array.data/data.pass.cpp Modified: libcxx/trunk/include/array URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/array?rev=324185&r1=324184&r2=324185&view=diff == --- libcxx/trunk/include/array (original) +++ libcxx/trunk/include/array Sat Feb 3 18:17:02 2018 @@ -122,7 +122,8 @@ struct __array_traits { typedef _Tp _StorageT[_Size]; _LIBCPP_INLINE_VISIBILITY - static _LIBCPP_CONSTEXPR_AFTER_CXX14 _Tp* __data(_StorageT& __store) { + static _LIBCPP_CONSTEXPR_AFTER_CXX14 typename remove_const<_Tp>::type* + __data(typename remove_const<_StorageT>::type& __store) { return __store; } @@ -144,12 +145,16 @@ struct __array_traits { template struct __array_traits<_Tp, 0> { - typedef typename aligned_storage::value>::type _StorageT; + typedef typename aligned_storage::value>::type + _NonConstStorageT; + typedef typename conditional::value, const _NonConstStorageT, + _NonConstStorageT>::type _StorageT; + typedef typename remove_const<_Tp>::type _NonConstTp; _LIBCPP_INLINE_VISIBILITY - static _Tp* __data(_StorageT& __store) { + static _NonConstTp* __data(_NonConstStorageT& __store) { _StorageT *__ptr = std::addressof(__store); -return reinterpret_cast<_Tp*>(__ptr); +return reinterpret_cast<_NonConstTp*>(__ptr); } _LIBCPP_INLINE_VISIBILITY @@ -162,8 +167,7 @@ struct __array_traits<_Tp, 0> { static void __swap(_StorageT&, _StorageT&) {} _LIBCPP_INLINE_VISIBILITY - static void __fill(_StorageT&, _Tp const&) { - } + static void __fill(_StorageT&, _Tp const&) {} }; template @@ -187,12 +191,19 @@ struct _LIBCPP_TEMPLATE_VIS array typename _Traits::_StorageT __elems_; // No explicit construct/copy/destroy for aggregate type -_LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) -{_Traits::__fill(__elems_, __u);} +_LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) { + static_assert(_Size != 0 || !is_const<_Tp>::value, +"cannot fill zero-sized array of type 'const T'"); + _Traits::__fill(__elems_, __u); +} _LIBCPP_INLINE_VISIBILITY -void swap(array& __a) _NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) -{ _Traits::__swap(__elems_, __a.__elems_); } +void swap(array& __a) +_NOEXCEPT_(_Size == 0 || __is_nothrow_swappable<_Tp>::value) { + static_assert(_Size != 0 || !is_const<_Tp>::value, +"cannot swap zero-sized array of type 'const T'"); + _Traits::__swap(__elems_, __a.__elems_); +} // iterators: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 Added: libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp?rev=324185&view=auto == --- libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp (added) +++ libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp Sat Feb 3 18:17:02 2018 @@ -0,0 +1,93 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// implicitly generated array constructors / assignment operators + +#include +#include +#include +#include "test_macros.h" + +// std::array is explicitly allowed to be initialized with A a = { init-list };. +// Disable the missing braces warning for this reason. +#include "disable_missing_braces_warning.h" + +// FIXME: Clang generates copy assignment operators for types with const members +// in C++03. The generated operator is ill-formed but still present. +// I'm not sure if
[libcxx] r324186 - correct comment about C++03 assignment operators
Author: ericwf Date: Sat Feb 3 18:22:33 2018 New Revision: 324186 URL: http://llvm.org/viewvc/llvm-project?rev=324186&view=rev Log: correct comment about C++03 assignment operators Modified: libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp Modified: libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp?rev=324186&r1=324185&r2=324186&view=diff == --- libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp (original) +++ libcxx/trunk/test/std/containers/sequences/array/array.cons/implicit_copy.pass.cpp Sat Feb 3 18:22:33 2018 @@ -20,10 +20,10 @@ // Disable the missing braces warning for this reason. #include "disable_missing_braces_warning.h" -// FIXME: Clang generates copy assignment operators for types with const members -// in C++03. The generated operator is ill-formed but still present. -// I'm not sure if this is a Clang bug, but we need to work around it for now. -#if TEST_STD_VER < 11 && defined(__clang__) +// In C++03 the copy assignment operator is not deleted when the implicitly +// generated operator would be ill-formed; like in the case of a struct with a +// const member. +#if TEST_STD_VER < 11 #define TEST_NOT_COPY_ASSIGNABLE(T) ((void)0) #else #define TEST_NOT_COPY_ASSIGNABLE(T) static_assert(!std::is_copy_assignable::value, "") ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r324187 - Address LWG 2849 and fix missing failure condition in copy_file.
Author: ericwf Date: Sat Feb 3 18:43:32 2018 New Revision: 324187 URL: http://llvm.org/viewvc/llvm-project?rev=324187&view=rev Log: Address LWG 2849 and fix missing failure condition in copy_file. Previously copy_file didn't handle the case where the input and output were the same file. Modified: libcxx/trunk/src/experimental/filesystem/operations.cpp libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/src/experimental/filesystem/operations.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/experimental/filesystem/operations.cpp?rev=324187&r1=324186&r2=324187&view=diff == --- libcxx/trunk/src/experimental/filesystem/operations.cpp (original) +++ libcxx/trunk/src/experimental/filesystem/operations.cpp Sat Feb 3 18:43:32 2018 @@ -263,18 +263,22 @@ void __copy(const path& from, const path bool __copy_file(const path& from, const path& to, copy_options options, std::error_code *ec) { -if (ec) ec->clear(); +using StatT = struct ::stat; +if (ec) + ec->clear(); std::error_code m_ec; -auto from_st = detail::posix_stat(from, &m_ec); +StatT from_stat; +auto from_st = detail::posix_stat(from, from_stat, &m_ec); if (not is_regular_file(from_st)) { -if (not m_ec) -m_ec = make_error_code(errc::not_supported); -set_or_throw(m_ec, ec, "copy_file", from, to); -return false; + if (not m_ec) +m_ec = make_error_code(errc::not_supported); + set_or_throw(m_ec, ec, "copy_file", from, to); + return false; } -auto to_st = detail::posix_stat(to, &m_ec); +StatT to_stat; +auto to_st = detail::posix_stat(to, to_stat, &m_ec); if (!status_known(to_st)) { set_or_throw(m_ec, ec, "copy_file", from, to); return false; @@ -285,6 +289,11 @@ bool __copy_file(const path& from, const set_or_throw(make_error_code(errc::not_supported), ec, "copy_file", from, to); return false; } +if (to_exists && detail::stat_equivalent(from_stat, to_stat)) { + set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from, + to); + return false; +} if (to_exists && bool(copy_options::skip_existing & options)) { return false; } @@ -302,8 +311,9 @@ bool __copy_file(const path& from, const return detail::copy_file_impl(from, to, from_st.permissions(), ec); } else { -set_or_throw(make_error_code(errc::file_exists), ec, "copy", from, to); -return false; + set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from, + to); + return false; } _LIBCPP_UNREACHABLE(); @@ -443,7 +453,7 @@ bool __equivalent(const path& p1, const if (!exists(s2)) return make_unsupported_error(); if (ec) ec->clear(); -return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); +return detail::stat_equivalent(st1, st2); } Modified: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp?rev=324187&r1=324186&r2=324187&view=diff == --- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp (original) +++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp Sat Feb 3 18:43:32 2018 @@ -70,17 +70,21 @@ TEST_CASE(test_error_reporting) scoped_test_env env; const path file = env.create_file("file1", 42); const path file2 = env.create_file("file2", 55); +const path non_regular_file = env.create_fifo("non_reg"); const path dne = env.make_env_path("dne"); { // exists(to) && equivalent(to, from) std::error_code ec; -TEST_CHECK(fs::copy_file(file, file, ec) == false); +TEST_CHECK(fs::copy_file(file, file, copy_options::overwrite_existing, + ec) == false); TEST_REQUIRE(ec); +TEST_CHECK(ec == std::make_error_code(std::errc::file_exists)); TEST_CHECK(checkThrow(file, file, ec)); } { // exists(to) && !(skip_existing | overwrite_existing | update_existing) std::error_code ec; TEST_CHECK(fs::copy_file(file, file2, ec) == false); TEST_REQUIRE(ec); +TEST_CHECK(ec == std::make_error_code(std::errc::file_exists)); TEST_CHECK(checkThrow(file, file2, ec)); } } @@ -181,6 +185,7 @@ TEST_CASE(non_regular_file_test) TEST_REQUIRE(fs::copy_file(file, fifo, copy_options::overwrite_existing, ec) == false); TEST_CHECK(ec); TEST_CHECK(ec !
[libcxx] r324188 - Mark issue 2851 as complete
Author: ericwf Date: Sat Feb 3 18:45:33 2018 New Revision: 324188 URL: http://llvm.org/viewvc/llvm-project?rev=324188&view=rev Log: Mark issue 2851 as complete Modified: libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/www/upcoming_meeting.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=324188&r1=324187&r2=324188&view=diff == --- libcxx/trunk/www/upcoming_meeting.html (original) +++ libcxx/trunk/www/upcoming_meeting.html Sat Feb 3 18:45:33 2018 @@ -64,7 +64,7 @@ https://wg21.link/LWG2816";>2816resize_file has impossible postconditionJacksonvilleNothing to do https://wg21.link/LWG2843";>2843Unclear behavior of std::pmr::memory_resource::do_allocate()Jacksonville https://wg21.link/LWG2849";>2849Why does !is_regular_file(from) cause copy_file to report a "file already exists" error?JacksonvilleNothing to do -https://wg21.link/LWG2851";>2851std::filesystem enum classes are now underspecifiedJacksonville +https://wg21.link/LWG2851";>2851std::filesystem enum classes are now underspecifiedJacksonvilleNothing to do https://wg21.link/LWG2969";>2969polymorphic_allocator::construct() shouldn't pass resource()Jacksonville https://wg21.link/LWG2975";>2975Missing case for pair construction in scoped and polymorphic allocatorsJacksonville https://wg21.link/LWG2989";>2989path's stream insertion operator lets you insert everything under the sunJacksonville @@ -101,7 +101,7 @@ 2816 - Wording changes only 2843 - We don't have PMRs yet 2849 - We already report different errors. - 2851 - Eric? + 2851 - Wording changes only 2969 - We don't have PMRs yet 2975 - We can do the scoped_ bit, but the PMR stuff will have to wait. 2989 - Eric? ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r324189 - Implement LWG2989: path's streaming operators allow everything under the sun.
Author: ericwf Date: Sat Feb 3 19:10:53 2018 New Revision: 324189 URL: http://llvm.org/viewvc/llvm-project?rev=324189&view=rev Log: Implement LWG2989: path's streaming operators allow everything under the sun. Because path can be constructed from a ton of different types, including string and wide strings, this caused it's streaming operators to suck up all sorts of silly types via silly conversions. For example: using namespace std::experimental::filesystem::v1; std::wstring w(L"wide"); std::cout << w; // converts to path. This patch tentatively adopts the resolution to LWG2989 and fixes the issue by making the streaming operators friends of path. Modified: libcxx/trunk/include/experimental/filesystem libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/include/experimental/filesystem URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/filesystem?rev=324189&r1=324188&r2=324189&view=diff == --- libcxx/trunk/include/experimental/filesystem (original) +++ libcxx/trunk/include/experimental/filesystem Sat Feb 3 19:10:53 2018 @@ -28,12 +28,13 @@ path operator/ (const path& lhs, const path& rhs); +// fs.path.io operators are friends of path. template -basic_ostream& +friend basic_ostream& operator<<(basic_ostream& os, const path& p); template -basic_istream& +friend basic_istream& operator>>(basic_istream& is, path& p); template @@ -994,6 +995,40 @@ public: iterator begin() const; iterator end() const; + +template +_LIBCPP_INLINE_VISIBILITY +friend typename enable_if::value && + is_same<_Traits, char_traits>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { +__os << std::__quoted(__p.native()); +return __os; +} + +template +_LIBCPP_INLINE_VISIBILITY +friend typename enable_if::value || + !is_same<_Traits, char_traits>::value, + basic_ostream<_CharT, _Traits>& +>::type +operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { +__os << std::__quoted(__p.string<_CharT, _Traits>()); +return __os; +} + +template +_LIBCPP_INLINE_VISIBILITY +friend basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) +{ +basic_string<_CharT, _Traits> __tmp; +__is >> __quoted(__tmp); +__p = __tmp; +return __is; +} + private: inline _LIBCPP_INLINE_VISIBILITY path& __assign_view(__string_view const& __s) noexcept { __pn_ = string_type(__s); return *this; } @@ -1037,39 +1072,6 @@ path operator/(const path& __lhs, const return path(__lhs) /= __rhs; } -template -_LIBCPP_INLINE_VISIBILITY -typename enable_if::value && - is_same<_Traits, char_traits>::value, - basic_ostream<_CharT, _Traits>& ->::type -operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { -__os << std::__quoted(__p.native()); -return __os; -} - -template -_LIBCPP_INLINE_VISIBILITY -typename enable_if::value || - !is_same<_Traits, char_traits>::value, - basic_ostream<_CharT, _Traits>& ->::type -operator<<(basic_ostream<_CharT, _Traits>& __os, const path& __p) { -__os << std::__quoted(__p.string<_CharT, _Traits>()); -return __os; -} - -template -_LIBCPP_INLINE_VISIBILITY -basic_istream<_CharT, _Traits>& -operator>>(basic_istream<_CharT, _Traits>& __is, path& __p) -{ -basic_string<_CharT, _Traits> __tmp; -__is >> __quoted(__tmp); -__p = __tmp; -return __is; -} - template _LIBCPP_INLINE_VISIBILITY typename enable_if<__is_pathable<_Source>::value, path>::type Modified: libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp?rev=324189&r1=324188&r2=324189&view=diff == --- libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp (original) +++ libcxx/trunk/test/std/experimental/filesystem/class.path/path.nonmember/path.io.pass.cpp Sat Feb 3 19:10:53 2018 @@ -26,6 +26,7 @@ #include #include #include +#include #include "test_macros.h" #include "test_iterators.h" @@ -35,6 +36,8 @@ MultiStringType InStr = MKSTR("abcdefg/\"hijklmnop\"/qrstuvwxyz/123456789"); MultiStringType OutStr = MKSTR("\"abcdefg/\\\"hijklmnop\\\"/qrstuvwxyz/123456789\""); + + template void doIOTest() { using namespace fs; @@ -56,10 +59,40 @@ void doIOTe
[libcxx] r324190 - Remove debug println from rec.dir.itr.increment test
Author: ericwf Date: Sat Feb 3 19:26:55 2018 New Revision: 324190 URL: http://llvm.org/viewvc/llvm-project?rev=324190&view=rev Log: Remove debug println from rec.dir.itr.increment test Modified: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp Modified: libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp?rev=324190&r1=324189&r2=324190&view=diff == --- libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp (original) +++ libcxx/trunk/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp Sat Feb 3 19:26:55 2018 @@ -24,7 +24,6 @@ #include "test_macros.h" #include "rapid-cxx-test.hpp" #include "filesystem_test_helper.hpp" -#include using namespace std::experimental::filesystem; @@ -347,7 +346,6 @@ TEST_CASE(test_PR35078_with_symlink) Opts |= directory_options::follow_directory_symlink; recursive_directory_iterator it(startDir, Opts, ec); while (!ec && it != endIt && *it != symDir) { -std::cout << *it << std::endl; if (*it == nestedFile) SeenFile3 = true; it.increment(ec); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r324191 - Mark LWG 3013 as already complete. See r316941
Author: ericwf Date: Sat Feb 3 23:29:53 2018 New Revision: 324191 URL: http://llvm.org/viewvc/llvm-project?rev=324191&view=rev Log: Mark LWG 3013 as already complete. See r316941 Modified: libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/www/upcoming_meeting.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=324191&r1=324190&r2=324191&view=diff == --- libcxx/trunk/www/upcoming_meeting.html (original) +++ libcxx/trunk/www/upcoming_meeting.html Sat Feb 3 23:29:53 2018 @@ -75,7 +75,7 @@ https://wg21.link/LWG3007";>3007allocate_shared should rebind allocator to cv-unqualified value_type for constructionJacksonville https://wg21.link/LWG3009";>3009Includingdoesn't provide std::size/empty/dataJacksonvilleComplete https://wg21.link/LWG3010";>3010[networking.ts] uses_executor says "if a type T::executor_type exists"Jacksonville -https://wg21.link/LWG3013";>3013(recursive_)directory_iterator construction and traversal should not be noexceptJacksonville +https://wg21.link/LWG3013";>3013(recursive_)directory_iterator construction and traversal should not be noexceptJacksonvilleComplete https://wg21.link/LWG3014";>3014More noexcept issues with filesystem operationsJacksonville https://wg21.link/LWG3015";>3015copy_options::unspecified underspecifiedJacksonville https://wg21.link/LWG3017";>3017list splice functions should use addressofJacksonville @@ -112,7 +112,7 @@ 3007 - Looks easy 3009 - We do this already; tests added in r323719 3010 - No networking TS implementation yet - 3013 - Eric? + 3013 - We already implement this 3014 - Eric? 3015 - Eric? 3017 - We don't do the splicing stuff yet ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[libcxx] r324192 - Implement LWG 3014 - Fix more noexcept issues in filesystem.
Author: ericwf Date: Sat Feb 3 23:35:36 2018 New Revision: 324192 URL: http://llvm.org/viewvc/llvm-project?rev=324192&view=rev Log: Implement LWG 3014 - Fix more noexcept issues in filesystem. This patch removes the noexcept declaration from filesystem operations which require creating temporary paths or creating a directory iterator. Either of these operations can throw. Modified: libcxx/trunk/include/experimental/filesystem libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/include/experimental/filesystem URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/experimental/filesystem?rev=324192&r1=324191&r2=324192&view=diff == --- libcxx/trunk/include/experimental/filesystem (original) +++ libcxx/trunk/include/experimental/filesystem Sat Feb 3 23:35:36 2018 @@ -88,17 +88,17 @@ error_code& ec); bool copy_file(const path& from, const path& to); -bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT; +bool copy_file(const path& from, const path& to, error_code& ec); bool copy_file(const path& from, const path& to, copy_options option); bool copy_file(const path& from, const path& to, copy_options option, - error_code& ec) _NOEXCEPT; + error_code& ec); void copy_symlink(const path& existing_symlink, const path& new_symlink); void copy_symlink(const path& existing_symlink, const path& new_symlink, error_code& ec) _NOEXCEPT; bool create_directories(const path& p); -bool create_directories(const path& p, error_code& ec) _NOEXCEPT; +bool create_directories(const path& p, error_code& ec); bool create_directory(const path& p); bool create_directory(const path& p, error_code& ec) _NOEXCEPT; @@ -188,7 +188,7 @@ bool remove(const path& p, error_code& ec) _NOEXCEPT; uintmax_tremove_all(const path& p); -uintmax_tremove_all(const path& p, error_code& ec) _NOEXCEPT; +uintmax_tremove_all(const path& p, error_code& ec); void rename(const path& from, const path& to); void rename(const path& from, const path& to, error_code& ec) _NOEXCEPT; @@ -1375,7 +1375,7 @@ bool copy_file(const path& __from, const } inline _LIBCPP_INLINE_VISIBILITY -bool copy_file(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT { +bool copy_file(const path& __from, const path& __to, error_code& __ec) { return __copy_file(__from, __to, copy_options::none, &__ec); } @@ -1386,7 +1386,7 @@ bool copy_file(const path& __from, const inline _LIBCPP_INLINE_VISIBILITY bool copy_file(const path& __from, const path& __to, - copy_options __opt, error_code& __ec) _NOEXCEPT { + copy_options __opt, error_code& __ec){ return __copy_file(__from, __to, __opt, &__ec); } @@ -1406,7 +1406,7 @@ bool create_directories(const path& __p) } inline _LIBCPP_INLINE_VISIBILITY -bool create_directories(const path& __p, error_code& __ec) _NOEXCEPT { +bool create_directories(const path& __p, error_code& __ec) { return __create_directories(__p, &__ec); } @@ -1699,7 +1699,7 @@ uintmax_t remove_all(const path& __p) { } inline _LIBCPP_INLINE_VISIBILITY -uintmax_t remove_all(const path& __p, error_code& __ec) _NOEXCEPT { +uintmax_t remove_all(const path& __p, error_code& __ec) { return __remove_all(__p, &__ec); } Modified: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp?rev=324192&r1=324191&r2=324192&view=diff == --- libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp (original) +++ libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp Sat Feb 3 23:35:36 2018 @@ -44,8 +44,8 @@ TEST_CASE(test_signatures) ASSERT_SAME_TYPE(decltype(fs::copy_file(p, p, opts, ec)), bool); ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p)); ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts)); -ASSERT_NOEXCEPT(fs::copy_file(p, p, ec)); -ASSERT_NOEXCEPT(fs::copy_file(p, p, opts, ec)); +ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, ec)); +ASSERT_NOT_NOEXCEPT(fs::copy_file(p, p, opts, ec)); } TEST_CASE(test_error_reporting) Modified: libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.create_directories/create_directorie
[libcxx] r324193 - Mark LWG 3014 as complete. No code changes needed
Author: ericwf Date: Sat Feb 3 23:37:09 2018 New Revision: 324193 URL: http://llvm.org/viewvc/llvm-project?rev=324193&view=rev Log: Mark LWG 3014 as complete. No code changes needed Modified: libcxx/trunk/www/upcoming_meeting.html Modified: libcxx/trunk/www/upcoming_meeting.html URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/upcoming_meeting.html?rev=324193&r1=324192&r2=324193&view=diff == --- libcxx/trunk/www/upcoming_meeting.html (original) +++ libcxx/trunk/www/upcoming_meeting.html Sat Feb 3 23:37:09 2018 @@ -77,7 +77,7 @@ https://wg21.link/LWG3010";>3010[networking.ts] uses_executor says "if a type T::executor_type exists"Jacksonville https://wg21.link/LWG3013";>3013(recursive_)directory_iterator construction and traversal should not be noexceptJacksonvilleComplete https://wg21.link/LWG3014";>3014More noexcept issues with filesystem operationsJacksonvilleComplete -https://wg21.link/LWG3015";>3015copy_options::unspecified underspecifiedJacksonville + https://wg21.link/LWG3015";>3015copy_options::unspecified underspecifiedJacksonvilleNothing to do https://wg21.link/LWG3017";>3017list splice functions should use addressofJacksonville https://wg21.link/LWG3020";>3020[networking.ts] Remove spurious nested value_type buffer sequence requirementJacksonville https://wg21.link/LWG3026";>3026filesystem::weakly_canonical still defined in terms of canonical(p, base)Jacksonville @@ -114,7 +114,7 @@ 3010 - No networking TS implementation yet 3013 - We already implement this 3014 - We implement this - 3015 - Eric? + 3015 - Wording changes only 3017 - We don't do the splicing stuff yet 3020 - No networking TS implementation yet 3026 - I think this is just wording cleanup - Eric? ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits