1616#include < util/arith_tools.h>
1717#include < util/base_type.h>
1818#include < util/c_types.h>
19+ #include < util/config.h>
1920#include < util/cprover_prefix.h>
2021#include < util/ieee_float.h>
2122#include < util/pointer_offset_size.h>
@@ -2581,7 +2582,7 @@ exprt c_typecheck_baset::do_special_functions(
25812582 }
25822583 else if (identifier==" __builtin_classify_type" )
25832584 {
2584- // This is a gcc extension that produces an integer
2585+ // This is a gcc/clang extension that produces an integer
25852586 // constant for the type of the argument expression.
25862587 if (expr.arguments ().size ()!=1 )
25872588 {
@@ -2594,22 +2595,34 @@ exprt c_typecheck_baset::do_special_functions(
25942595
25952596 // The value doesn't matter at all, we only care about the type.
25962597 // Need to sync with typeclass.h.
2597- const typet &type=follow (object.type ());
2598-
2599- unsigned type_number=
2600- type.id ()==ID_empty?0 :
2601- type.id ()==ID_c_enum_tag?3 :
2602- (type.id ()==ID_bool || type.id ()==ID_c_bool)?4 :
2603- type.id ()==ID_pointer?5 :
2604- type.id ()==ID_floatbv?8 :
2605- (type.id ()==ID_complex && type.subtype ().id ()==ID_floatbv)?9 :
2606- type.id ()==ID_struct?12 :
2607- type.id ()==ID_union?13 :
2608- type.id ()==ID_array?14 :
2609- 1 ; // int, short
2610-
2611- // clang returns 15 for the three 'char' types,
2612- // gcc treats these as 'int'
2598+ typet type=follow (object.type ());
2599+
2600+ // use underlying type for bit fields
2601+ if (type.id ()==ID_c_bit_field)
2602+ type=to_c_bit_field_type (type).subtype ();
2603+
2604+ unsigned type_number;
2605+
2606+ if (type.id ()==ID_bool || type.id ()==ID_c_bool)
2607+ {
2608+ // clang returns 4 for _Bool, gcc treats these as 'int'.
2609+ if (config.ansi_c .preprocessor == configt::ansi_ct::preprocessort::CLANG)
2610+ type_number=4 ;
2611+ else
2612+ type_number=1 ;
2613+ }
2614+ else
2615+ {
2616+ type_number=
2617+ type.id ()==ID_empty?0 :
2618+ (type.id ()==ID_bool || type.id ()==ID_c_bool)?4 :
2619+ (type.id ()==ID_pointer || type.id ()==ID_array)?5 :
2620+ type.id ()==ID_floatbv?8 :
2621+ (type.id ()==ID_complex && type.subtype ().id ()==ID_floatbv)?9 :
2622+ type.id ()==ID_struct?12 :
2623+ type.id ()==ID_union?13 :
2624+ 1 ; // int, short, char, enum_tag
2625+ }
26132626
26142627 exprt tmp=from_integer (type_number, expr.type ());
26152628 tmp.add_source_location ()=source_location;
0 commit comments