| 212 | } |
| 213 | |
| 214 | StateValue Input::mkInput(State &s, const Type &ty, unsigned child) const { |
| 215 | if (auto agg = ty.getAsAggregateType()) { |
| 216 | vector<StateValue> vals; |
| 217 | for (unsigned i = 0, e = agg->numElementsConst(); i < e; ++i) { |
| 218 | if (agg->isPadding(i)) |
| 219 | continue; |
| 220 | auto name = getSMTName(child + i); |
| 221 | vals.emplace_back(mkInput(s, agg->getChild(i), child + i)); |
| 222 | } |
| 223 | return agg->aggregateVals(vals); |
| 224 | } |
| 225 | |
| 226 | expr val; |
| 227 | if (hasAttribute(ParamAttrs::ByVal)) { |
| 228 | unsigned bid; |
| 229 | expr size = expr::mkUInt(attrs.blockSize, bits_size_t); |
| 230 | val = Pointer(s.getMemory(), |
| 231 | get_global(s, smt_name, &size, attrs.align, false, false,bid)) |
| 232 | .setAttrs(attrs) |
| 233 | .setIsBasedOnArg() |
| 234 | .release(); |
| 235 | bool is_const = hasAttribute(ParamAttrs::NoWrite) || |
| 236 | !s.getFn().getFnAttrs().mem.canWrite(MemoryAccess::Args); |
| 237 | s.getMemory().markByVal(bid, is_const); |
| 238 | } else { |
| 239 | auto name = getSMTName(child); |
| 240 | val = ty.mkInput(s, name.c_str(), attrs); |
| 241 | } |
| 242 | |
| 243 | auto undef_mask = getUndefVar(ty, child); |
| 244 | if (config::disable_undef_input || attrs.poisonImpliesUB()) { |
| 245 | s.addUB(undef_mask == 0); |
| 246 | } else if (s.isAsmMode()) { |
| 247 | // do nothing; there's no undef in assembly |
| 248 | } else { |
| 249 | auto [undef, var] = ty.mkUndefInput(s, attrs); |
| 250 | if (undef_mask.bits() == 1) |
| 251 | val = expr::mkIf(undef_mask == 0, val, undef); |
| 252 | else |
| 253 | val = (~undef_mask & val) | (undef_mask & undef); |
| 254 | s.addUndefVar(std::move(var)); |
| 255 | } |
| 256 | |
| 257 | auto state_val = attrs.encode(s, {std::move(val), expr(true)}, ty, true); |
| 258 | |
| 259 | bool never_poison = config::disable_poison_input || attrs.poisonImpliesUB(); |
| 260 | expr np = expr::mkBoolVar(("np_" + getSMTName(child)).c_str()); |
| 261 | if (never_poison) { |
| 262 | s.addUB(std::move(np)); |
| 263 | } else if (s.isAsmMode()) { |
| 264 | // There's no poison in assembly |
| 265 | state_val.non_poison = true; |
| 266 | } else { |
| 267 | state_val.non_poison &= np; |
| 268 | } |
| 269 | |
| 270 | return state_val; |
| 271 | } |
nothing calls this directly
no test coverage detected