9595
9696import cpp
9797private import new.DataFlow
98+ private import semmle.code.cpp.controlflow.IRGuards
9899private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private
99100private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
100101private import internal.FlowSummaryImpl
@@ -367,6 +368,8 @@ private predicate elementSpec(
367368) {
368369 sourceModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) or
369370 sinkModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) or
371+ barrierModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) or
372+ barrierGuardModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _, _) or
370373 summaryModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _, _)
371374}
372375
@@ -1028,6 +1031,52 @@ private module Cached {
10281031 isSinkNode ( n , kind , model ) and n .asNode ( ) = node
10291032 )
10301033 }
1034+
1035+ private newtype TKindModelPair =
1036+ TMkPair ( string kind , string model ) { isBarrierGuardNode ( _, _, kind , model ) }
1037+
1038+ private GuardValue convertAcceptingValue ( Public:: AcceptingValue av ) {
1039+ av .isTrue ( ) and result .asBooleanValue ( ) = true
1040+ or
1041+ av .isFalse ( ) and result .asBooleanValue ( ) = false
1042+ or
1043+ av .isNoException ( ) and result .getDualValue ( ) .isThrowsException ( )
1044+ or
1045+ av .isZero ( ) and result .asIntValue ( ) = 0
1046+ or
1047+ av .isNotZero ( ) and result .getDualValue ( ) .asIntValue ( ) = 0
1048+ or
1049+ av .isNull ( ) and result .isNullValue ( )
1050+ or
1051+ av .isNotNull ( ) and result .isNonNullValue ( )
1052+ }
1053+
1054+ private predicate barrierGuardChecks ( IRGuardCondition g , Expr e , GuardValue gv , TKindModelPair kmp ) {
1055+ exists (
1056+ SourceSinkInterpretationInput:: InterpretNode n , Public:: AcceptingValue acceptingvalue ,
1057+ string kind , string model
1058+ |
1059+ isBarrierGuardNode ( n , acceptingvalue , kind , model ) and
1060+ n .asNode ( ) .asExpr ( ) = e and
1061+ kmp = TMkPair ( kind , model ) and
1062+ gv = convertAcceptingValue ( acceptingvalue ) and
1063+ n .asNode ( ) .( ArgumentNode ) .getCallInstruction ( ) = g
1064+ )
1065+ }
1066+
1067+ /**
1068+ * Holds if `node` is specified as a barrier with the given kind in a MaD flow
1069+ * model.
1070+ */
1071+ cached
1072+ predicate barrierNode ( DataFlow:: Node node , string kind , string model ) {
1073+ exists ( SourceSinkInterpretationInput:: InterpretNode n |
1074+ isBarrierNode ( n , kind , model ) and n .asNode ( ) = node
1075+ )
1076+ or
1077+ DataFlow:: ParameterizedBarrierGuard< TKindModelPair , barrierGuardChecks / 4 > :: getABarrierNode ( TMkPair ( kind ,
1078+ model ) ) = node
1079+ }
10311080}
10321081
10331082import Cached
@@ -1044,6 +1093,12 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind,
10441093 */
10451094predicate sinkNode ( DataFlow:: Node node , string kind ) { sinkNode ( node , kind , _) }
10461095
1096+ /**
1097+ * Holds if `node` is specified as a barrier with the given kind in a MaD flow
1098+ * model.
1099+ */
1100+ predicate barrierNode ( DataFlow:: Node node , string kind ) { barrierNode ( node , kind , _) }
1101+
10471102private predicate interpretSummary (
10481103 Function f , string input , string output , string kind , string provenance , string model
10491104) {
0 commit comments