@@ -795,12 +795,63 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
795795 */
796796predicate allowParameterReturnInSelf ( ParameterNode p ) { none ( ) }
797797
798+ private predicate fieldHasApproxName ( Field f , string s ) {
799+ s = f .getName ( ) .charAt ( 0 ) and
800+ // Reads and writes of union fields are tracked using `UnionContent`.
801+ not f .getDeclaringType ( ) instanceof Cpp:: Union
802+ }
803+
804+ private predicate unionHasApproxName ( Cpp:: Union u , string s ) { s = u .getName ( ) .charAt ( 0 ) }
805+
806+ cached
807+ private newtype TContentApprox =
808+ TFieldApproxContent ( string s ) { fieldHasApproxName ( _, s ) } or
809+ TUnionApproxContent ( string s ) { unionHasApproxName ( _, s ) }
810+
798811/** An approximated `Content`. */
799- class ContentApprox = Unit ;
812+ class ContentApprox extends TContentApprox {
813+ string toString ( ) { none ( ) } // overriden in subclasses
814+ }
815+
816+ private class FieldApproxContent extends ContentApprox , TFieldApproxContent {
817+ string s ;
818+
819+ FieldApproxContent ( ) { this = TFieldApproxContent ( s ) }
820+
821+ Field getAField ( ) { fieldHasApproxName ( result , s ) }
822+
823+ string getPrefix ( ) { result = s }
824+
825+ final override string toString ( ) { result = s }
826+ }
827+
828+ private class UnionApproxContent extends ContentApprox , TUnionApproxContent {
829+ string s ;
830+
831+ UnionApproxContent ( ) { this = TUnionApproxContent ( s ) }
832+
833+ Cpp:: Union getAUnion ( ) { unionHasApproxName ( result , s ) }
834+
835+ string getPrefix ( ) { result = s }
836+
837+ final override string toString ( ) { result = s }
838+ }
800839
801840/** Gets an approximated value for content `c`. */
802841pragma [ inline]
803- ContentApprox getContentApprox ( Content c ) { any ( ) }
842+ ContentApprox getContentApprox ( Content c ) {
843+ exists ( string prefix , Field f |
844+ prefix = result .( FieldApproxContent ) .getPrefix ( ) and
845+ f = c .( FieldContent ) .getField ( ) and
846+ fieldHasApproxName ( f , prefix )
847+ )
848+ or
849+ exists ( string prefix , Cpp:: Union u |
850+ prefix = result .( UnionApproxContent ) .getPrefix ( ) and
851+ u = c .( UnionContent ) .getUnion ( ) and
852+ unionHasApproxName ( u , prefix )
853+ )
854+ }
804855
805856private class MyConsistencyConfiguration extends Consistency:: ConsistencyConfiguration {
806857 override predicate argHasPostUpdateExclude ( ArgumentNode n ) {
0 commit comments