@@ -529,14 +529,14 @@ TriviallyDestructedClass* trivial_class_uar () {
529529 return ptr; // expected-note {{returned here}}
530530}
531531
532- // FIXME: No lifetime warning for this as no expire facts are generated for parameters
533532const int & return_parameter (int a) {
534- return a;
533+ return a; // expected-warning {{address of stack memory is returned later}}
534+ // expected-note@-1 {{returned here}}
535535}
536536
537- // FIXME: No lifetime warning for this as no expire facts are generated for parameters
538537int * return_pointer_to_parameter (int a) {
539- return &a;
538+ return &a; // expected-warning {{address of stack memory is returned later}}
539+ // expected-note@-1 {{returned here}}
540540}
541541
542542const int & return_reference_to_parameter (int a)
@@ -788,9 +788,52 @@ const MyObj& lifetimebound_return_ref_to_local() {
788788 // expected-note@-1 {{returned here}}
789789}
790790
791- // FIXME: Fails to diagnose UAR when a reference to a by-value param escapes via the return value.
792- View lifetimebound_return_of_by_value_param (MyObj stack_param) {
793- return Identity (stack_param);
791+ View lifetimebound_return_by_value_param (MyObj stack_param) {
792+ return Identity (stack_param); // expected-warning {{address of stack memory is returned later}}
793+ // expected-note@-1 {{returned here}}
794+ }
795+
796+ View lifetimebound_return_by_value_multiple_param (int cond, MyObj a, MyObj b, MyObj c) {
797+ if (cond == 1 )
798+ return Identity (a); // expected-warning {{address of stack memory is returned later}}
799+ // expected-note@-1 {{returned here}}
800+ if (cond == 2 )
801+ return Identity (b); // expected-warning {{address of stack memory is returned later}}
802+ // expected-note@-1 {{returned here}}
803+ return Identity (c); // expected-warning {{address of stack memory is returned later}}
804+ // expected-note@-1 {{returned here}}
805+ }
806+
807+ template <class T >
808+ View lifetimebound_return_by_value_param_template (T t) {
809+ return Identity (t); // expected-warning {{address of stack memory is returned later}}
810+ // expected-note@-1 {{returned here}}
811+ }
812+ void use_lifetimebound_return_by_value_param_template () {
813+ lifetimebound_return_by_value_param_template (MyObj{}); // expected-note {{in instantiation of}}
814+ }
815+
816+ void lambda_uar_param () {
817+ auto lambda = [](MyObj stack_param) {
818+ return Identity (stack_param); // expected-warning {{address of stack memory is returned later}}
819+ // expected-note@-1 {{returned here}}
820+ };
821+ lambda (MyObj{});
822+ }
823+
824+ // FIXME: This should be detected. We see correct destructors but origin flow breaks somewhere.
825+ namespace VariadicTemplatedParamsUAR {
826+
827+ template <typename ... Args>
828+ View Max (Args... args [[clang::lifetimebound]]);
829+
830+ template <typename ... Args>
831+ View lifetimebound_return_of_variadic_param (Args... args) {
832+ return Max (args...);
833+ }
834+ void test_variadic () {
835+ lifetimebound_return_of_variadic_param (MyObj{1 }, MyObj{2 }, MyObj{3 });
836+ }
794837}
795838
796839// FIXME: Fails to diagnose UAF when a reference to a by-value param escapes via an out-param.
0 commit comments