1+ /**
2+ * Provides classes for identifying and reasoning about Microsoft source code
3+ * annotation language (SAL) macros.
4+ */
5+
16import cpp
27
8+ /**
9+ * A SAL macro defined in `sal.h` or a similar header file.
10+ */
311class SALMacro extends Macro {
412 SALMacro ( ) {
513 exists ( string filename | filename = this .getFile ( ) .getBaseName ( ) |
@@ -20,27 +28,34 @@ class SALMacro extends Macro {
2028}
2129
2230pragma [ noinline]
23- predicate isTopLevelMacroAccess ( MacroAccess ma ) { not exists ( ma .getParentInvocation ( ) ) }
31+ private predicate isTopLevelMacroAccess ( MacroAccess ma ) { not exists ( ma .getParentInvocation ( ) ) }
2432
33+ /**
34+ * An invocation of a SAL macro (excluding invocations inside other macros).
35+ */
2536class SALAnnotation extends MacroInvocation {
2637 SALAnnotation ( ) {
2738 this .getMacro ( ) instanceof SALMacro and
2839 isTopLevelMacroAccess ( this )
2940 }
3041
31- /** Returns the `Declaration` annotated by `this`. */
42+ /** Gets the `Declaration` annotated by `this`. */
3243 Declaration getDeclaration ( ) {
3344 annotatesAt ( this , result .getADeclarationEntry ( ) , _, _) and
3445 not result instanceof Type // exclude typedefs
3546 }
3647
37- /** Returns the `DeclarationEntry` annotated by `this`. */
48+ /** Gets the `DeclarationEntry` annotated by `this`. */
3849 DeclarationEntry getDeclarationEntry ( ) {
3950 annotatesAt ( this , result , _, _) and
4051 not result instanceof TypeDeclarationEntry // exclude typedefs
4152 }
4253}
4354
55+ /**
56+ * A SAL macro indicating that the return value of a function should always be
57+ * checked.
58+ */
4459class SALCheckReturn extends SALAnnotation {
4560 SALCheckReturn ( ) {
4661 exists ( SALMacro m | m = this .getMacro ( ) |
@@ -50,6 +65,10 @@ class SALCheckReturn extends SALAnnotation {
5065 }
5166}
5267
68+ /**
69+ * A SAL macro indicating that a pointer variable or return value should not be
70+ * `NULL`.
71+ */
5372class SALNotNull extends SALAnnotation {
5473 SALNotNull ( ) {
5574 exists ( SALMacro m | m = this .getMacro ( ) |
@@ -69,6 +88,9 @@ class SALNotNull extends SALAnnotation {
6988 }
7089}
7190
91+ /**
92+ * A SAL macro indicating that a value may be `NULL`.
93+ */
7294class SALMaybeNull extends SALAnnotation {
7395 SALMaybeNull ( ) {
7496 exists ( SALMacro m | m = this .getMacro ( ) |
@@ -79,13 +101,29 @@ class SALMaybeNull extends SALAnnotation {
79101 }
80102}
81103
104+ /**
105+ * A parameter annotated by one or more SAL annotations.
106+ */
107+ class SALParameter extends Parameter {
108+ /** One of this parameter's annotations. */
109+ SALAnnotation a ;
110+
111+ SALParameter ( ) { annotatesAt ( a , this .getADeclarationEntry ( ) , _, _) }
112+
113+ predicate isIn ( ) { a .getMacroName ( ) .toLowerCase ( ) .matches ( "%\\_in%" ) }
114+
115+ predicate isOut ( ) { a .getMacroName ( ) .toLowerCase ( ) .matches ( "%\\_out%" ) }
116+
117+ predicate isInOut ( ) { a .getMacroName ( ) .toLowerCase ( ) .matches ( "%\\_inout%" ) }
118+ }
119+
82120///////////////////////////////////////////////////////////////////////////////
83121// Implementation details
84122/**
85123 * Holds if `a` annotates the declaration entry `d` and
86124 * its start position is the `idx`th position in `file` that holds a SAL element.
87125 */
88- predicate annotatesAt ( SALAnnotation a , DeclarationEntry d , File file , int idx ) {
126+ private predicate annotatesAt ( SALAnnotation a , DeclarationEntry d , File file , int idx ) {
89127 annotatesAtPosition ( a .( SALElement ) .getStartPosition ( ) , d , file , idx )
90128}
91129
@@ -109,22 +147,6 @@ private predicate annotatesAtPosition(SALPosition pos, DeclarationEntry d, File
109147 )
110148}
111149
112- /**
113- * A parameter annotated by one or more SAL annotations.
114- */
115- class SALParameter extends Parameter {
116- /** One of this parameter's annotations. */
117- SALAnnotation a ;
118-
119- SALParameter ( ) { annotatesAt ( a , this .getADeclarationEntry ( ) , _, _) }
120-
121- predicate isIn ( ) { a .getMacroName ( ) .toLowerCase ( ) .matches ( "%\\_in%" ) }
122-
123- predicate isOut ( ) { a .getMacroName ( ) .toLowerCase ( ) .matches ( "%\\_out%" ) }
124-
125- predicate isInOut ( ) { a .getMacroName ( ) .toLowerCase ( ) .matches ( "%\\_inout%" ) }
126- }
127-
128150/**
129151 * A SAL element, that is, a SAL annotation or a declaration entry
130152 * that may have SAL annotations.
0 commit comments