an example/test uses a dangling reference

Open
#8 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Needs clarification
Activity status
Stale
Tech stack
cpp
Domain
testing

Research direction

Start with libs/local_function/test/return_assign.cpp and run the existing test to compare the temporary and local-variable cases. Trace how the returned boost::function retains the bound reference, then determine the intended safe test behavior; done means the example no longer relies on a dangling reference and the relevant lifetime case is correctly covered.

Written by the indexing model from the issue text.

Description

libs/local_function/test/return_assign.cpp uses a dangling reference:

#include <boost/local_function.hpp>
#include <boost/function.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>

//[return_assign
void call1(boost::function<int (int) > f) { BOOST_TEST(f(1) == 5); }
void call0(boost::function<int (void)> f) { BOOST_TEST(f() == 5); }

boost::function<int (int, int)> linear(const int& slope) {
    int BOOST_LOCAL_FUNCTION(const bind& slope,
            int x, default 1, int y, default 2) {
        return x + slope * y;
    } BOOST_LOCAL_FUNCTION_NAME(lin)

    boost::function<int (int, int)> f = lin; // Assign to local variable.
    BOOST_TEST(f(1, 2) == 5);

    call1(lin); // Pass to other functions.
    call0(lin);

    return lin; // Return.
}

void call(void) {
    boost::function<int (int, int)> f = linear(2); // create temporary, bind reference to temporary
    BOOST_TEST(f(1, 2) == 5); // !!!!!!!!!!!!!!!!!!!!!!!! use the reference
}
//]

int main(void) {
    call();
    return boost::report_errors();
}

changing the target from temporary to local variable can let the test fail:

#include <boost/local_function.hpp>
#include <boost/function.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <iostream>

//[return_assign
void call1(boost::function<int(int) > f) { BOOST_TEST(f(1) == 5); }
void call0(boost::function<int(void)> f) { BOOST_TEST(f() == 5); }

boost::function<int(int, int)> linear(const int& slope) {
    int BOOST_LOCAL_FUNCTION(const bind & slope,
        int x, default 1, int y, default 2) {
        return x + slope * y;
    } BOOST_LOCAL_FUNCTION_NAME(lin)

        boost::function<int(int, int)> f = lin; // Assign to local variable.
    BOOST_TEST(f(1, 2) == 5);

    call1(lin); // Pass to other functions.
    call0(lin);

    return lin; // Return.
}

void call1(void) {
    boost::function<int(int, int)> f = linear(2);
    BOOST_TEST(f(1, 2) == 5); // !!!!!!!!!!!!!!!!!!!!!!!! test passed, although dangling reference
}
void call2(void) {
    int a = 2;
    boost::function<int(int, int)> f = linear(a);
    a = 3;
    BOOST_TEST(f(1, 2) == 5); // !!!!!!!!!!!!!!!!!!!!!!!! test failed
}
//]

int main(void) {
    call1();
    call2();
    return boost::report_errors();
}
Dominant language
C++
Stars
11
Forks
28
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from boostorg/local_function

All issues in boostorg/local_function

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.