@@ -795,12 +795,63 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
795
795
*/
796
796
predicate allowParameterReturnInSelf ( ParameterNode p ) { none ( ) }
797
797
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
+
798
811
/** 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
+ }
800
839
801
840
/** Gets an approximated value for content `c`. */
802
841
pragma [ 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
+ }
804
855
805
856
private class MyConsistencyConfiguration extends Consistency:: ConsistencyConfiguration {
806
857
override predicate argHasPostUpdateExclude ( ArgumentNode n ) {
0 commit comments