Skip to content

Commit e6314c5

Browse files
author
Robert Marsh
committed
C++: add support for enums in HashCons
1 parent 91da02b commit e6314c5

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ import cpp
4343
private cached newtype HCBase =
4444
HC_IntLiteral(int val, Type t) { mk_IntLiteral(val,t,_) }
4545
or
46+
HC_EnumConstantAccess(EnumConstant val, Type t) { mk_EnumConstantAccess(val,t,_) }
47+
or
4648
HC_FloatLiteral(float val, Type t) { mk_FloatLiteral(val,t,_) }
4749
or
4850
HC_StringLiteral(string val, Type t) {mk_StringLiteral(val,t,_)}
@@ -179,6 +181,17 @@ private predicate mk_IntLiteral(int val, Type t, Expr e) {
179181
t = e.getType().getUnspecifiedType()
180182
}
181183

184+
private predicate analyzableEnumConstantAccess(EnumConstantAccess e) {
185+
strictcount (e.getValue().toInt()) = 1 and
186+
strictcount (e.getType().getUnspecifiedType()) = 1 and
187+
e.getType().getUnspecifiedType() instanceof Enum
188+
}
189+
190+
private predicate mk_EnumConstantAccess(EnumConstant val, Type t, Expr e) {
191+
analyzableEnumConstantAccess(e) and
192+
val = e.(EnumConstantAccess).getTarget() and
193+
t = e.getType().getUnspecifiedType()
194+
}
182195

183196
private predicate analyzableFloatLiteral(Literal e) {
184197
strictcount (e.getValue().toFloat()) = 1 and
@@ -446,6 +459,10 @@ cached HC hashCons(Expr e) {
446459
| mk_IntLiteral(val, t, e) and
447460
result = HC_IntLiteral(val, t))
448461
or
462+
exists (EnumConstant val, Type t
463+
| mk_EnumConstantAccess(val, t, e) and
464+
result = HC_EnumConstantAccess(val, t))
465+
or
449466
exists (float val, Type t
450467
| mk_FloatLiteral(val, t, e) and
451468
result = HC_FloatLiteral(val, t))
@@ -521,6 +538,7 @@ cached HC hashCons(Expr e) {
521538
*/
522539
predicate analyzableExpr(Expr e, string kind) {
523540
(analyzableIntLiteral(e) and kind = "IntLiteral") or
541+
(analyzableEnumConstantAccess(e) and kind = "EnumConstantAccess") or
524542
(analyzableFloatLiteral(e) and kind = "FloatLiteral") or
525543
(analyzableStringLiteral(e) and kind = "StringLiteral") or
526544
(analyzableNullptr(e) and kind = "Nullptr") or

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,5 @@
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 |
6969
| test.cpp:156:14:156:20 | 0 | 156:c14-c20 156:c3-c9 157:c10-c16 |
70+
| test.cpp:171:3:171:6 | (int)... | 171:c3-c6 172:c3-c6 |
71+
| test.cpp:171:3:171:6 | e1x1 | 171:c3-c6 172:c3-c6 |

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,19 @@ void* test11() {
156156
nullptr == nullptr;
157157
return nullptr;
158158
}
159+
160+
enum t1 {
161+
e1x1 = 1,
162+
e1x2 = 2
163+
};
164+
165+
enum t2 {
166+
e2x1 = 1,
167+
e2x2 = 2
168+
};
169+
170+
int test12() {
171+
e1x1 == e2x1;
172+
e1x1 == e2x2;
173+
return e1x2;
174+
}

0 commit comments

Comments
 (0)