Skip to content

Commit 4d01a93

Browse files
committed
C++: Use 'getUnderlyingType' instead of 'getUnspecifiedType'.
1 parent 78ce857 commit 4d01a93

File tree

3 files changed

+33
-103
lines changed

3 files changed

+33
-103
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
709709
override DataFlowType getType() {
710710
exists(int indirectionIndex |
711711
indirectionIndex = globalUse.getIndirectionIndex() and
712-
result = getTypeImpl(globalUse.getUnspecifiedType(), indirectionIndex - 1)
712+
result = getTypeImpl(globalUse.getUnderlyingType(), indirectionIndex - 1)
713713
)
714714
}
715715

@@ -740,7 +740,7 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
740740

741741
override DataFlowType getType() {
742742
exists(DataFlowType type |
743-
type = globalDef.getUnspecifiedType() and
743+
type = globalDef.getUnderlyingType() and
744744
if this.isGLValue()
745745
then result = type
746746
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
@@ -942,11 +942,14 @@ private Type getTypeImpl0(Type t, int indirectionIndex) {
942942
or
943943
indirectionIndex > 0 and
944944
exists(Type stripped |
945-
stripped = stripPointer(t.stripTopLevelSpecifiers()) and
946-
// We need to avoid the case where `stripPointer(t) = t` (which can happen on
947-
// iterators that specify a `value_type` that is the iterator itself). Such a type
948-
// would create an infinite loop otherwise. For these cases we simply don't produce
949-
// a result for `getTypeImpl`.
945+
stripped = stripPointer(t) and
946+
// We need to avoid the case where `stripPointer(t) = t` (which can happen
947+
// on iterators that specify a `value_type` that is the iterator itself).
948+
// Such a type would create an infinite loop otherwise. For these cases we
949+
// simply don't produce a result for `getTypeImpl`.
950+
// To be on the safe side, we check whether the _unspecified_ type has
951+
// changed since this also prevents an infinite loop for occuring when
952+
// `stripped` and `t` only differ by const'ness or volatile'ness.
950953
stripped.getUnspecifiedType() != t.getUnspecifiedType() and
951954
result = getTypeImpl0(stripped, indirectionIndex - 1)
952955
)
@@ -1001,7 +1004,7 @@ private module RawIndirectNodes {
10011004
type = getOperandType(this.getOperand(), isGLValue) and
10021005
if isGLValue = true then sub = 1 else sub = 0
10031006
|
1004-
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
1007+
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
10051008
)
10061009
}
10071010

@@ -1043,7 +1046,7 @@ private module RawIndirectNodes {
10431046
type = getInstructionType(this.getInstruction(), isGLValue) and
10441047
if isGLValue = true then sub = 1 else sub = 0
10451048
|
1046-
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
1049+
result = getTypeImpl(type.getUnderlyingType(), indirectionIndex - sub)
10471050
)
10481051
}
10491052

@@ -1136,7 +1139,7 @@ class FinalParameterNode extends Node, TFinalParameterNode {
11361139

11371140
override Declaration getEnclosingCallable() { result = this.getFunction() }
11381141

1139-
override DataFlowType getType() { result = getTypeImpl(p.getUnspecifiedType(), indirectionIndex) }
1142+
override DataFlowType getType() { result = getTypeImpl(p.getUnderlyingType(), indirectionIndex) }
11401143

11411144
final override Location getLocationImpl() {
11421145
// Parameters can have multiple locations. When there's a unique location we use
@@ -1789,7 +1792,7 @@ class VariableNode extends Node, TVariableNode {
17891792
}
17901793

17911794
override DataFlowType getType() {
1792-
result = getTypeImpl(v.getUnspecifiedType(), indirectionIndex - 1)
1795+
result = getTypeImpl(v.getUnderlyingType(), indirectionIndex - 1)
17931796
}
17941797

17951798
final override Location getLocationImpl() {

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,11 @@ class GlobalUse extends UseImpl, TGlobalUse {
548548
*/
549549
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
550550

551+
/**
552+
* Gets the type of this use, after typedefs have been resolved.
553+
*/
554+
Type getUnderlyingType() { result = global.getUnderlyingType() }
555+
551556
override predicate isCertain() { any() }
552557

553558
override BaseSourceVariableInstruction getBase() { none() }
@@ -591,11 +596,16 @@ class GlobalDefImpl extends DefOrUseImpl, TGlobalDefImpl {
591596
int getIndirection() { result = indirectionIndex }
592597

593598
/**
594-
* Gets the type of this use after specifiers have been deeply stripped
595-
* and typedefs have been resolved.
599+
* Gets the type of this definition after specifiers have been deeply
600+
* stripped and typedefs have been resolved.
596601
*/
597602
Type getUnspecifiedType() { result = global.getUnspecifiedType() }
598603

604+
/**
605+
* Gets the type of this definition, after typedefs have been resolved.
606+
*/
607+
Type getUnderlyingType() { result = global.getUnderlyingType() }
608+
599609
override string toString() { result = "Def of " + this.getSourceVariable() }
600610

601611
override Location getLocation() { result = f.getLocation() }
@@ -1115,6 +1125,11 @@ class GlobalDef extends TGlobalDef, SsaDefOrUse {
11151125
*/
11161126
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
11171127

1128+
/**
1129+
* Gets the type of this definition, after typedefs have been resolved.
1130+
*/
1131+
DataFlowType getUnderlyingType() { result = global.getUnderlyingType() }
1132+
11181133
/** Gets the `IRFunction` whose body is evaluated after this definition. */
11191134
IRFunction getIRFunction() { result = global.getIRFunction() }
11201135

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,18 @@
11
astTypeBugs
22
irTypeBugs
33
incorrectBaseType
4-
| BarrierGuard.cpp:75:15:75:17 | *buf | Expected 'Node.getType()' to be const int, but it was int |
5-
| clang.cpp:18:8:18:19 | *sourceArray1 | Expected 'Node.getType()' to be const int, but it was int |
64
| clang.cpp:22:8:22:20 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
75
| clang.cpp:23:17:23:29 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
8-
| clang.cpp:52:8:52:17 | *stackArray | Expected 'Node.getType()' to be const int, but it was int |
96
| dispatch.cpp:60:3:60:14 | *globalBottom | Expected 'Node.getType()' to be Top, but it was Top * |
107
| dispatch.cpp:61:3:61:14 | *globalMiddle | Expected 'Node.getType()' to be Top, but it was Top * |
11-
| example.c:19:6:19:6 | *b | Expected 'Node.getType()' to be MyBool, but it was (unnamed class/struct/union) |
12-
| example.c:26:18:26:24 | *& ... | Expected 'Node.getType()' to be MyCoords, but it was (unnamed class/struct/union) |
13-
| file://:0:0:0:0 | *this | Expected 'Node.getType()' to be const lambda [] type at line 13, col. 11, but it was decltype([...](...){...}) |
148
| flowOut.cpp:50:14:50:15 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
15-
| flowOut.cpp:67:21:67:21 | *p | Expected 'Node.getType()' to be const char, but it was char |
169
| flowOut.cpp:84:9:84:10 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
1710
| flowOut.cpp:101:13:101:14 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
18-
| flowOut.cpp:111:34:111:34 | *p | Expected 'Node.getType()' to be const void, but it was void |
19-
| flowOut.cpp:139:30:139:30 | *p | Expected 'Node.getType()' to be const char *, but it was char * |
20-
| flowOut.cpp:154:30:154:30 | *p | Expected 'Node.getType()' to be const char *, but it was char * |
2111
| flowOut.cpp:168:3:168:10 | ** ... | Expected 'Node.getType()' to be char, but it was char * |
22-
| flowOut.cpp:176:30:176:30 | *p | Expected 'Node.getType()' to be const char *, but it was char * |
23-
| flowOut.cpp:193:30:193:30 | *p | Expected 'Node.getType()' to be const char *, but it was char * |
24-
| lambdas.cpp:14:3:14:6 | *this | Expected 'Node.getType()' to be const lambda [] type at line 13, col. 11, but it was decltype([...](...){...}) |
25-
| lambdas.cpp:15:3:15:6 | *this | Expected 'Node.getType()' to be const lambda [] type at line 13, col. 11, but it was decltype([...](...){...}) |
26-
| lambdas.cpp:21:3:21:6 | *this | Expected 'Node.getType()' to be const lambda [] type at line 20, col. 11, but it was decltype([...](...){...}) |
27-
| lambdas.cpp:22:3:22:6 | *this | Expected 'Node.getType()' to be const lambda [] type at line 20, col. 11, but it was decltype([...](...){...}) |
28-
| lambdas.cpp:23:3:23:14 | *this | Expected 'Node.getType()' to be const lambda [] type at line 20, col. 11, but it was decltype([...](...){...}) |
29-
| lambdas.cpp:29:3:29:6 | *this | Expected 'Node.getType()' to be const lambda [] type at line 28, col. 11, but it was decltype([...](...){...}) |
30-
| lambdas.cpp:30:3:30:6 | *this | Expected 'Node.getType()' to be const lambda [] type at line 28, col. 11, but it was decltype([...](...){...}) |
3112
| self_parameter_flow.cpp:8:8:8:9 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
3213
| test.cpp:67:28:67:37 | (reference dereference) | Expected 'Node.getType()' to be const int, but it was int * |
33-
| test.cpp:67:28:67:37 | *call to move | Expected 'Node.getType()' to be const int, but it was int |
34-
| test.cpp:70:19:70:33 | *x3 | Expected 'Node.getType()' to be const int, but it was int |
35-
| test.cpp:71:8:71:9 | *x4 | Expected 'Node.getType()' to be const int, but it was int |
36-
| test.cpp:384:16:384:23 | *& ... | Expected 'Node.getType()' to be const void, but it was void |
37-
| test.cpp:391:16:391:23 | *& ... | Expected 'Node.getType()' to be const void, but it was void |
38-
| test.cpp:400:16:400:22 | *& ... | Expected 'Node.getType()' to be const void, but it was void |
39-
| test.cpp:407:16:407:22 | *& ... | Expected 'Node.getType()' to be const void, but it was void |
40-
| test.cpp:526:3:526:4 | ** ... | Expected 'Node.getType()' to be const int *, but it was int * |
41-
| test.cpp:526:3:526:4 | ** ... | Expected 'Node.getType()' to be const int, but it was int * |
42-
| test.cpp:526:8:526:9 | *& ... | Expected 'Node.getType()' to be const int, but it was int |
43-
| test.cpp:531:39:531:40 | *& ... | Expected 'Node.getType()' to be const int *, but it was int * |
44-
| test.cpp:531:39:531:40 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
14+
| test.cpp:526:3:526:4 | ** ... | Expected 'Node.getType()' to be const int, but it was const int * |
15+
| test.cpp:531:39:531:40 | *& ... | Expected 'Node.getType()' to be int, but it was const int * |
4516
| test.cpp:562:5:562:13 | *globalInt | Expected 'Node.getType()' to be int, but it was int * |
4617
| test.cpp:576:5:576:13 | *globalInt | Expected 'Node.getType()' to be int, but it was int * |
4718
| test.cpp:584:3:584:3 | *x | Expected 'Node.getType()' to be int, but it was int * |
@@ -50,73 +21,14 @@ incorrectBaseType
5021
| test.cpp:704:22:704:25 | *& ... | Expected 'Node.getType()' to be int, but it was int * |
5122
| test.cpp:715:24:715:25 | *& ... | Expected 'Node.getType()' to be unsigned char, but it was unsigned char * |
5223
| test.cpp:727:3:727:3 | *p | Expected 'Node.getType()' to be int, but it was int * |
53-
| test.cpp:797:31:797:39 | *content | Expected 'Node.getType()' to be const int, but it was int |
5424
| test.cpp:808:5:808:21 | ** ... | Expected 'Node.getType()' to be int, but it was int * |
5525
| test.cpp:832:5:832:17 | *global_direct | Expected 'Node.getType()' to be int *, but it was int ** |
5626
| test.cpp:848:23:848:25 | (reference dereference) | Expected 'Node.getType()' to be int, but it was int * |
5727
| test.cpp:854:10:854:36 | * ... | Expected 'Node.getType()' to be const int, but it was int |
58-
| test.cpp:860:54:860:59 | *call to source | Expected 'Node.getType()' to be const int, but it was int |
59-
| test.cpp:861:10:861:37 | *static_local_pointer_dynamic | Expected 'Node.getType()' to be const int, but it was int |
6028
| test.cpp:867:10:867:30 | * ... | Expected 'Node.getType()' to be const int, but it was int |
61-
| test.cpp:872:46:872:51 | *call to source | Expected 'Node.getType()' to be const int, but it was int |
62-
| test.cpp:875:10:875:31 | *global_pointer_dynamic | Expected 'Node.getType()' to be const int, but it was int |
63-
| test.cpp:882:10:882:34 | *static_local_array_static | Expected 'Node.getType()' to be const char, but it was char |
64-
| test.cpp:883:10:883:45 | *static_local_array_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
65-
| test.cpp:884:19:884:54 | *static_local_array_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
66-
| test.cpp:885:10:885:45 | *static_local_array_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
67-
| test.cpp:886:19:886:54 | *static_local_array_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
68-
| test.cpp:890:54:890:61 | *source | Expected 'Node.getType()' to be const char, but it was char |
69-
| test.cpp:891:65:891:84 | *indirect_source(1) | Expected 'Node.getType()' to be const char, but it was char |
70-
| test.cpp:892:65:892:84 | *indirect_source(2) | Expected 'Node.getType()' to be const char, but it was char |
71-
| test.cpp:893:10:893:36 | *static_local_pointer_static | Expected 'Node.getType()' to be const char, but it was char |
72-
| test.cpp:894:10:894:47 | *static_local_pointer_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
73-
| test.cpp:895:19:895:56 | *static_local_pointer_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
74-
| test.cpp:896:10:896:47 | *static_local_pointer_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
75-
| test.cpp:897:19:897:56 | *static_local_pointer_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
76-
| test.cpp:905:10:905:28 | *global_array_static | Expected 'Node.getType()' to be const char, but it was char |
77-
| test.cpp:907:10:907:39 | *global_array_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
78-
| test.cpp:909:19:909:37 | *global_array_static | Expected 'Node.getType()' to be const char, but it was char |
79-
| test.cpp:910:19:910:48 | *global_array_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
80-
| test.cpp:911:19:911:48 | *global_array_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
81-
| test.cpp:914:46:914:53 | *source | Expected 'Node.getType()' to be const char, but it was char |
82-
| test.cpp:915:57:915:76 | *indirect_source(1) | Expected 'Node.getType()' to be const char, but it was char |
83-
| test.cpp:916:57:916:76 | *indirect_source(2) | Expected 'Node.getType()' to be const char, but it was char |
84-
| test.cpp:919:10:919:30 | *global_pointer_static | Expected 'Node.getType()' to be const char, but it was char |
85-
| test.cpp:920:10:920:41 | *global_pointer_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
86-
| test.cpp:921:19:921:50 | *global_pointer_static_indirect_1 | Expected 'Node.getType()' to be const char, but it was char |
87-
| test.cpp:922:10:922:41 | *global_pointer_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
88-
| test.cpp:923:19:923:50 | *global_pointer_static_indirect_2 | Expected 'Node.getType()' to be const char, but it was char |
8929
| test.cpp:931:5:931:18 | *global_pointer | Expected 'Node.getType()' to be int, but it was int * |
90-
| test.cpp:952:32:952:35 | *data | Expected 'Node.getType()' to be const char, but it was char |
91-
| test.cpp:959:32:959:35 | *data | Expected 'Node.getType()' to be const char, but it was char |
92-
| test.cpp:967:33:967:38 | *domain | Expected 'Node.getType()' to be const char, but it was char |
93-
| test.cpp:967:41:967:44 | *data | Expected 'Node.getType()' to be const char, but it was char |
94-
| test.cpp:975:33:975:38 | *domain | Expected 'Node.getType()' to be const char, but it was char |
95-
| test.cpp:975:41:975:44 | *data | Expected 'Node.getType()' to be const char, but it was char |
96-
| test.cpp:984:33:984:36 | *data | Expected 'Node.getType()' to be const char, but it was char |
97-
| test.cpp:984:39:984:40 | *np | Expected 'Node.getType()' to be const char, but it was char |
9830
| test.cpp:988:5:988:14 | *translated | Expected 'Node.getType()' to be char, but it was char * |
99-
| test.cpp:988:27:988:28 | *np | Expected 'Node.getType()' to be const char, but it was char |
100-
| test.cpp:988:31:988:34 | *data | Expected 'Node.getType()' to be const char, but it was char |
101-
| test.cpp:997:33:997:36 | *data | Expected 'Node.getType()' to be const char, but it was char |
102-
| test.cpp:997:39:997:40 | *np | Expected 'Node.getType()' to be const char, but it was char |
10331
| test.cpp:1001:5:1001:14 | *translated | Expected 'Node.getType()' to be char, but it was char * |
104-
| test.cpp:1001:27:1001:28 | *np | Expected 'Node.getType()' to be const char, but it was char |
105-
| test.cpp:1001:31:1001:34 | *data | Expected 'Node.getType()' to be const char, but it was char |
106-
| test.cpp:1011:34:1011:39 | *domain | Expected 'Node.getType()' to be const char, but it was char |
107-
| test.cpp:1011:42:1011:45 | *data | Expected 'Node.getType()' to be const char, but it was char |
108-
| test.cpp:1011:48:1011:49 | *np | Expected 'Node.getType()' to be const char, but it was char |
10932
| test.cpp:1015:5:1015:14 | *translated | Expected 'Node.getType()' to be char, but it was char * |
110-
| test.cpp:1015:28:1015:33 | *domain | Expected 'Node.getType()' to be const char, but it was char |
111-
| test.cpp:1015:36:1015:37 | *np | Expected 'Node.getType()' to be const char, but it was char |
112-
| test.cpp:1015:40:1015:43 | *data | Expected 'Node.getType()' to be const char, but it was char |
113-
| test.cpp:1025:34:1025:39 | *domain | Expected 'Node.getType()' to be const char, but it was char |
114-
| test.cpp:1025:42:1025:45 | *data | Expected 'Node.getType()' to be const char, but it was char |
115-
| test.cpp:1025:48:1025:49 | *np | Expected 'Node.getType()' to be const char, but it was char |
11633
| test.cpp:1029:5:1029:14 | *translated | Expected 'Node.getType()' to be char, but it was char * |
117-
| test.cpp:1029:28:1029:33 | *domain | Expected 'Node.getType()' to be const char, but it was char |
118-
| test.cpp:1029:36:1029:37 | *np | Expected 'Node.getType()' to be const char, but it was char |
119-
| test.cpp:1029:40:1029:43 | *data | Expected 'Node.getType()' to be const char, but it was char |
120-
| test.cpp:1036:33:1036:38 | *domain | Expected 'Node.getType()' to be const char, but it was char |
121-
| test.cpp:1036:41:1036:47 | *0 | Expected 'Node.getType()' to be const char, but it was char |
12234
failures

0 commit comments

Comments
 (0)