@@ -9,11 +9,13 @@ private import ControlFlow::BasicBlocks
99
1010/** An assertion method. */
1111abstract class AssertMethod extends Method {
12- /** Gets the index of the parameter being asserted. */
13- abstract int getAssertionIndex ( ) ;
12+ /** Gets the index of a parameter being asserted. */
13+ abstract int getAnAssertionIndex ( ) ;
1414
15- /** Gets the parameter being asserted. */
16- final Parameter getAssertedParameter ( ) { result = this .getParameter ( this .getAssertionIndex ( ) ) }
15+ /** Gets a parameter being asserted. */
16+ final Parameter getAnAssertedParameter ( ) {
17+ result = this .getParameter ( this .getAnAssertionIndex ( ) )
18+ }
1719
1820 /** Gets the exception being thrown if the assertion fails, if any. */
1921 abstract Class getExceptionClass ( ) ;
@@ -40,8 +42,8 @@ class Assertion extends MethodCall {
4042 /** Gets the assertion method targeted by this assertion. */
4143 AssertMethod getAssertMethod ( ) { result = target }
4244
43- /** Gets the expression that this assertion pertains to. */
44- Expr getExpr ( ) { result = this .getArgumentForParameter ( target .getAssertedParameter ( ) ) }
45+ /** Gets an expression that this assertion pertains to. */
46+ Expr getAnExpr ( ) { result = this .getArgumentForParameter ( target .getAnAssertedParameter ( ) ) }
4547
4648 /**
4749 * Holds if basic block `succ` is immediately dominated by this assertion.
@@ -144,7 +146,7 @@ class FailingAssertion extends Assertion {
144146 FailingAssertion ( ) {
145147 exists ( AssertMethod am , Expr e |
146148 am = this .getAssertMethod ( ) and
147- e = this .getExpr ( )
149+ e = this .getAnExpr ( )
148150 |
149151 am instanceof AssertTrueMethod and
150152 e .getValue ( ) = "false"
@@ -163,7 +165,7 @@ class SystemDiagnosticsDebugAssertTrueMethod extends AssertTrueMethod {
163165 this = any ( SystemDiagnosticsDebugClass c ) .getAssertMethod ( )
164166 }
165167
166- override int getAssertionIndex ( ) { result = 0 }
168+ override int getAnAssertionIndex ( ) { result = 0 }
167169
168170 override Class getExceptionClass ( ) {
169171 // A failing assertion generates a message box, see
@@ -186,7 +188,7 @@ class SystemDiagnosticsContractAssertTrueMethod extends AssertTrueMethod {
186188 )
187189 }
188190
189- override int getAssertionIndex ( ) { result = 0 }
191+ override int getAnAssertionIndex ( ) { result = 0 }
190192
191193 override Class getExceptionClass ( ) {
192194 // A failing assertion generates a message box, see
@@ -195,11 +197,60 @@ class SystemDiagnosticsContractAssertTrueMethod extends AssertTrueMethod {
195197 }
196198}
197199
200+ private predicate isDoesNotReturnIfAttributeParameter ( Parameter p , boolean value ) {
201+ exists ( Attribute a | a = p .getAnAttribute ( ) |
202+ a .getType ( ) = any ( SystemDiagnosticsCodeAnalysisDoesNotReturnIfAttributeClass c ) and
203+ a .getConstructorArgument ( 0 ) .( BoolLiteral ) .getBoolValue ( ) = value
204+ )
205+ }
206+
207+ /**
208+ * A method with a parameter that is annotated with
209+ * `System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute(false)`.
210+ */
211+ class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertTrueMethod extends AssertTrueMethod {
212+ SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertTrueMethod ( ) {
213+ this = any ( Method m | isDoesNotReturnIfAttributeParameter ( m .getAParameter ( ) , false ) )
214+ }
215+
216+ override int getAnAssertionIndex ( ) {
217+ exists ( Parameter p |
218+ this .getParameter ( result ) = p and isDoesNotReturnIfAttributeParameter ( p , false )
219+ )
220+ }
221+
222+ override Class getExceptionClass ( ) {
223+ // The user defines the thrown exception.
224+ any ( )
225+ }
226+ }
227+
228+ /**
229+ * A method with a parameter that is annotated with
230+ * `System.Diagnostics.CodeAnalysis.DoesNotReturnIfAttribute(true)`.
231+ */
232+ class SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertFalseMethod extends AssertFalseMethod {
233+ SystemDiagnosticsCodeAnalysisDoesNotReturnIfAnnotatedAssertFalseMethod ( ) {
234+ this = any ( Method m | isDoesNotReturnIfAttributeParameter ( m .getAParameter ( ) , true ) )
235+ }
236+
237+ override int getAnAssertionIndex ( ) {
238+ exists ( Parameter p |
239+ this .getParameter ( result ) = p and isDoesNotReturnIfAttributeParameter ( p , true )
240+ )
241+ }
242+
243+ override Class getExceptionClass ( ) {
244+ // The user defines the thrown exception.
245+ any ( )
246+ }
247+ }
248+
198249/** A Visual Studio assertion method. */
199250class VSTestAssertTrueMethod extends AssertTrueMethod {
200251 VSTestAssertTrueMethod ( ) { this = any ( VSTestAssertClass c ) .getIsTrueMethod ( ) }
201252
202- override int getAssertionIndex ( ) { result = 0 }
253+ override int getAnAssertionIndex ( ) { result = 0 }
203254
204255 override AssertFailedExceptionClass getExceptionClass ( ) { any ( ) }
205256}
@@ -208,7 +259,7 @@ class VSTestAssertTrueMethod extends AssertTrueMethod {
208259class VSTestAssertFalseMethod extends AssertFalseMethod {
209260 VSTestAssertFalseMethod ( ) { this = any ( VSTestAssertClass c ) .getIsFalseMethod ( ) }
210261
211- override int getAssertionIndex ( ) { result = 0 }
262+ override int getAnAssertionIndex ( ) { result = 0 }
212263
213264 override AssertFailedExceptionClass getExceptionClass ( ) { any ( ) }
214265}
@@ -217,7 +268,7 @@ class VSTestAssertFalseMethod extends AssertFalseMethod {
217268class VSTestAssertNullMethod extends AssertNullMethod {
218269 VSTestAssertNullMethod ( ) { this = any ( VSTestAssertClass c ) .getIsNullMethod ( ) }
219270
220- override int getAssertionIndex ( ) { result = 0 }
271+ override int getAnAssertionIndex ( ) { result = 0 }
221272
222273 override AssertFailedExceptionClass getExceptionClass ( ) { any ( ) }
223274}
@@ -226,14 +277,14 @@ class VSTestAssertNullMethod extends AssertNullMethod {
226277class VSTestAssertNonNullMethod extends AssertNonNullMethod {
227278 VSTestAssertNonNullMethod ( ) { this = any ( VSTestAssertClass c ) .getIsNotNullMethod ( ) }
228279
229- override int getAssertionIndex ( ) { result = 0 }
280+ override int getAnAssertionIndex ( ) { result = 0 }
230281
231282 override AssertFailedExceptionClass getExceptionClass ( ) { any ( ) }
232283}
233284
234285/** An NUnit assertion method. */
235286abstract class NUnitAssertMethod extends AssertMethod {
236- override int getAssertionIndex ( ) { result = 0 }
287+ override int getAnAssertionIndex ( ) { result = 0 }
237288
238289 override AssertionExceptionClass getExceptionClass ( ) { any ( ) }
239290}
@@ -292,11 +343,11 @@ class ForwarderAssertMethod extends AssertMethod {
292343 strictcount ( AssignableDefinition def | def .getTarget ( ) = p ) = 1 and
293344 forex ( ControlFlowElement body | body = this .getBody ( ) |
294345 bodyAsserts ( this , body , a ) and
295- a .getExpr ( ) = p .getAnAccess ( )
346+ a .getAnExpr ( ) = p .getAnAccess ( )
296347 )
297348 }
298349
299- override int getAssertionIndex ( ) { result = p .getPosition ( ) }
350+ override int getAnAssertionIndex ( ) { result = p .getPosition ( ) }
300351
301352 override Class getExceptionClass ( ) {
302353 result = this .getUnderlyingAssertMethod ( ) .getExceptionClass ( )
@@ -345,4 +396,4 @@ class ForwarderAssertNonNullMethod extends ForwarderAssertMethod, AssertNonNullM
345396}
346397
347398/** Holds if expression `e` appears in an assertion. */
348- predicate isExprInAssertion ( Expr e ) { e = any ( Assertion a ) .getExpr ( ) .getAChildExpr * ( ) }
399+ predicate isExprInAssertion ( Expr e ) { e = any ( Assertion a ) .getAnExpr ( ) .getAChildExpr * ( ) }
0 commit comments