C front-end: Do not wrongly propagate const-ness
This bug has been lingering for a longer time, but only started showing up with
the propagation fix in 2c16231b48
.
1. Qualifiers (and const-ness in particular) are a property of the type, and not
an expression. Make sure all uses of ID_C_constant affect the type.
2. Qualifiers go with the type of the symbol being declared, and aren't a
property that applies across uses of the same type.
This commit is contained in:
parent
0e695d08f7
commit
03d4b70a7e
|
@ -0,0 +1,36 @@
|
|||
#if TEST == 0
|
||||
const struct buffer *foo();
|
||||
|
||||
typedef struct buffer
|
||||
{
|
||||
int head;
|
||||
} buffer_t;
|
||||
#endif
|
||||
|
||||
#if TEST == 1
|
||||
struct buffer *foo();
|
||||
|
||||
typedef struct buffer
|
||||
{
|
||||
int head;
|
||||
} buffer_t;
|
||||
#endif
|
||||
|
||||
#if TEST == 2
|
||||
typedef struct buffer
|
||||
{
|
||||
int head;
|
||||
} buffer_t;
|
||||
|
||||
const struct buffer *foo();
|
||||
#endif
|
||||
|
||||
static void clear(buffer_t *buf)
|
||||
{
|
||||
buf->head = 0u;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
CORE
|
||||
main.c
|
||||
-DTEST=0
|
||||
^EXIT=0$
|
||||
^SIGNAL=0$
|
||||
--
|
||||
^.*: .* is constant$
|
|
@ -0,0 +1,7 @@
|
|||
CORE
|
||||
main.c
|
||||
-DTEST=1
|
||||
^EXIT=0$
|
||||
^SIGNAL=0$
|
||||
--
|
||||
^.*: .* is constant$
|
|
@ -0,0 +1,7 @@
|
|||
CORE
|
||||
main.c
|
||||
-DTEST=2
|
||||
^EXIT=0$
|
||||
^SIGNAL=0$
|
||||
--
|
||||
^.*: .* is constant$
|
|
@ -29,10 +29,11 @@ static exprt make_member_expr(
|
|||
const typet &type=
|
||||
ns.follow(struct_union.type());
|
||||
|
||||
if(result.get_bool(ID_C_constant) ||
|
||||
type.get_bool(ID_C_constant) ||
|
||||
struct_union.type().get_bool(ID_C_constant))
|
||||
result.set(ID_C_constant, true);
|
||||
if(
|
||||
type.get_bool(ID_C_constant) || struct_union.type().get_bool(ID_C_constant))
|
||||
{
|
||||
result.type().set(ID_C_constant, true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -555,12 +555,6 @@ void c_typecastt::implicit_typecast_followed(
|
|||
|
||||
// check qualifiers
|
||||
|
||||
/*
|
||||
if(src_type.subtype().get_bool(ID_C_constant) &&
|
||||
!dest_type.subtype().get_bool(ID_C_constant))
|
||||
warnings.push_back("disregarding const");
|
||||
*/
|
||||
|
||||
if(src_type.subtype().get_bool(ID_C_volatile) &&
|
||||
!dest_type.subtype().get_bool(ID_C_volatile))
|
||||
warnings.push_back("disregarding volatile");
|
||||
|
|
|
@ -358,8 +358,8 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr)
|
|||
if(op.get_bool(ID_C_lvalue))
|
||||
complex_real_expr.set(ID_C_lvalue, true);
|
||||
|
||||
if(op.get_bool(ID_C_constant))
|
||||
complex_real_expr.set(ID_C_constant, true);
|
||||
if(op.type().get_bool(ID_C_constant))
|
||||
complex_real_expr.type().set(ID_C_constant, true);
|
||||
|
||||
expr.swap(complex_real_expr);
|
||||
}
|
||||
|
@ -396,8 +396,8 @@ void c_typecheck_baset::typecheck_expr_main(exprt &expr)
|
|||
if(op.get_bool(ID_C_lvalue))
|
||||
complex_imag_expr.set(ID_C_lvalue, true);
|
||||
|
||||
if(op.get_bool(ID_C_constant))
|
||||
complex_imag_expr.set(ID_C_constant, true);
|
||||
if(op.type().get_bool(ID_C_constant))
|
||||
complex_imag_expr.type().set(ID_C_constant, true);
|
||||
|
||||
expr.swap(complex_imag_expr);
|
||||
}
|
||||
|
@ -2853,7 +2853,7 @@ void c_typecheck_baset::typecheck_function_call_arguments(
|
|||
if(type.id()==ID_array)
|
||||
{
|
||||
typet dest_type=pointer_type(void_type());
|
||||
dest_type.subtype().set(ID_C_constant, ID_1);
|
||||
dest_type.subtype().set(ID_C_constant, true);
|
||||
implicit_typecast(op, dest_type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -722,6 +722,16 @@ void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type)
|
|||
|
||||
bool have_body=type.find(ID_components).is_not_nil();
|
||||
|
||||
c_qualifierst original_qualifiers(type);
|
||||
|
||||
// the type symbol, which may get re-used in other declarations, must not
|
||||
// carry any qualifiers (other than transparent_union, which isn't really a
|
||||
// qualifier)
|
||||
c_qualifierst remove_qualifiers;
|
||||
remove_qualifiers.is_transparent_union =
|
||||
original_qualifiers.is_transparent_union;
|
||||
remove_qualifiers.write(type);
|
||||
|
||||
if(type.find(ID_tag).is_nil())
|
||||
{
|
||||
// Anonymous? Must come with body.
|
||||
|
@ -818,8 +828,6 @@ void c_typecheck_baset::typecheck_compound_type(struct_union_typet &type)
|
|||
}
|
||||
}
|
||||
|
||||
c_qualifierst original_qualifiers(type);
|
||||
|
||||
typet tag_type;
|
||||
|
||||
if(type.id() == ID_union || type.id() == ID_incomplete_union)
|
||||
|
|
Loading…
Reference in New Issue