Skip to content

Commit

Permalink
Fixed object-lifetime visualization for more than one temporary.
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasfertig committed Jul 16, 2024
1 parent 7dd35be commit caec790
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 10 deletions.
21 changes: 13 additions & 8 deletions CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,11 +905,12 @@ class BindingDeclFinder : public ConstStmtVisitor<BindingDeclFinder>
/// \brief Find a \c DeclRefExpr belonging to a \c DecompositionDecl
class TemporaryDeclFinder : public StmtVisitor<TemporaryDeclFinder>
{
CodeGenerator& codeGenerator;
bool mFound{};
bool mHaveTemporary{};
Stmt* mPrevStmt{};
std::string mTempName{};
CodeGenerator& codeGenerator;
bool mFound{};
bool mHaveTemporary{};
Stmt* mPrevStmt{};
std::string mTempName{};
std::vector<VarDecl*> mDecls{};

public:
TemporaryDeclFinder(CodeGenerator& _codeGenerator, const Stmt* stmt, bool inspectReturn = false)
Expand All @@ -920,6 +921,10 @@ class TemporaryDeclFinder : public StmtVisitor<TemporaryDeclFinder>

Visit(mPrevStmt);

for(auto d : mDecls) {
codeGenerator.InsertArg(d);
}

RETURN_IF(not GetInsightsOptions().UseShow2C or mFound or not inspectReturn);

if(auto* expr = dyn_cast_or_null<CXXConstructExpr>(stmt)) {
Expand Down Expand Up @@ -1001,7 +1006,7 @@ class TemporaryDeclFinder : public StmtVisitor<TemporaryDeclFinder>
ReplaceNode(mPrevStmt, expr, newValue);
}

codeGenerator.InsertArg(vd);
mDecls.push_back(vd);
}

#if 0
Expand Down Expand Up @@ -1031,14 +1036,14 @@ class TemporaryDeclFinder : public StmtVisitor<TemporaryDeclFinder>
auto* newValue = mkDeclRefExpr(vd);
ReplaceNode(mPrevStmt, stmt, newValue);

if(SD_FullExpression == stmt->getStorageDuration()) {
if(SD_FullExpression == stmt->getStorageDuration() and not mHaveTemporary) {
codeGenerator.StartLifetimeScope();
mHaveTemporary = true;
} else if(const auto* extending = stmt->getExtendingDecl()) {
codeGenerator.LifetimeAddExtended(vd, extending);
}

codeGenerator.InsertArg(vd);
mDecls.push_back(vd);
}

void VisitStmt(Stmt* stmt)
Expand Down
4 changes: 2 additions & 2 deletions tests/EduLifeTimeTest12.expect
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ int main()
const std::pair<int, int> __temporary10_16 = std::pair<int, int>{__temporary10_13, __temporary10_15};
S a = {1, __temporary10_16};
/* __temporary10_15 // lifetime ends here */
/* __temporary10_13 // lifetime ends here */
int __temporary11_21 = 2;
int __temporary11_23 = 3;
const std::pair<int, int> __temporary11_24 = std::pair<int, int>{__temporary11_21, __temporary11_23};
S * p = new S{1, __temporary11_24};
/* __temporary11_24 // lifetime ends here */
return 0;
/* __temporary11_23 // lifetime ends here */
/* __temporary11_21 // lifetime ends here */
/* __temporary10_13 // lifetime ends here */
return 0;
/* __temporary10_16 // lifetime ends here */
/* a // lifetime ends here */
}
29 changes: 29 additions & 0 deletions tests/EduLifeTimeTest13.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// cmdlineinsights:-edu-show-lifetime

template<class T, class U>
struct pair {
T first;
U second;

pair(T&& t, U&& u)
: first{t}
, second{u}
{}

pair(const T& t, const U& u)
: first{t}
, second{u}
{}
};

// From: https://eel.is/c++draft/class.temporary#6.11
struct S {
int mi;
const pair<int, int>& failingp;
};

int main()
{
S invalids{1, {2, 3}}; // #A
}

61 changes: 61 additions & 0 deletions tests/EduLifeTimeTest13.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*************************************************************************************
* NOTE: This an educational hand-rolled transformation. Things can be incorrect or *
* buggy. *
*************************************************************************************/
template<class T, class U>
struct pair
{
T first;
U second;
inline pair(T && t, U && u)
: first{t}
, second{u}
{
}

inline pair(const T & t, const U & u)
: first{t}
, second{u}
{
}

};

/* First instantiated from: EduLifeTimeTest13.cpp:27 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct pair<int, int>
{
int first;
int second;
inline pair(int && t, int && u)
: first{t}
, second{u}
{
}

inline pair(const int & t, const int & u);

};

#endif

struct S
{
int mi;
const pair<int, int> & failingp;
};


int main()
{
int __temporary27_18 = 2;
int __temporary27_21 = 3;
const pair<int, int> __temporary27_22 = pair<int, int>{__temporary27_18, __temporary27_21};
S invalids = {1, __temporary27_22};
/* __temporary27_21 // lifetime ends here */
/* __temporary27_18 // lifetime ends here */
return 0;
/* __temporary27_22 // lifetime ends here */
/* invalids // lifetime ends here */
}

0 comments on commit caec790

Please sign in to comment.