* */
| 156 | * |
| 157 | */ |
| 158 | Expression * |
| 159 | Expression::make_random(CGContext &cg_context, const Type* type, const CVQualifiers* qfer, bool no_func, bool no_const, enum eTermType tt) |
| 160 | { |
| 161 | DEPTH_GUARD_BY_TYPE_RETURN_WITH_FLAG(dtExpression, tt, NULL); |
| 162 | Expression *e = 0; |
| 163 | if (type == NULL) { |
| 164 | do { |
| 165 | type = cg_context.get_effect_context().is_side_effect_free() ? Type::choose_random_nonvoid() : Type::choose_random_nonvoid_nonvolatile(); |
| 166 | } while (type->eType == eStruct && tt == eConstant); |
| 167 | } |
| 168 | assert(!(no_func && tt == eFunction)); |
| 169 | assert(!(no_const && tt == eConstant)); |
| 170 | // constant struct variables can not be a subexpression? |
| 171 | assert(!(type->eType == eStruct && tt == eConstant)); |
| 172 | |
| 173 | // if no term type is provided, choose a random term type with restrictions |
| 174 | if (tt == MAX_TERM_TYPES) { |
| 175 | VectorFilter filter(&Expression::exprTable_); |
| 176 | if (no_func || |
| 177 | (!CGOptions::return_structs() && type->eType == eStruct) || |
| 178 | (!CGOptions::return_unions() && type->eType == eUnion)) { |
| 179 | filter.add(eFunction); |
| 180 | } |
| 181 | // struct constants can't be subexpressions (union constant can't either?) |
| 182 | if (no_const || type->eType == eStruct || type->eType == eUnion) { |
| 183 | filter.add(eConstant); |
| 184 | } |
| 185 | // can't assign to constant struct/unions. on the other hand, assign to a volatile |
| 186 | // struct/union cause too much trouble for effect analysis, disable it for now |
| 187 | if (type->is_const_struct_union() || type->is_volatile_struct_union()) { |
| 188 | filter.add(eAssignment); |
| 189 | } |
| 190 | if (cg_context.expr_depth + 2 > CGOptions::max_expr_depth()) { |
| 191 | filter.add(eFunction).add(eAssignment).add(eCommaExpr); |
| 192 | } |
| 193 | tt = ExpressionTypeProbability(&filter); |
| 194 | } |
| 195 | |
| 196 | ERROR_GUARD(NULL); |
| 197 | |
| 198 | switch (tt) { |
| 199 | case eConstant: |
| 200 | if (type->eType == eSimple) |
| 201 | assert(type->simple_type != eVoid); |
| 202 | e = Constant::make_random(type); |
| 203 | break; |
| 204 | case eVariable: |
| 205 | e = ExpressionVariable::make_random(cg_context, type, qfer); |
| 206 | break; |
| 207 | case eFunction: |
| 208 | e = ExpressionFuncall::make_random(cg_context, type, qfer); |
| 209 | break; |
| 210 | case eAssignment: |
| 211 | e = ExpressionAssign::make_random(cg_context, type, qfer); |
| 212 | break; |
| 213 | case eCommaExpr: |
| 214 | e = ExpressionComma::make_random(cg_context, type, qfer); |
| 215 | break; |
nothing calls this directly
no test coverage detected