Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bug in dyn_var implementation where returns from [] and * cause bug #73

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading