| // Copyright 2024 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| import cpp | |
| module CommonPatterns { | |
| /** | |
| * Predicate to check if a function call is not followed by a return statement | |
| * within the same or immediately after in any block. | |
| */ | |
| pragma[inline] | |
| predicate isCallNotFollowedByReturn(FunctionCall call) { | |
| exists(Function f | | |
| call.getEnclosingFunction() = f and | |
| // Ignore any calls with a returnStatement in the same enclosing block. | |
| not exists(ReturnStmt returnStmt | | |
| call.getEnclosingBlock() = returnStmt.getEnclosingBlock() | |
| ) and | |
| // Ignore any calls with a returnStatement immediately after in the block. | |
| exists(Stmt stmtAfterCall | | |
| stmtAfterCall.getEnclosingFunction() = f and | |
| stmtAfterCall.getLocation().getStartLine() > call.getLocation().getStartLine() and | |
| not stmtAfterCall instanceof ReturnStmt and | |
| not exists(ReturnStmt returnBetween | | |
| returnBetween.getEnclosingFunction() = f and | |
| returnBetween.getLocation().getStartLine() > call.getLocation().getStartLine() and | |
| returnBetween.getLocation().getStartLine() < stmtAfterCall.getLocation().getStartLine() | |
| ) | |
| ) | |
| ) | |
| } | |
| } |