Skip to content

Commit c64eacc

Browse files
author
thk123
committed
Fixed the failing ANSI-C test caused by typedef types not being equal
Previously, basic types were being compared by directly calling operator== on the two types. However, we now add a flag to all types defined with a typedef saying what the typedef'd name was. This was causing the two types to not be equal. Now, instead of directly comparing them, we remove the ID_C_typedef flag from them if present and then compare the resulting types. Also added a few more checks to the test to cover some other typedef cases.
1 parent 7c1aeb4 commit c64eacc

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed

regression/ansi-c/gcc_types_compatible_p1/main.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ double d;
77
typedef enum T1 { hot, dog, poo, bear } dingos;
88
typedef enum T2 { janette, laura, amanda } cranberry;
99

10+
typedef enum AnonEnum { jim, bob, fred } names;
11+
12+
typedef dingos altdingos;
13+
typedef dingos diffdingos;
14+
15+
typedef names altnames;
16+
typedef names diffnames;
17+
1018
typedef float same1;
1119
typedef float same2;
1220

@@ -52,6 +60,9 @@ STATIC_ASSERT(__builtin_types_compatible_p(typeof (dingos), unsigned)); // ha!
5260
STATIC_ASSERT(__builtin_types_compatible_p(typeof (hot), typeof (laura)));
5361
STATIC_ASSERT(__builtin_types_compatible_p(int[5], int[]));
5462
STATIC_ASSERT(__builtin_types_compatible_p(same1, same2));
63+
STATIC_ASSERT(__builtin_types_compatible_p(dingos, altdingos));
64+
STATIC_ASSERT(__builtin_types_compatible_p(diffdingos, altdingos));
65+
STATIC_ASSERT(__builtin_types_compatible_p(diffnames, altnames));
5566
STATIC_ASSERT(__builtin_types_compatible_p(typeof (hot) *, int *));
5667
STATIC_ASSERT(__builtin_types_compatible_p(typeof (hot), typeof (janette)));
5768
STATIC_ASSERT(__builtin_types_compatible_p(__int128, signed __int128));
@@ -84,7 +95,6 @@ STATIC_ASSERT(!__builtin_types_compatible_p(__float128, long double));
8495
STATIC_ASSERT(!__builtin_types_compatible_p(__float128, double));
8596
STATIC_ASSERT(!__builtin_types_compatible_p(__int128, unsigned __int128));
8697
#endif
87-
8898
#endif
8999

90100
int main(void)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#define STATIC_ASSERT(condition) \
2+
int some_array[(condition) ? 1 : -1];
3+
4+
typedef struct struct_tag
5+
{
6+
int x;
7+
float y;
8+
} struct_typedef;
9+
10+
typedef struct struct_tag alt_typedef;
11+
typedef struct_typedef another_typedef;
12+
13+
#ifdef __GNUC__
14+
15+
16+
STATIC_ASSERT(__builtin_types_compatible_p(struct struct_tag, struct_typedef));
17+
STATIC_ASSERT(__builtin_types_compatible_p(struct struct_tag, alt_typedef));
18+
STATIC_ASSERT(__builtin_types_compatible_p(struct struct_tag, another_typedef));
19+
STATIC_ASSERT(__builtin_types_compatible_p(struct_typedef, alt_typedef));
20+
STATIC_ASSERT(__builtin_types_compatible_p(struct_typedef, another_typedef));
21+
STATIC_ASSERT(__builtin_types_compatible_p(alt_typedef, another_typedef));
22+
23+
#endif
24+
25+
int main(void)
26+
{
27+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

src/ansi-c/c_typecheck_base.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ class c_typecheck_baset:
262262
asm_label_mapt asm_label_map;
263263

264264
void apply_asm_label(const irep_idt &asm_label, symbolt &symbol);
265+
266+
private:
267+
static bool are_types_equal_ignoring_typedef(
268+
const typet type1, const typet &type2);
265269
};
266270

267271
#endif // CPROVER_ANSI_C_C_TYPECHECK_BASE_H

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ bool c_typecheck_baset::gcc_types_compatible_p(
140140
if(type1.id()==ID_c_enum)
141141
{
142142
if(type2.id()==ID_c_enum) // both are enums
143+
// We don't need to remove the typedef flag here since as it is an enum
144+
// we have already followed the enum tag to get to the underlying enum
143145
return type1==type2; // compares the tag
144146
else if(type2==type1.subtype())
145147
return true;
@@ -184,12 +186,13 @@ bool c_typecheck_baset::gcc_types_compatible_p(
184186
}
185187
else
186188
{
187-
if(type1==type2)
189+
if(are_types_equal_ignoring_typedef(type1, type2))
188190
{
189191
// Need to distinguish e.g. long int from int or
190192
// long long int from long int.
191193
// The rules appear to match those of C++.
192-
194+
// Isn't this explictly handled by checking type1==type2 (since
195+
// operator== recursively checks all sub types).
193196
if(type1.get(ID_C_c_type)==type2.get(ID_C_c_type))
194197
return true;
195198
}
@@ -200,6 +203,38 @@ bool c_typecheck_baset::gcc_types_compatible_p(
200203

201204
/*******************************************************************\
202205
206+
Function: c_typecheck_baset::are_types_equal_ignoring_typedef
207+
208+
Inputs:
209+
type1 - the first type to compare
210+
type2 - the second type to compare
211+
212+
Outputs: True if the types are equal
213+
214+
Purpose: To check whether two types are equal, ignoring if they have a
215+
different typedef tag. We do this by explictly removing the
216+
ID_C_typedef from the type before comparing. Then we just use
217+
operator== to compare the resultant types.
218+
219+
\*******************************************************************/
220+
bool c_typecheck_baset::are_types_equal_ignoring_typedef(
221+
const typet type1, const typet &type2)
222+
{
223+
typet non_typedefd_type1=type1;
224+
typet non_typedefd_type2=type2;
225+
if(type1.get(ID_C_typedef)!=ID_nil)
226+
{
227+
non_typedefd_type1.remove(ID_C_typedef);
228+
}
229+
if(type2.get(ID_C_typedef)!=ID_nil)
230+
{
231+
non_typedefd_type2.remove(ID_C_typedef);
232+
}
233+
return non_typedefd_type1==non_typedefd_type2;
234+
}
235+
236+
/*******************************************************************\
237+
203238
Function: c_typecheck_baset::typecheck_expr_main
204239
205240
Inputs:

0 commit comments

Comments
 (0)