| 238 | } |
| 239 | |
| 240 | void deriveAliasing ( const FunctionPtr & func, TextWriter & logs, bool logAliasing ) { |
| 241 | if ( func->arguments.size()==0 && func->useGlobalVariables.size()==0 && func->useFunctions.size()==0 ) return; |
| 242 | // collect indirect global variables |
| 243 | IndirectSources ind; |
| 244 | das_hash_set<Function *> depInd; |
| 245 | appendIndVariables(func,ind,depInd); |
| 246 | if ( !(func->copyOnReturn || func->moveOnReturn) ) return; // not a cmres function, we don't need cmres aliasing |
| 247 | if ( func->arguments.size()==0 && ind.size()==0 ) return; // no arguments, no globals, no cmres aliasing |
| 248 | // collect type aliasing |
| 249 | if ( logAliasing ) logs << "function " << func->getMangledName() << " returns by reference\n"; |
| 250 | das_set<Structure *> rdep; |
| 251 | TypeAliasMap resTypeAliases; |
| 252 | func->result->collectAliasing(resTypeAliases, rdep, false); |
| 253 | // do arguments |
| 254 | func->resultAliases.clear(); |
| 255 | for ( size_t i=0, is=func->arguments.size(); i!=is; ++i ) { |
| 256 | if ( !(func->arguments[i]->type->isRef() || func->arguments[i]->type->baseType==Type::tPointer) ) { |
| 257 | continue; |
| 258 | } |
| 259 | das_set<Structure *> dep; |
| 260 | TypeAliasMap typeAliases; |
| 261 | func->arguments[i]->type->collectAliasing(typeAliases, dep, false); |
| 262 | for ( auto resT : resTypeAliases ) { |
| 263 | for ( auto alias : typeAliases ) { |
| 264 | if ( alias.second.first->isSameType(*(resT.second.first),RefMatters::no,ConstMatters::no,TemporaryMatters::no,AllowSubstitute::yes,false,false) ) { |
| 265 | func->resultAliases.push_back(int(i)); |
| 266 | if ( logAliasing ) logs << "\targument " << i << " aliasing result with type " |
| 267 | << func->arguments[i]->type->describe() << "\n"; |
| 268 | goto nada; |
| 269 | } |
| 270 | } |
| 271 | } |
| 272 | nada:; |
| 273 | } |
| 274 | // do globals |
| 275 | func->resultAliasesGlobals.clear(); |
| 276 | for ( auto & it : ind ) { |
| 277 | if ( !(it.first->type->isRef() || it.first->type->baseType==Type::tPointer) || it.first->type->temporary) { |
| 278 | continue; |
| 279 | } |
| 280 | das_set<Structure *> dep; |
| 281 | TypeAliasMap typeAliases; |
| 282 | it.first->type->collectAliasing(typeAliases, dep, false); |
| 283 | for ( auto resT : resTypeAliases ) { |
| 284 | for ( auto alias : typeAliases ) { |
| 285 | if ( alias.second.first->isSameType(*(resT.second.first),RefMatters::no,ConstMatters::no,TemporaryMatters::no,AllowSubstitute::yes,false,false) ) { |
| 286 | Function::AliasInfo info = {it.first, it.second, resT.second.second || alias.second.second}; |
| 287 | func->resultAliasesGlobals.emplace_back(info); |
| 288 | if ( logAliasing ) logs << "\tglobal variable " << it.first->getMangledName() << " aliasing result with type " |
| 289 | << it.first->type->describe() << (info.viaPointer ? " through pointer aliasing" : "") << "\n"; |
| 290 | goto nadaHere; |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | nadaHere:; |
| 295 | } |
| 296 | } |
| 297 |
no test coverage detected