fix emission of allocsize() attr for the function under test
It was only being encoded for fn calls
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -2816,14 +2816,15 @@ void Return::print(ostream &os) const {
static StateValue
check_ret_attributes(State &s, StateValue &&sv, const Type &t,
- const FnAttrs &attrs) {
+ const FnAttrs &attrs,
+ const vector<pair<Value*, ParamAttrs>> &args) {
if (auto agg = t.getAsAggregateType()) {
vector<StateValue> vals;
for (unsigned i = 0, e = agg->numElementsConst(); i != e; ++i) {
if (agg->isPadding(i))
continue;
- vals.emplace_back(
- check_ret_attributes(s, agg->extract(sv, i), agg->getChild(i), attrs));
+ vals.emplace_back(check_ret_attributes(s, agg->extract(sv, i),
+ agg->getChild(i), attrs, args));
}
return agg->aggregateVals(vals);
}
@@ -2834,7 +2835,7 @@ check_ret_attributes(State &s, StateValue &&sv, const Type &t,
sv.non_poison &= !p.isNocapture();
}
- return check_return_value(s, std::move(sv), t, attrs, {});
+ return check_return_value(s, std::move(sv), t, attrs, args);
}
static void eq_val_rec(State &s, const Type &t, const StateValue &a,
@@ -2860,7 +2861,13 @@ StateValue Return::toSMT(State &s) const {
retval = s[*val];
s.addUB(s.getMemory().checkNocapture());
- retval = check_ret_attributes(s, std::move(retval), getType(), attrs);
+
+ vector<pair<Value*, ParamAttrs>> args;
+ for (auto &arg : s.getFn().getInputs()) {
+ args.emplace_back(const_cast<Value*>(&arg), ParamAttrs());
+ }
+
+ retval = check_ret_attributes(s, std::move(retval), getType(), attrs, args);
if (attrs.has(FnAttrs::NoReturn))
s.addUB(expr(false));

MODIFY
llvm_util/known_fns.cpp
llvm_util/known_fns.cpp
@@ -42,6 +42,9 @@ bool implict_attrs_(llvm::LibFunc libfn, FnAttrs &attrs,
switch (libfn) {
case llvm::LibFunc_calloc:
+ attrs.allocsize_1 = 1;
+ [[fallthrough]];
+
case llvm::LibFunc_malloc:
case llvm::LibFunc_vec_calloc:
ret_and_args_no_undef();
@@ -50,6 +53,8 @@ bool implict_attrs_(llvm::LibFunc libfn, FnAttrs &attrs,
attrs.set(FnAttrs::NoThrow);
attrs.set(FnAttrs::NoFree);
attrs.set(FnAttrs::WillReturn);
+ attrs.set(FnAttrs::AllocSize);
+ attrs.allocsize_0 = 0;
RETURN_EXACT();
case llvm::LibFunc_fwrite:
@@ -406,6 +411,8 @@ known_call(llvm::CallInst &i, const llvm::TargetLibraryInfo &TLI,
if (!ty)
RETURN_EXACT();
+ auto decl = i.getCalledFunction();
+
// TODO: add support for checking mismatch of C vs C++ alloc fns
if (llvm::isMallocOrCallocLikeFn(&i, &TLI)) {
// aligned malloc
@@ -422,11 +429,11 @@ known_call(llvm::CallInst &i, const llvm::TargetLibraryInfo &TLI,
}
// calloc
- if (auto *init = llvm::getInitialValueOfAllocation(&i, &TLI, i.getType());
- init && init->isNullValue())
+ if (decl && decl->getName() == "calloc") {
+
RETURN_VAL(make_unique<Calloc>(*ty, value_name(i), *args[0], *args[1],
std::move(attrs)));
-
+ }
// malloc or new
RETURN_VAL(
make_unique<Malloc>(*ty, value_name(i), *args[0], std::move(attrs)));
@@ -445,7 +452,6 @@ known_call(llvm::CallInst &i, const llvm::TargetLibraryInfo &TLI,
RETURN_VAL(make_unique<Free>(*args[0]));
}
- auto decl = i.getCalledFunction();
llvm::LibFunc libfn;
if (!decl || !TLI.getLibFunc(*decl, libfn) || !TLI.has(libfn))
RETURN_EXACT();

fix emission of allocsize() attr for the function under test
It was only being encoded for fn calls