Skip to content

Commit 91da02b

Browse files
author
Robert Marsh
committed
C++: uniqueness fixes for HashCons
1 parent 3a5eb03 commit 91da02b

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

cpp/ql/src/semmle/code/cpp/valuenumbering/HashCons.qll

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ private cached newtype HCBase =
4747
or
4848
HC_StringLiteral(string val, Type t) {mk_StringLiteral(val,t,_)}
4949
or
50+
HC_Nullptr() {mk_Nullptr(_)}
51+
or
5052
HC_Variable(Variable x) {
5153
mk_Variable(x, _)
5254
}
@@ -167,30 +169,42 @@ class HC extends HCBase {
167169

168170
private predicate analyzableIntLiteral(Literal e) {
169171
strictcount (e.getValue().toInt()) = 1 and
170-
strictcount (e.getType().getUnspecifiedType()) = 1
172+
strictcount (e.getType().getUnspecifiedType()) = 1 and
173+
e.getType().getUnspecifiedType() instanceof IntegralType
171174
}
172175

173176
private predicate mk_IntLiteral(int val, Type t, Expr e) {
174177
analyzableIntLiteral(e) and
175178
val = e.getValue().toInt() and
176-
t = e.getType().getUnspecifiedType() and
177-
t instanceof IntegralType
179+
t = e.getType().getUnspecifiedType()
178180
}
181+
182+
179183
private predicate analyzableFloatLiteral(Literal e) {
180184
strictcount (e.getValue().toFloat()) = 1 and
181-
strictcount (e.getType().getUnspecifiedType()) = 1
185+
strictcount (e.getType().getUnspecifiedType()) = 1 and
186+
e.getType().getUnspecifiedType() instanceof FloatingPointType
182187
}
183188

184189
private predicate mk_FloatLiteral(float val, Type t, Expr e) {
185190
analyzableFloatLiteral(e) and
186191
val = e.getValue().toFloat() and
187-
t = e.getType().getUnspecifiedType() and
188-
t instanceof FloatingPointType
192+
t = e.getType().getUnspecifiedType()
193+
}
194+
195+
private predicate analyzableNullptr(NullValue e) {
196+
strictcount (e.getType().getUnspecifiedType()) = 1 and
197+
e.getType() instanceof NullPointerType
198+
}
199+
200+
private predicate mk_Nullptr(Expr e) {
201+
analyzableNullptr(e)
189202
}
190203

191204
private predicate analyzableStringLiteral(Literal e) {
192205
strictcount(e.getValue()) = 1 and
193-
strictcount(e.getType().getUnspecifiedType()) = 1
206+
strictcount(e.getType().getUnspecifiedType()) = 1 and
207+
e.getType().getUnspecifiedType().(ArrayType).getBaseType() instanceof CharType
194208
}
195209

196210
private predicate mk_StringLiteral(string val, Type t, Expr e) {
@@ -348,9 +362,9 @@ private predicate mk_Deref(
348362

349363
private predicate analyzableNonmemberFunctionCall(
350364
FunctionCall fc) {
351-
forall(int i | exists(fc.getArgument(i)) | strictcount(fc.getArgument(i)) = 1) and
365+
forall(int i | exists(fc.getArgument(i)) | strictcount(fc.getArgument(i).getFullyConverted()) = 1) and
352366
strictcount(fc.getTarget()) = 1 and
353-
not fc.getTarget().isMember()
367+
not exists(fc.getQualifier())
354368
}
355369

356370
private predicate mk_NonmemberFunctionCall(
@@ -373,9 +387,9 @@ private predicate mk_NonmemberFunctionCall(
373387

374388
private predicate analyzableMemberFunctionCall(
375389
FunctionCall fc) {
376-
forall(int i | exists(fc.getArgument(i)) | strictcount(fc.getArgument(i)) = 1) and
390+
forall(int i | exists(fc.getArgument(i)) | strictcount(fc.getArgument(i).getFullyConverted()) = 1) and
377391
strictcount(fc.getTarget()) = 1 and
378-
strictcount(fc.getQualifier()) = 1
392+
strictcount(fc.getQualifier().getFullyConverted()) = 1
379393
}
380394

381395
private predicate mk_MemberFunctionCall(
@@ -386,7 +400,7 @@ private predicate mk_MemberFunctionCall(
386400
) {
387401
fc.getTarget() = fcn and
388402
analyzableMemberFunctionCall(fc) and
389-
hashCons(fc.getQualifier()) = qual and
403+
hashCons(fc.getQualifier().getFullyConverted()) = qual and
390404
(
391405
exists(HC head, HC_Args tail |
392406
args = HC_ArgCons(fcn, head, fc.getNumberOfArguments() - 1, tail) and
@@ -490,6 +504,11 @@ cached HC hashCons(Expr e) {
490504
| mk_MemberFunctionCall(fcn, qual, args, e) and
491505
result = HC_MemberFunctionCall(fcn, qual, args)
492506
)
507+
or
508+
(
509+
mk_Nullptr(e) and
510+
result = HC_Nullptr()
511+
)
493512

494513
or
495514
(not analyzableExpr(e,_) and result = HC_Unanalyzable(e))
@@ -504,6 +523,7 @@ predicate analyzableExpr(Expr e, string kind) {
504523
(analyzableIntLiteral(e) and kind = "IntLiteral") or
505524
(analyzableFloatLiteral(e) and kind = "FloatLiteral") or
506525
(analyzableStringLiteral(e) and kind = "StringLiteral") or
526+
(analyzableNullptr(e) and kind = "Nullptr") or
507527
(analyzableDotFieldAccess(e) and kind = "DotFieldAccess") or
508528
(analyzablePointerFieldAccess(e) and kind = "PointerFieldAccess") or
509529
(analyzableImplicitThisFieldAccess(e) and kind = "ImplicitThisFieldAccess") or

cpp/ql/test/library-tests/valuenumbering/HashCons/HashCons.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@
6666
| test.cpp:150:3:150:3 | x | 150:c3-c3 150:c9-c9 151:c3-c3 151:c9-c9 152:c12-c12 |
6767
| test.cpp:150:3:150:5 | ... ++ | 150:c3-c5 150:c9-c11 151:c3-c5 151:c9-c11 152:c10-c12 |
6868
| test.cpp:150:3:150:11 | ... + ... | 150:c3-c11 151:c3-c11 |
69+
| test.cpp:156:14:156:20 | 0 | 156:c14-c20 156:c3-c9 157:c10-c16 |

cpp/ql/test/library-tests/valuenumbering/HashCons/test.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,8 @@ int test10(int x) {
151151
x++ + x++; // same as above
152152
return ++x; // ++x is not the same as x++
153153
}
154+
155+
void* test11() {
156+
nullptr == nullptr;
157+
return nullptr;
158+
}

0 commit comments

Comments
 (0)