================
@@ -2531,3 +2531,90 @@ int *noreturn_dead_nested(bool cond, bool cond2, int
*num) {
}
} // namespace conditional_operator_control_flow
+
+namespace callable_wrappers {
+
+std::function<void()> direct_return() {
+ int x;
+ return [&x]() { (void)x; }; // expected-warning {{address of stack memory is
returned later}} \
+ // expected-note {{returned here}}
+}
+
+std::function<void()> copy_function() {
+ int x;
+ std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{address
of stack memory is returned later}}
+ std::function<void()> f2 = f;
+ return f2; // expected-note {{returned here}}
+}
+
+std::function<void()> copy_assign() {
+ int x;
+ std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{address
of stack memory is returned later}}
+ std::function<void()> f2 = []() {};
+ f2 = f;
+ return f2; // expected-note {{returned here}}
+}
+
+// FIXME: False negative. std::move's lifetimebound handling in
+// `handleFunctionCall` only flows the outermost origin, missing inner origins
+// that carry the lambda's loans.
+std::function<void()> move_assign() {
+ int x;
+ std::function<void()> f = [&x]() { (void)x; }; // Should warn.
+ std::function<void()> f2 = []() {};
+ f2 = std::move(f);
+ return f2;
+}
+
+std::function<void()> reassign_safe_then_unsafe() {
+ static int safe = 1;
+ int local = 2;
+ std::function<void()> f = []() { (void)safe; };
+ f = [&local]() { (void)local; }; // expected-warning {{address of stack
memory is returned later}}
+ return f; // expected-note {{returned here}}
+}
+
+std::function<void()> reassign_unsafe_then_safe() {
+ static int safe = 1;
+ int local = 2;
+ std::function<void()> f = [&local]() { (void)local; };
+ f = []() { (void)safe; };
+ return f;
+}
+
+std::function<void()> non_capturing_lambda() {
+ return []() {};
+}
+
+void free_function();
+
+std::function<void()> reassign_lambda_to_function_pointer() {
+ int local;
+ std::function<void()> f = [&local]() { (void)local; };
+ f = &free_function;
+ return f;
+}
+
+struct Functor { void operator()() const; };
+
+std::function<void()> reassign_lambda_to_functor() {
+ int local;
+ Functor c;
+ std::function<void()> f = [&local]() { (void)local; };
+ f = c;
+ return f;
+}
+
+struct [[gsl::Pointer]] function_ref {
+ template <typename Callable>
+ function_ref(Callable &&callable [[clang::lifetimebound]]) : ref(callable) {}
+ void (*ref)();
+};
+
+void assign_non_capturing_to_function_ref(function_ref &r) {
----------------
usx95 wrote:
Yes.
Can you enclose this in a namespace GH126600
Please also add a FIXME. This looks like we need annotate inner callable
instead of the outer reference. Also a case for lifetimebound(2) or similar
solution for inner lifetimes.
https://github.com/llvm/llvm-project/pull/191123
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits