Fix assertion failure when GlobalVariable::toSMT is called twice in src
MODIFY
ir/state.cpp
ir/state.cpp
@@ -183,22 +183,32 @@ void State::resetUndefVars() {
}
void State::addGlobalVarBid(const string &glbvar, unsigned bid) {
- ENSURE(glbvar_bids.emplace(glbvar, bid).second);
+ ENSURE(glbvar_bids.emplace(glbvar, make_pair(bid, true)).second);
}
-bool State::hasGlobalVarBid(const string &glbvar, unsigned &bid) const {
+bool State::hasGlobalVarBid(const string &glbvar, unsigned &bid,
+ bool &allocated) const {
auto itr = glbvar_bids.find(glbvar);
bool found = itr != glbvar_bids.end();
if (found) {
- bid = itr->second;
+ bid = itr->second.first;
+ allocated = itr->second.second;
}
return found;
}
+void State::markGlobalAsAllocated(const string &glbvar) {
+ auto itr = glbvar_bids.find(glbvar);
+ assert(itr != glbvar_bids.end());
+ itr->second.second = true;
+}
+
void State::copyGlobalVarBidsFromSrc(const State &src) {
assert(glbvar_bids.empty());
assert(src.isSource());
glbvar_bids = src.glbvar_bids;
+ for (auto &itm : glbvar_bids)
+ itm.second.second = false;
Memory::resetLocalBids();
}

MODIFY
ir/state.h
ir/state.h
@@ -50,8 +50,8 @@ private:
predecessor_data;
std::unordered_set<const BasicBlock*> seen_bbs;
- // Global variables' memory block ids
- std::unordered_map<std::string, unsigned> glbvar_bids;
+ // Global variables' memory block ids & Memory::alloc has been called?
+ std::unordered_map<std::string, std::pair<unsigned, bool> > glbvar_bids;
// temp state
DomainTy domain;
@@ -118,8 +118,10 @@ public:
void addGlobalVarBid(const std::string &glbvar, unsigned bid);
// Checks whether glbvar has block id assigned.
- // If it has, bid is updated with the block id.
- bool hasGlobalVarBid(const std::string &glbvar, unsigned &bid) const;
+ // If it has, bid is updated with the block id, and allocated is updated too.
+ bool hasGlobalVarBid(const std::string &glbvar, unsigned &bid,
+ bool &allocated) const;
+ void markGlobalAsAllocated(const std::string &glbvar);
void copyGlobalVarBidsFromSrc(const State &src);
private:

MODIFY
ir/value.cpp
ir/value.cpp
@@ -87,12 +87,18 @@ StateValue GlobalVariable::toSMT(State &s) const {
auto sizeexpr = expr::mkUInt(allocsize, 64);
expr ptrval;
unsigned glbvar_bid;
+ bool allocated;
auto blkkind = isconst ? Memory::CONSTGLOBAL : Memory::GLOBAL;
- if (s.hasGlobalVarBid(getName(), glbvar_bid)) {
+ if (s.hasGlobalVarBid(getName(), glbvar_bid, allocated)) {
+ if (!allocated) {
// Use the same block id that is used by src
assert(!s.isSource());
ptrval = s.getMemory().alloc(sizeexpr, align, blkkind, glbvar_bid);
+ s.markGlobalAsAllocated(getName());
+ } else {
+ ptrval = Pointer(s.getMemory(), glbvar_bid, false).release();
+ }
} else {
ptrval = s.getMemory().alloc(sizeexpr, align, blkkind, nullopt,
&glbvar_bid);

ADD
tests/alive-tv/constexpr/aggregate2.src.ll
+@a = constant i8 0
+@x = constant { i8*, i8* } { i8* @a, i8* @a }
+
+define i8* @f() {
+ %a = load { i8*, i8* }, { i8*, i8* }* @x
+ %b = extractvalue {i8*, i8*} %a, 0
+ ret i8* %b
+}

ADD
tests/alive-tv/constexpr/aggregate2.tgt.ll
+@a = constant i8 0
+@x = constant { i8*, i8* } { i8* @a, i8* @a }
+
+define i8* @f() {
+ ret i8* @a
+}

Fix assertion failure when GlobalVariable::toSMT is called twice in src (#206)