@@ -3710,8 +3710,11 @@ exprt c_typecheck_baset::do_special_functions(
3710
3710
}
3711
3711
else if (identifier==" __builtin_constant_p" )
3712
3712
{
3713
- // this is a gcc extension to tell whether the argument
3714
- // is known to be a compile-time constant
3713
+ // This is a gcc/clang extension to tell whether the argument
3714
+ // is known to be a compile-time constant. The behavior of these two
3715
+ // compiler families, however, is quite different, which we need to take
3716
+ // care of in the below config-dependent branches.
3717
+
3715
3718
if (expr.arguments ().size ()!=1 )
3716
3719
{
3717
3720
error ().source_location = f_op.source_location ();
@@ -3722,27 +3725,35 @@ exprt c_typecheck_baset::do_special_functions(
3722
3725
// do not typecheck the argument - it is never evaluated, and thus side
3723
3726
// effects must not show up either
3724
3727
3725
- // try to produce constant
3726
- exprt tmp1=expr.arguments ().front ();
3727
- simplify (tmp1, *this );
3728
-
3729
- bool is_constant=false ;
3730
-
3731
- // Need to do some special treatment for string literals,
3732
- // which are (void *)&("lit"[0])
3733
- if (
3734
- tmp1.id () == ID_typecast &&
3735
- to_typecast_expr (tmp1).op ().id () == ID_address_of &&
3736
- to_address_of_expr (to_typecast_expr (tmp1).op ()).object ().id () ==
3737
- ID_index &&
3738
- to_index_expr (to_address_of_expr (to_typecast_expr (tmp1).op ()).object ())
3739
- .array ()
3740
- .id () == ID_string_constant)
3728
+ bool is_constant = false ;
3729
+ if (config.ansi_c .mode == configt::ansi_ct::flavourt::CLANG)
3741
3730
{
3742
- is_constant= true ;
3731
+ is_constant = is_compile_time_constantt (* this )(expr. arguments (). front ()) ;
3743
3732
}
3744
3733
else
3745
- is_constant=tmp1.is_constant ();
3734
+ {
3735
+ // try to produce constant
3736
+ exprt tmp1 = expr.arguments ().front ();
3737
+ simplify (tmp1, *this );
3738
+
3739
+ // Need to do some special treatment for string literals,
3740
+ // which are (void *)&("lit"[0])
3741
+ if (
3742
+ tmp1.id () == ID_typecast &&
3743
+ to_typecast_expr (tmp1).op ().id () == ID_address_of &&
3744
+ to_address_of_expr (to_typecast_expr (tmp1).op ()).object ().id () ==
3745
+ ID_index &&
3746
+ to_index_expr (to_address_of_expr (to_typecast_expr (tmp1).op ()).object ())
3747
+ .array ()
3748
+ .id () == ID_string_constant)
3749
+ {
3750
+ is_constant = true ;
3751
+ }
3752
+ else if (tmp1.id () == ID_string_constant)
3753
+ is_constant = true ;
3754
+ else
3755
+ is_constant = tmp1.is_constant ();
3756
+ }
3746
3757
3747
3758
exprt tmp2=from_integer (is_constant, expr.type ());
3748
3759
tmp2.add_source_location ()=source_location;
0 commit comments