@@ -3,6 +3,7 @@ private import semmle.code.cpp.ir.implementation.Opcode
33private import semmle.code.cpp.ir.implementation.internal.OperandTag
44private import semmle.code.cpp.ir.internal.CppType
55private import semmle.code.cpp.models.interfaces.SideEffect
6+ private import semmle.code.cpp.models.interfaces.Throwing
67private import InstructionTag
78private import SideEffects
89private import TranslatedElement
@@ -76,7 +77,14 @@ abstract class TranslatedCall extends TranslatedExpr {
7677 any ( UnreachedInstruction instr |
7778 this .getEnclosingFunction ( ) .getFunction ( ) = instr .getEnclosingFunction ( )
7879 )
79- else result = this .getParent ( ) .getChildSuccessor ( this , kind )
80+ else (
81+ not this .mustThrowException ( ) and
82+ result = this .getParent ( ) .getChildSuccessor ( this , kind )
83+ or
84+ this .mayThrowException ( ) and
85+ kind instanceof ExceptionEdge and
86+ result = this .getParent ( ) .getExceptionSuccessorInstruction ( any ( GotoEdge edge ) )
87+ )
8088 }
8189
8290 override Instruction getInstructionSuccessor ( InstructionTag tag , EdgeKind kind ) {
@@ -102,6 +110,16 @@ abstract class TranslatedCall extends TranslatedExpr {
102110
103111 final override Instruction getResult ( ) { result = this .getInstruction ( CallTag ( ) ) }
104112
113+ /**
114+ * Holds if the evaluation of this call may throw an exception.
115+ */
116+ abstract predicate mayThrowException ( ) ;
117+
118+ /**
119+ * Holds if the evaluation of this call always throws an exception.
120+ */
121+ abstract predicate mustThrowException ( ) ;
122+
105123 /**
106124 * Gets the result type of the call.
107125 */
@@ -295,6 +313,15 @@ class TranslatedExprCall extends TranslatedCallExpr {
295313 override TranslatedExpr getCallTarget ( ) {
296314 result = getTranslatedExpr ( expr .getExpr ( ) .getFullyConverted ( ) )
297315 }
316+
317+ final override predicate mayThrowException ( ) {
318+ // We assume that a call to a function pointer will not throw an exception.
319+ // This is not sound in general, but this will greatly reduce the number of
320+ // exceptional edges.
321+ none ( )
322+ }
323+
324+ final override predicate mustThrowException ( ) { none ( ) }
298325}
299326
300327/**
@@ -316,6 +343,14 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
316343 exists ( this .getQualifier ( ) ) and
317344 not exists ( MemberFunction func | expr .getTarget ( ) = func and func .isStatic ( ) )
318345 }
346+
347+ final override predicate mayThrowException ( ) {
348+ expr .getTarget ( ) .( ThrowingFunction ) .mayThrowException ( _)
349+ }
350+
351+ final override predicate mustThrowException ( ) {
352+ expr .getTarget ( ) .( ThrowingFunction ) .mayThrowException ( true )
353+ }
319354}
320355
321356/**
0 commit comments