-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathAV Rule 114.ql
More file actions
71 lines (66 loc) · 2.35 KB
/
AV Rule 114.ql
File metadata and controls
71 lines (66 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* @name Missing return statement
* @description All functions that are not void should return a value on every exit path.
* @kind problem
* @problem.severity error
* @precision high
* @id cpp/missing-return
* @tags reliability
* readability
* language-features
* external/jsf
*/
import cpp
/*
* This is slightly subtle: The extractor adds a dummy 'return;' statement for control paths
* that fall off the end of a function. So we can simply look for non-void functions containing
* a non-value carrying return. If the predecessor is a return statement it means that
* the return did not return a value. (If that return was not added by the extractor but by the
* programmer, we can flag it anyway, since this is arguably a bug.)
*/
predicate functionsMissingReturnStmt(Function f, ControlFlowNode blame) {
f.fromSource() and
exists(Type returnType |
returnType = f.getUnspecifiedType() and
not returnType instanceof VoidType and
not returnType instanceof TypeTemplateParameter
) and
exists(ReturnStmt s |
f.getAPredecessor() = s and
(
blame = s.getAPredecessor() and
count(blame.getASuccessor()) = 1
or
blame = s and
exists(ControlFlowNode pred | pred = s.getAPredecessor() | count(pred.getASuccessor()) != 1)
)
)
}
/**
* If a function has a value-carrying return statement, but the extractor hit a snag
* whilst parsing the value, then the control flow graph will not include the value.
* As such, to avoid embarrassing false positives, we exclude any function which
* wasn't perfectly extracted.
*/
predicate functionImperfectlyExtracted(Function f) {
exists(CompilerError e | f.getBlock().getLocation().subsumes(e.getLocation()))
or
f.hasErrors()
or
count(f.getType()) > 1
or
// an `AsmStmt` isn't strictly 'imperfectly extracted', but it's beyond the scope
// of this analysis.
exists(AsmStmt asm | asm.getEnclosingFunction() = f)
}
from Stmt stmt, string msg, Function f, ControlFlowNode blame
where
functionsMissingReturnStmt(f, blame) and
reachable(blame) and
not functionImperfectlyExtracted(f) and
not f.isFromUninstantiatedTemplate(_) and
(blame = stmt or blame.(Expr).getEnclosingStmt() = stmt) and
msg =
"Function " + f.getName() + " should return a value of type " + f.getType().getName() +
" but does not return a value here"
select stmt, msg