From c4c5cdc1f595e5177ec7fe3164a644aa19f9a783 Mon Sep 17 00:00:00 2001 From: Jon Meow <46229924+jonmeow@users.noreply.github.com> Date: Thu, 3 Mar 2022 10:21:38 -0800 Subject: [PATCH] Replace is_sorted with comparison (#1104) * Replace is_sorted with comparison * Switch to StringRefContainsPointer --- common/string_helpers.cpp | 7 ++++++- common/string_helpers.h | 5 +++++ toolchain/lexer/BUILD | 2 ++ toolchain/lexer/test_helpers.h | 3 ++- toolchain/lexer/tokenized_buffer.cpp | 4 ++-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/common/string_helpers.cpp b/common/string_helpers.cpp index 2d66f4dae345..f9b9147f4da3 100644 --- a/common/string_helpers.cpp +++ b/common/string_helpers.cpp @@ -13,7 +13,7 @@ namespace Carbon { -static constexpr llvm::StringRef TripleQuotes = "\"\"\""; +static constexpr llvm::StringRef TripleQuotes = R"(""")"; static constexpr llvm::StringRef HorizontalWhitespaceChars = " \t"; // Carbon only takes uppercase hex input. @@ -169,4 +169,9 @@ auto ParseBlockStringLiteral(llvm::StringRef source) return parsed; } +auto StringRefContainsPointer(llvm::StringRef ref, const char* ptr) -> bool { + auto le = std::less_equal(); + return le(ref.begin(), ptr) && le(ptr, ref.end()); +} + } // namespace Carbon diff --git a/common/string_helpers.h b/common/string_helpers.h index 79d07fea5432..1b0a79911da8 100644 --- a/common/string_helpers.h +++ b/common/string_helpers.h @@ -26,6 +26,11 @@ auto UnescapeStringLiteral(llvm::StringRef source, bool is_block_string = false) auto ParseBlockStringLiteral(llvm::StringRef source) -> llvm::Expected; +// Returns true if the pointer is in the string ref (including equality with +// `ref.end()`). This should be used instead of `<=` comparisons for +// correctness. +auto StringRefContainsPointer(llvm::StringRef ref, const char* ptr) -> bool; + } // namespace Carbon #endif // COMMON_STRING_HELPERS_H_ diff --git a/toolchain/lexer/BUILD b/toolchain/lexer/BUILD index c701956024c4..7dfe303d272d 100644 --- a/toolchain/lexer/BUILD +++ b/toolchain/lexer/BUILD @@ -40,6 +40,7 @@ cc_library( hdrs = ["test_helpers.h"], deps = [ "//common:check", + "//common:string_helpers", "//toolchain/diagnostics:diagnostic_emitter", "@com_google_googletest//:gtest", "@llvm-project//llvm:Support", @@ -160,6 +161,7 @@ cc_library( ":token_kind", "//common:check", "//common:ostream", + "//common:string_helpers", "//toolchain/diagnostics:diagnostic_emitter", "//toolchain/source:source_buffer", "@llvm-project//llvm:Support", diff --git a/toolchain/lexer/test_helpers.h b/toolchain/lexer/test_helpers.h index f66cfdd64103..f47abc612b89 100644 --- a/toolchain/lexer/test_helpers.h +++ b/toolchain/lexer/test_helpers.h @@ -11,6 +11,7 @@ #include #include "common/check.h" +#include "common/string_helpers.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/FormatVariadic.h" #include "toolchain/diagnostics/diagnostic_emitter.h" @@ -28,7 +29,7 @@ class SingleTokenDiagnosticTranslator : token_(token) {} auto GetLocation(const char* pos) -> Diagnostic::Location override { - CHECK(llvm::is_sorted(std::array{token_.begin(), pos, token_.end()})) + CHECK(StringRefContainsPointer(token_, pos)) << "invalid diagnostic location"; llvm::StringRef prefix = token_.take_front(pos - token_.begin()); auto [before_last_newline, this_line] = prefix.rsplit('\n'); diff --git a/toolchain/lexer/tokenized_buffer.cpp b/toolchain/lexer/tokenized_buffer.cpp index e0ad9946429d..38af659bc270 100644 --- a/toolchain/lexer/tokenized_buffer.cpp +++ b/toolchain/lexer/tokenized_buffer.cpp @@ -11,6 +11,7 @@ #include #include "common/check.h" +#include "common/string_helpers.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" @@ -901,8 +902,7 @@ auto TokenizedBuffer::TokenIterator::Print(llvm::raw_ostream& output) const auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation( const char* loc) -> Diagnostic::Location { - CHECK(llvm::is_sorted(std::array{buffer_->source_->Text().begin(), loc, - buffer_->source_->Text().end()})) + CHECK(StringRefContainsPointer(buffer_->source_->Text(), loc)) << "location not within buffer"; int64_t offset = loc - buffer_->source_->Text().begin();