@@ -271,6 +271,43 @@ class TrivialFunctionAnalysisVisitor
271
271
272
272
TrivialFunctionAnalysisVisitor (CacheTy &Cache) : Cache(Cache) {}
273
273
274
+ bool IsFunctionTrivial (const Decl *D) {
275
+ auto CacheIt = Cache.find (D);
276
+ if (CacheIt != Cache.end ())
277
+ return CacheIt->second ;
278
+
279
+ // Treat a recursive function call to be trivial until proven otherwise.
280
+ auto [RecursiveIt, IsNew] = RecursiveFn.insert (std::make_pair (D, true ));
281
+ if (!IsNew)
282
+ return RecursiveIt->second ;
283
+
284
+ bool Result = [&]() {
285
+ if (auto *CtorDecl = dyn_cast<CXXConstructorDecl>(D)) {
286
+ for (auto *CtorInit : CtorDecl->inits ()) {
287
+ if (!Visit (CtorInit->getInit ()))
288
+ return false ;
289
+ }
290
+ }
291
+ const Stmt *Body = D->getBody ();
292
+ if (!Body)
293
+ return false ;
294
+ return Visit (Body);
295
+ }();
296
+
297
+ if (!Result) {
298
+ // D and its mutually recursive callers are all non-trivial.
299
+ for (auto &It : RecursiveFn)
300
+ It.second = false ;
301
+ }
302
+ RecursiveIt = RecursiveFn.find (D);
303
+ assert (RecursiveIt != RecursiveFn.end ());
304
+ Result = RecursiveIt->second ;
305
+ RecursiveFn.erase (RecursiveIt);
306
+ Cache[D] = Result;
307
+
308
+ return Result;
309
+ }
310
+
274
311
bool VisitStmt (const Stmt *S) {
275
312
// All statements are non-trivial unless overriden later.
276
313
// Don't even recurse into children by default.
@@ -368,7 +405,7 @@ class TrivialFunctionAnalysisVisitor
368
405
Name == " bitwise_cast" || Name.find (" __builtin" ) == 0 )
369
406
return true ;
370
407
371
- return TrivialFunctionAnalysis::isTrivialImpl (Callee, Cache );
408
+ return IsFunctionTrivial (Callee);
372
409
}
373
410
374
411
bool
@@ -403,7 +440,7 @@ class TrivialFunctionAnalysisVisitor
403
440
return true ;
404
441
405
442
// Recursively descend into the callee to confirm that it's trivial as well.
406
- return TrivialFunctionAnalysis::isTrivialImpl (Callee, Cache );
443
+ return IsFunctionTrivial (Callee);
407
444
}
408
445
409
446
bool VisitCXXOperatorCallExpr (const CXXOperatorCallExpr *OCE) {
@@ -413,7 +450,7 @@ class TrivialFunctionAnalysisVisitor
413
450
if (!Callee)
414
451
return false ;
415
452
// Recursively descend into the callee to confirm that it's trivial as well.
416
- return TrivialFunctionAnalysis::isTrivialImpl (Callee, Cache );
453
+ return IsFunctionTrivial (Callee);
417
454
}
418
455
419
456
bool VisitCXXDefaultArgExpr (const CXXDefaultArgExpr *E) {
@@ -439,7 +476,7 @@ class TrivialFunctionAnalysisVisitor
439
476
}
440
477
441
478
// Recursively descend into the callee to confirm that it's trivial.
442
- return TrivialFunctionAnalysis::isTrivialImpl (CE->getConstructor (), Cache );
479
+ return IsFunctionTrivial (CE->getConstructor ());
443
480
}
444
481
445
482
bool VisitCXXNewExpr (const CXXNewExpr *NE) { return VisitChildren (NE); }
@@ -513,36 +550,13 @@ class TrivialFunctionAnalysisVisitor
513
550
514
551
private:
515
552
CacheTy &Cache;
553
+ CacheTy RecursiveFn;
516
554
};
517
555
518
556
bool TrivialFunctionAnalysis::isTrivialImpl (
519
557
const Decl *D, TrivialFunctionAnalysis::CacheTy &Cache) {
520
- // If the function isn't in the cache, conservatively assume that
521
- // it's not trivial until analysis completes. This makes every recursive
522
- // function non-trivial. This also guarantees that each function
523
- // will be scanned at most once.
524
- auto [It, IsNew] = Cache.insert (std::make_pair (D, false ));
525
- if (!IsNew)
526
- return It->second ;
527
-
528
558
TrivialFunctionAnalysisVisitor V (Cache);
529
-
530
- if (auto *CtorDecl = dyn_cast<CXXConstructorDecl>(D)) {
531
- for (auto *CtorInit : CtorDecl->inits ()) {
532
- if (!V.Visit (CtorInit->getInit ()))
533
- return false ;
534
- }
535
- }
536
-
537
- const Stmt *Body = D->getBody ();
538
- if (!Body)
539
- return false ;
540
-
541
- bool Result = V.Visit (Body);
542
- if (Result)
543
- Cache[D] = true ;
544
-
545
- return Result;
559
+ return V.IsFunctionTrivial (D);
546
560
}
547
561
548
562
bool TrivialFunctionAnalysis::isTrivialImpl (
0 commit comments