@@ -89,6 +89,15 @@ extensible predicate summaryModel(
8989 QlBuiltins:: ExtensionId madId
9090) ;
9191
92+ /**
93+ * Holds if a neutral model exists for the function with canonical path `path`. The only
94+ * effect of a neutral model is to prevent generated and inherited models of the corresponding
95+ * `kind` (`source`, `sink` or `summary`) from being applied to that function.
96+ */
97+ extensible predicate neutralModel (
98+ string path , string kind , string provenance , QlBuiltins:: ExtensionId madId
99+ ) ;
100+
92101/**
93102 * Holds if the given extension tuple `madId` should pretty-print as `model`.
94103 *
@@ -109,6 +118,11 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
109118 summaryModel ( path , input , output , kind , _, madId ) and
110119 model = "Summary: " + path + "; " + input + "; " + output + "; " + kind
111120 )
121+ or
122+ exists ( string path , string kind |
123+ neutralModel ( path , kind , _, madId ) and
124+ model = "Neutral: " + path + "; " + kind
125+ )
112126}
113127
114128private class SummarizedCallableFromModel extends SummarizedCallable:: Range {
@@ -124,7 +138,9 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
124138 summaryModel ( path , input_ , output_ , kind , p , madId ) and
125139 f .getCanonicalPath ( ) = path
126140 |
127- this = f and isExact_ = true and p_ = p
141+ this = f and
142+ isExact_ = true and
143+ p_ = p
128144 or
129145 this .implements ( f ) and
130146 isExact_ = false and
@@ -158,6 +174,12 @@ private class FlowSourceFromModel extends FlowSource::Range {
158174 exists ( QlBuiltins:: ExtensionId madId |
159175 sourceModel ( path , output , kind , provenance , madId ) and
160176 model = "MaD:" + madId .toString ( )
177+ ) and
178+ // Only apply generated models when no neutral model exists
179+ // (the shared code only applies neutral models to summaries at present)
180+ not (
181+ provenance .isGenerated ( ) and
182+ neutralModel ( path , "source" , _, _)
161183 )
162184 }
163185}
@@ -174,6 +196,12 @@ private class FlowSinkFromModel extends FlowSink::Range {
174196 exists ( QlBuiltins:: ExtensionId madId |
175197 sinkModel ( path , input , kind , provenance , madId ) and
176198 model = "MaD:" + madId .toString ( )
199+ ) and
200+ // Only apply generated models when no neutral model exists
201+ // (the shared code only applies neutral models to summaries at present)
202+ not (
203+ provenance .isGenerated ( ) and
204+ neutralModel ( path , "sink" , _, _)
177205 )
178206 }
179207}
0 commit comments