CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
478 lines
13 KiB
C++
478 lines
13 KiB
C++
// RUN: %check_clang_tidy \
|
|
// RUN: -std=c++17-or-later %s modernize-use-string-view %t
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
// ==========================================================
|
|
// Positive tests
|
|
// ==========================================================
|
|
|
|
std::string simpleLiteral() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view simpleLiteral() {
|
|
return "simpleLiteral";
|
|
}
|
|
|
|
std::string simpleLiteralConcat() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view simpleLiteralConcat() {
|
|
return "hello" " " "world";
|
|
}
|
|
|
|
std::wstring simpleLiteralW() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::wstring_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::wstring_view simpleLiteralW() {
|
|
return L"wide literal";
|
|
}
|
|
|
|
std::string simpleRLiteral() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view simpleRLiteral() {
|
|
return R"(simpleLiteral)";
|
|
}
|
|
|
|
[[nodiscard]] std::string Attributed() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:15: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: {{\[\[nodiscard\]\]}} std::string_view Attributed() {
|
|
return "attributed";
|
|
}
|
|
|
|
const std::string Const() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:7: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: const std::string_view Const() {
|
|
return "Const";
|
|
}
|
|
|
|
auto Trailing() -> std::string {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// TODO: support fixes for trailing types
|
|
return "Trailing";
|
|
}
|
|
|
|
std::string initList() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view initList() {
|
|
return {"list"};
|
|
}
|
|
|
|
std::string ctorReturn(int i) {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view ctorReturn(int i) {
|
|
if( i == 42) {
|
|
do {
|
|
return std::string();
|
|
// CHECK-FIXES: return {};
|
|
} while(true);
|
|
}
|
|
else {
|
|
for(int k = 0; k < 1000; k++)
|
|
if ( i > k ) {
|
|
return std::string();
|
|
// CHECK-FIXES: return {};
|
|
}
|
|
else {
|
|
return "else";
|
|
}
|
|
}
|
|
return std::string{};
|
|
// CHECK-FIXES: return {};
|
|
}
|
|
|
|
std::string ctorWithInitListReturn() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view ctorWithInitListReturn() {
|
|
// CHECK-FIXES: return {};
|
|
return std::string{};
|
|
}
|
|
|
|
std::string emptyReturn() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view emptyReturn() {
|
|
return {};
|
|
}
|
|
|
|
std::string switchCaseTest(int i) {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view switchCaseTest(int i) {
|
|
switch (i) {
|
|
case 1:
|
|
return "case1";
|
|
case 2:
|
|
return "case2";
|
|
case 3:
|
|
return {};
|
|
default:
|
|
return "default";
|
|
}
|
|
}
|
|
|
|
std::string switchCaseTestWithOnlyEmptyStrings(int i) {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view switchCaseTestWithOnlyEmptyStrings(int i) {
|
|
switch (i) {
|
|
case 1:
|
|
// CHECK-FIXES: return {};
|
|
return std::string();
|
|
case 2:
|
|
// CHECK-FIXES: return {};
|
|
return std::string{};
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
std::string ifElseTest(bool flag) {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view ifElseTest(bool flag) {
|
|
if (flag)
|
|
return "true";
|
|
return "false";
|
|
}
|
|
|
|
std::string ternary(bool flag) {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view ternary(bool flag) {
|
|
return flag ? "true" : "false";
|
|
}
|
|
|
|
std::string nested(int x) {
|
|
// TODO: support for nested ternary
|
|
return x < 0 ? "neg" : (x == 0 ? "zero" : "pos");
|
|
}
|
|
|
|
class A {
|
|
std::string classMethodInt() { return "internal"; }
|
|
// CHECK-MESSAGES:[[@LINE-1]]:3: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view classMethodInt() { return "internal"; }
|
|
|
|
std::string classMethodExt();
|
|
// CHECK-FIXES: std::string_view classMethodExt();
|
|
};
|
|
|
|
std::string A::classMethodExt() { return "external"; }
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view A::classMethodExt() { return "external"; }
|
|
|
|
#define MACRO "MACRO LITERAL"
|
|
std::string macro() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view macro() {
|
|
return MACRO;
|
|
}
|
|
|
|
#define my_string std::string
|
|
my_string macro_type() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view macro_type() {
|
|
return "MACTO LITERAL";
|
|
}
|
|
|
|
#define my_definition std::string function_inside_macro()
|
|
my_definition {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
return "literal";
|
|
}
|
|
|
|
std::string multiDecl();
|
|
std::string multiDecl();
|
|
std::string multiDecl() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view multiDecl() {
|
|
return "multiDecl";
|
|
}
|
|
|
|
using MyTrivialString = std::string;
|
|
MyTrivialString aliasedTrivial() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view aliasedTrivial() {
|
|
return "aliased";
|
|
}
|
|
|
|
template <typename T>
|
|
using MyString = std::basic_string<T>;
|
|
|
|
MyString<char> aliasedChar() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::string_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::string_view aliasedChar() {
|
|
return "aliasedChar";
|
|
}
|
|
|
|
MyString<wchar_t> aliasedWChar() {
|
|
// CHECK-MESSAGES:[[@LINE-1]]:1: warning: consider using 'std::wstring_view' to avoid unnecessary copying and allocations [modernize-use-string-view]
|
|
// CHECK-FIXES: std::wstring_view aliasedWChar() {
|
|
return L"aliasedWChar";
|
|
}
|
|
|
|
// ==========================================================
|
|
// Negative tests
|
|
// ==========================================================
|
|
|
|
std::string toString() {
|
|
return "ignored by default options";
|
|
}
|
|
|
|
std::string ToString() {
|
|
return "ignored by default options";
|
|
}
|
|
|
|
std::string to_string() {
|
|
return "ignored by default options";
|
|
}
|
|
|
|
std::string localVariable() {
|
|
std::string s = "local variable";
|
|
// TODO: extract and return literal
|
|
return s;
|
|
}
|
|
|
|
std::string dynamicCalculation() {
|
|
std::string s1 = "hello ";
|
|
return s1 + "world";
|
|
}
|
|
|
|
std::string mixedReturns(bool flag) {
|
|
if (flag) {
|
|
return "safe static literal";
|
|
}
|
|
std::string s = "unsafe dynamic";
|
|
return s;
|
|
}
|
|
|
|
std::string stringTernary(bool flag) {
|
|
// TODO: extract literals
|
|
return flag ? std::string("true") : std::string("false");
|
|
}
|
|
|
|
std::string_view alreadyGood() {
|
|
return "alreadyGood";
|
|
}
|
|
|
|
std::wstring_view alreadyGoodW() {
|
|
return L"alreadyGood";
|
|
}
|
|
|
|
std::string simpleLiteralS() {
|
|
// TODO: replace ""s to literal and return string_view
|
|
using namespace std::literals::string_literals;
|
|
return "simpleLiteral"s;
|
|
}
|
|
|
|
std::string_view alreadyGoodSV() {
|
|
using namespace std::literals::string_view_literals;
|
|
return "alreadyGood"sv;
|
|
}
|
|
|
|
std::string returnArgCopy(std::string s) {
|
|
// Must not be converted to string_view because of use-after-free on stack
|
|
return s;
|
|
}
|
|
|
|
std::string returnIndirection(const char* ptr) {
|
|
// Can be unsafe or intentional, like converting string_view into string
|
|
return ptr;
|
|
}
|
|
|
|
std::string localBuffer() {
|
|
char buf[] = "local buffer";
|
|
// Must not be converted to string_view because of use-after-free on stack
|
|
return buf;
|
|
}
|
|
|
|
std::string returnConstVar() {
|
|
// TODO: seems safe
|
|
constexpr auto kVar = "const string";
|
|
return kVar;
|
|
}
|
|
|
|
std::string passStringView(std::string_view sv) {
|
|
// TODO: Can be unsafe or intentional, like converting string_view into string
|
|
return std::string(sv);
|
|
}
|
|
|
|
std::string explicitConstruction() {
|
|
// Cannot be std::string_view: returning address of local temporary object
|
|
// TODO: extract and return literal
|
|
return std::string("explicitConstruction");
|
|
}
|
|
|
|
std::string explicitConstructionWithInitList() {
|
|
// Cannot be std::string_view: returning address of local temporary object
|
|
// TODO: extract and return literal
|
|
return std::string{"explicitConstruction"};
|
|
}
|
|
|
|
std::string explicitConstructionEmpty() {
|
|
return std::string("");
|
|
}
|
|
|
|
std::string explicitConstructionWithInitListEmpty() {
|
|
return std::string{""};
|
|
}
|
|
|
|
std::string switchCaseTestWithExplicitEmptyString(int i) {
|
|
switch (i) {
|
|
case 1:
|
|
return "case1";
|
|
case 2:
|
|
return "case2";
|
|
case 3:
|
|
return {};
|
|
default:
|
|
return std::string("");
|
|
}
|
|
}
|
|
|
|
std::string switchCaseTestWithExplicitNonEmptyString(int i) {
|
|
switch (i) {
|
|
case 1:
|
|
return "case1";
|
|
case 2:
|
|
return "case2";
|
|
case 3:
|
|
return {};
|
|
default:
|
|
return std::string("default");
|
|
}
|
|
}
|
|
|
|
struct B {
|
|
virtual ~B() = default;
|
|
virtual std::string virtMethod1() { return "B::virtual1"; }
|
|
virtual std::string virtMethod2();
|
|
};
|
|
|
|
std::string B::virtMethod2() { return "B::virtual2"; }
|
|
|
|
struct C: public B {
|
|
std::string virtMethod1() override { return "C::virtual"; }
|
|
std::string virtMethod2() override;
|
|
};
|
|
|
|
std::string C::virtMethod2() { return "C::virtual"; }
|
|
|
|
std::string lambda() {
|
|
// TODO: extract and return literal from lambda
|
|
return []() {
|
|
return "lambda";
|
|
}();
|
|
}
|
|
|
|
struct TemplateString {
|
|
static constexpr char* val = "TEMPLATE";
|
|
template<typename T>
|
|
// TODO: extract and return literal
|
|
std::string templateFunc() { return T::val; }
|
|
std::string templateFuncCall() {
|
|
return templateFunc<TemplateString>();
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
std::basic_string<T> templateStringConditional() {
|
|
if constexpr(std::is_same_v<T, wchar_t>) {
|
|
return L"TEMPLATE";
|
|
} else {
|
|
return "TEMPLATE";
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
std::basic_string<T> templateStringMixedConditional() {
|
|
if constexpr(std::is_same_v<T, wchar_t>) {
|
|
return L"TEMPLATE";
|
|
} else {
|
|
std::string s = "haha";
|
|
return s;
|
|
}
|
|
}
|
|
|
|
void UseTemplateStringConditional() {
|
|
templateStringConditional<char>();
|
|
templateStringConditional<wchar_t>();
|
|
|
|
templateStringMixedConditional<char>();
|
|
templateStringMixedConditional<wchar_t>();
|
|
}
|
|
|
|
std::string& Ref() {
|
|
static std::string s = "Ref";
|
|
return s;
|
|
}
|
|
|
|
const std::string& ConstRef() {
|
|
static std::string s = "ConstRef";
|
|
return s;
|
|
}
|
|
|
|
auto autoReturn() {
|
|
// Deduced to const char*
|
|
return "autoReturn";
|
|
}
|
|
|
|
template <class T>
|
|
std::basic_string<T> templateString() {
|
|
// Intentionally skip templates
|
|
return L"TEMPLATE";
|
|
}
|
|
std::wstring returnTemplateString() {
|
|
return templateString<wchar_t>();
|
|
}
|
|
|
|
template <typename R> R f() {
|
|
// Intentionally skip templates
|
|
return "str";
|
|
}
|
|
template std::string f();
|
|
|
|
struct stringOperator {
|
|
operator std::string() const {
|
|
return "conversion";
|
|
}
|
|
};
|
|
|
|
std::string safeFunctionWithLambda() {
|
|
auto lambda = []() -> std::string {
|
|
std::string local = "unsafe";
|
|
return local;
|
|
};
|
|
// TODO: fix hasDescendant(returnStmt(hasReturnValue... which is too strict
|
|
return "safe literal";
|
|
}
|
|
|
|
using Handle = std::wstring;
|
|
|
|
#ifdef HANDLE_SUPPORTED
|
|
Handle handle_or_string();
|
|
#else
|
|
std::string handle_or_string();
|
|
#endif
|
|
|
|
#ifdef HANDLE_SUPPORTED
|
|
Handle
|
|
#else
|
|
std::string
|
|
#endif
|
|
my_function() {
|
|
return handle_or_string();
|
|
}
|
|
|
|
|
|
namespace TemplatedFunctions {
|
|
template <typename MojoType>
|
|
extern std::string GetErrorString(const MojoType& mojo_type);
|
|
|
|
class A{};
|
|
class B{};
|
|
|
|
template <>
|
|
std::string GetErrorString(const A& a) {
|
|
return "Can be string_view";
|
|
}
|
|
|
|
template <>
|
|
std::string GetErrorString(const B& a) {
|
|
std::string s("Cannot be string_view");
|
|
return s;
|
|
}
|
|
} // namespace TemplatedFunctions
|