Skip to content

Commit d23d3ed

Browse files
committed
Extract customizations into own module
1 parent 5ff2a10 commit d23d3ed

File tree

2 files changed

+69
-66
lines changed

2 files changed

+69
-66
lines changed

cpp/common/src/codingstandards/cpp/exceptions/ExceptionFlow.qll

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import cpp
66
import codingstandards.cpp.standardlibrary.Exceptions
77
import codingstandards.cpp.exceptions.ExceptionSpecifications
8+
import codingstandards.cpp.exceptions.ExceptionFlowCustomizations
89
import ThirdPartyExceptions
910

1011
/*
@@ -271,72 +272,6 @@ ExceptionType getAFunctionThrownType(Function f, ThrowingExpr throwingExpr) {
271272
)
272273
}
273274

274-
/** A `ThrowingExpr` which is the origin of a exceptions in the program. */
275-
abstract class OriginThrowingExpr extends ThrowingExpr { }
276-
277-
/** An expression which directly throws. */
278-
class DirectThrowExprThrowingExpr extends DirectThrowExpr, OriginThrowingExpr {
279-
override ExceptionType getAnExceptionType() { result = getExceptionType() }
280-
}
281-
282-
/** An `typeid` expression which may throw `std::bad_typeid`. */
283-
class TypeIdThrowingExpr extends TypeidOperator, OriginThrowingExpr {
284-
override ExceptionType getAnExceptionType() { result instanceof StdBadTypeId }
285-
}
286-
287-
/** An `new[]` expression which may throw `std::bad_array_new_length`. */
288-
class NewThrowingExpr extends NewArrayExpr, OriginThrowingExpr {
289-
NewThrowingExpr() {
290-
// If the extent is known to be below 0 at runtime
291-
getExtent().getValue().toInt() < 0
292-
or
293-
// initializer has more elements than the array size
294-
getExtent().getValue().toInt() < getInitializer().(ArrayAggregateLiteral).getArraySize()
295-
}
296-
297-
override ExceptionType getAnExceptionType() { result instanceof StdBadArrayNewLength }
298-
}
299-
300-
/** A `ReThrowExpr` which throws a previously caught exception. */
301-
class ReThrowExprThrowingExpr extends ReThrowExpr, ThrowingExpr {
302-
predicate rethrows(CatchBlock cb, ExceptionType et, ThrowingExpr te) {
303-
// Find the nearest CatchBlock
304-
cb = getNearestCatch(this.getEnclosingStmt()) and
305-
// Find an `ExceptionType` which is caught by this catch block, and `ThrowingExpr` which throws that exception type
306-
catches(cb, te, et)
307-
}
308-
309-
override ExceptionType getAnExceptionType() { rethrows(_, result, _) }
310-
311-
CatchBlock getCatchBlock() { rethrows(result, _, _) }
312-
}
313-
314-
/** An expression which calls a function which may throw an exception. */
315-
class FunctionCallThrowingExpr extends FunctionCall, ThrowingExpr {
316-
override ExceptionType getAnExceptionType() {
317-
exists(Function target |
318-
target = getTarget() and
319-
result = getAFunctionThrownType(target, _) and
320-
// [expect.spec] states that throwing an exception type that is prohibited
321-
// by the specification will result in the program terminating, unless
322-
// a custom `unexpected_handler` is registered that throws an exception type
323-
// which is compatible with the dynamic exception specification, or the
324-
// dynamic exception specification lists `std::bad_exception`, in which case
325-
// a `std::bad_exception` is thrown.
326-
// As dynamic exception specifications and the `unexpected_handler` are both
327-
// deprecated in C++14 and removed in C++17, we assume a default
328-
// `std::unexpected` handler that calls `std::terminate` and therefore
329-
// do not propagate such exceptions to the call sites for the function.
330-
not (
331-
hasDynamicExceptionSpecification(target) and
332-
not result = getAHandledExceptionType(target.getAThrownType())
333-
or
334-
isNoExceptTrue(target)
335-
)
336-
)
337-
}
338-
}
339-
340275
module ExceptionPathGraph {
341276
/**
342277
* A function for which we want path information.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import cpp
2+
private import codingstandards.cpp.exceptions.ExceptionFlow
3+
4+
/** A `ThrowingExpr` which is the origin of a exceptions in the program. */
5+
abstract class OriginThrowingExpr extends ThrowingExpr { }
6+
7+
/** An expression which directly throws. */
8+
class DirectThrowExprThrowingExpr extends DirectThrowExpr, OriginThrowingExpr {
9+
override ExceptionType getAnExceptionType() { result = getExceptionType() }
10+
}
11+
12+
/** A `ReThrowExpr` which throws a previously caught exception. */
13+
class ReThrowExprThrowingExpr extends ReThrowExpr, ThrowingExpr {
14+
predicate rethrows(CatchBlock cb, ExceptionType et, ThrowingExpr te) {
15+
// Find the nearest CatchBlock
16+
cb = getNearestCatch(this.getEnclosingStmt()) and
17+
// Find an `ExceptionType` which is caught by this catch block, and `ThrowingExpr` which throws that exception type
18+
catches(cb, te, et)
19+
}
20+
21+
override ExceptionType getAnExceptionType() { rethrows(_, result, _) }
22+
23+
CatchBlock getCatchBlock() { rethrows(result, _, _) }
24+
}
25+
26+
/** An expression which calls a function which may throw an exception. */
27+
class FunctionCallThrowingExpr extends FunctionCall, ThrowingExpr {
28+
override ExceptionType getAnExceptionType() {
29+
exists(Function target |
30+
target = getTarget() and
31+
result = getAFunctionThrownType(target, _) and
32+
// [expect.spec] states that throwing an exception type that is prohibited
33+
// by the specification will result in the program terminating, unless
34+
// a custom `unexpected_handler` is registered that throws an exception type
35+
// which is compatible with the dynamic exception specification, or the
36+
// dynamic exception specification lists `std::bad_exception`, in which case
37+
// a `std::bad_exception` is thrown.
38+
// As dynamic exception specifications and the `unexpected_handler` are both
39+
// deprecated in C++14 and removed in C++17, we assume a default
40+
// `std::unexpected` handler that calls `std::terminate` and therefore
41+
// do not propagate such exceptions to the call sites for the function.
42+
not (
43+
hasDynamicExceptionSpecification(target) and
44+
not result = getAHandledExceptionType(target.getAThrownType())
45+
or
46+
isNoExceptTrue(target)
47+
)
48+
)
49+
}
50+
}
51+
52+
/** An `typeid` expression which may throw `std::bad_typeid`. */
53+
private class TypeIdThrowingExpr extends TypeidOperator, OriginThrowingExpr {
54+
override ExceptionType getAnExceptionType() { result instanceof StdBadTypeId }
55+
}
56+
57+
/** An `new[]` expression which may throw `std::bad_array_new_length`. */
58+
private class NewThrowingExpr extends NewArrayExpr, OriginThrowingExpr {
59+
NewThrowingExpr() {
60+
// If the extent is known to be below 0 at runtime
61+
getExtent().getValue().toInt() < 0
62+
or
63+
// initializer has more elements than the array size
64+
getExtent().getValue().toInt() < getInitializer().(ArrayAggregateLiteral).getArraySize()
65+
}
66+
67+
override ExceptionType getAnExceptionType() { result instanceof StdBadArrayNewLength }
68+
}

0 commit comments

Comments
 (0)