Skip to content

Commit

Permalink
Disabled copy elision for return from [] and * operators so that vari…
Browse files Browse the repository at this point in the history
…ables initialized from such expressions don'

t get removed
  • Loading branch information
AjayBrahmakshatriya committed Apr 22, 2024
1 parent 5d60a58 commit 6c33af0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
29 changes: 23 additions & 6 deletions include/builder/dyn_var.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,10 @@ struct member_initializer_end {
template <typename T>
struct dyn_var_parent_selector<T,
typename std::enable_if<
std::is_class<T>::value && !std::is_base_of<var, T>::value
&& !std::is_base_of<static_var_base, T>::value
std::is_class<typename std::remove_reference<T>::type>::value && !std::is_base_of<var, typename std::remove_reference<T>::type>::value
&& !std::is_base_of<static_var_base, typename std::remove_reference<T>::type>::value
>::type>
: public member_initializer_begin<T>, public T, public member_initializer_end {};
: public member_initializer_begin<T>, public std::remove_reference<T>::type, public member_initializer_end {};

// Actual dyn_var implementation
// Split design to allow for easily extending types with specialization
Expand Down Expand Up @@ -370,6 +370,23 @@ class dyn_var : public dyn_var_impl<T>, public dyn_var_parent_selector<T, void>

// dyn var specialization for pointer types to return the appropriate types on [], * and ->

template <typename T>
class dyn_var_mimic: public dyn_var<T> {
// 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<T> super;

using super::super;
using super::operator=;
builder operator=(const dyn_var_mimic<T> &t) {
return *this = (builder)t;
}
};


template <typename T>
class dyn_var<T *>
: public dyn_var_impl<T *> { // No need for parent selector, pointers types aren't custom types by themselves
Expand All @@ -387,10 +404,10 @@ class dyn_var<T *>
}

// Specialization for the [] operator to return the right type
dyn_var<T> operator[](const builder &bt) {
return (cast)this->dyn_var_impl<T *>::operator[](bt);
dyn_var_mimic<T> operator[](const builder &bt) {
return (dyn_var_mimic<T>)(cast)this->dyn_var_impl<T *>::operator[](bt);
}
dyn_var<T> operator*() {
dyn_var_mimic<T> operator*() {
return this->operator[](0);
}
// Hack for creating a member that's live across return site
Expand Down
15 changes: 15 additions & 0 deletions samples/outputs.var_names/sample38
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
15 changes: 15 additions & 0 deletions samples/outputs/sample38
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -60,4 +73,6 @@ STMT_BLOCK
FooT* var3 = (&(var0));
var3->member = 0;
var3->member = 1;
FooT var4 = var3[0];
var4.member = 3;
}
4 changes: 4 additions & 0 deletions samples/sample38.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ static void bar(void) {
dyn_var<foo_t *> ptr = &g;
(*ptr).member = 0;
ptr->member = 1;

// This SHOULD produce a copy
dyn_var<foo_t> i = *ptr;
i.member = 3;
}

int main(int argc, char *argv[]) {
Expand Down

0 comments on commit 6c33af0

Please sign in to comment.