From 6c33af0e7e737e3a7832d18824e8d393137b5fd1 Mon Sep 17 00:00:00 2001 From: Ajay Brahmakshatriya Date: Mon, 22 Apr 2024 15:51:26 -0400 Subject: [PATCH] Disabled copy elision for return from [] and * operators so that variables initialized from such expressions don' t get removed --- include/builder/dyn_var.h | 29 +++++++++++++++++++++++------ samples/outputs.var_names/sample38 | 15 +++++++++++++++ samples/outputs/sample38 | 15 +++++++++++++++ samples/sample38.cpp | 4 ++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/include/builder/dyn_var.h b/include/builder/dyn_var.h index 0c64872..ca9c101 100644 --- a/include/builder/dyn_var.h +++ b/include/builder/dyn_var.h @@ -339,10 +339,10 @@ struct member_initializer_end { template struct dyn_var_parent_selector::value && !std::is_base_of::value - && !std::is_base_of::value + std::is_class::type>::value && !std::is_base_of::type>::value + && !std::is_base_of::type>::value >::type> - : public member_initializer_begin, public T, public member_initializer_end {}; + : public member_initializer_begin, public std::remove_reference::type, public member_initializer_end {}; // Actual dyn_var implementation // Split design to allow for easily extending types with specialization @@ -370,6 +370,23 @@ class dyn_var : public dyn_var_impl, public dyn_var_parent_selector // dyn var specialization for pointer types to return the appropriate types on [], * and -> +template +class dyn_var_mimic: public dyn_var { + // Behaves exactly like a dyn_var for most purposes + // including accessign members + // But allows us to disable copy elision when required + // Currently only used when returning dyn_vars from [] and * operators +public: + typedef dyn_var super; + + using super::super; + using super::operator=; + builder operator=(const dyn_var_mimic &t) { + return *this = (builder)t; + } +}; + + template class dyn_var : public dyn_var_impl { // No need for parent selector, pointers types aren't custom types by themselves @@ -387,10 +404,10 @@ class dyn_var } // Specialization for the [] operator to return the right type - dyn_var operator[](const builder &bt) { - return (cast)this->dyn_var_impl::operator[](bt); + dyn_var_mimic operator[](const builder &bt) { + return (dyn_var_mimic)(cast)this->dyn_var_impl::operator[](bt); } - dyn_var operator*() { + dyn_var_mimic operator*() { return this->operator[](0); } // Hack for creating a member that's live across return site diff --git a/samples/outputs.var_names/sample38 b/samples/outputs.var_names/sample38 index 8420240..03e8fce 100644 --- a/samples/outputs.var_names/sample38 +++ b/samples/outputs.var_names/sample38 @@ -51,6 +51,19 @@ STMT_BLOCK VAR (ptr_3) INT_CONST (0) INT_CONST (1) + DECL_STMT + NAMED_TYPE (FooT) + VAR (i_4) + SQ_BKT_EXPR + VAR_EXPR + VAR (ptr_3) + INT_CONST (0) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + VAR_EXPR + VAR (i_4) + INT_CONST (3) { FooT g_0; g_0 = g_0 + 1; @@ -60,4 +73,6 @@ STMT_BLOCK FooT* ptr_3 = (&(g_0)); ptr_3->member = 0; ptr_3->member = 1; + FooT i_4 = ptr_3[0]; + i_4.member = 3; } diff --git a/samples/outputs/sample38 b/samples/outputs/sample38 index ec58f09..7fda647 100644 --- a/samples/outputs/sample38 +++ b/samples/outputs/sample38 @@ -51,6 +51,19 @@ STMT_BLOCK VAR (var3) INT_CONST (0) INT_CONST (1) + DECL_STMT + NAMED_TYPE (FooT) + VAR (var4) + SQ_BKT_EXPR + VAR_EXPR + VAR (var3) + INT_CONST (0) + EXPR_STMT + ASSIGN_EXPR + MEMBER_ACCESS_EXPR (member) + VAR_EXPR + VAR (var4) + INT_CONST (3) { FooT var0; var0 = var0 + 1; @@ -60,4 +73,6 @@ STMT_BLOCK FooT* var3 = (&(var0)); var3->member = 0; var3->member = 1; + FooT var4 = var3[0]; + var4.member = 3; } diff --git a/samples/sample38.cpp b/samples/sample38.cpp index a8ed2f2..ea0a750 100644 --- a/samples/sample38.cpp +++ b/samples/sample38.cpp @@ -43,6 +43,10 @@ static void bar(void) { dyn_var ptr = &g; (*ptr).member = 0; ptr->member = 1; + + // This SHOULD produce a copy + dyn_var i = *ptr; + i.member = 3; } int main(int argc, char *argv[]) {