diff --git a/tccgen.c b/tccgen.c index a4a3e640..a899444c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5006,9 +5006,6 @@ the_end: function pointer) */ static inline void convert_parameter_type(CType *pt) { - /* remove const and volatile qualifiers (XXX: const could be used - to indicate a const function parameter */ - pt->t &= ~(VT_CONSTANT | VT_VOLATILE); /* array must be transformed to pointer according to ANSI C */ pt->t &= ~(VT_ARRAY | VT_VLA); if ((pt->t & VT_BTYPE) == VT_FUNC) { @@ -5016,6 +5013,13 @@ static inline void convert_parameter_type(CType *pt) } } +/* apply the conversions required for an expression value */ +static inline void convert_expression_type(CType *pt) +{ + pt->t &= ~(VT_CONSTANT | VT_VOLATILE); + convert_parameter_type(pt); +} + ST_FUNC CString* parse_asm_str(void) { skip('('); @@ -6063,7 +6067,7 @@ ST_FUNC void unary(void) next(); skip('('); expr_type(&controlling_type, expr_eq); - convert_parameter_type (&controlling_type); + convert_expression_type(&controlling_type); nocode_wanted = saved_nocode_wanted; @@ -6774,7 +6778,7 @@ ST_FUNC void gexpr(void) } while (tok == ','); /* convert array & function to pointer */ - convert_parameter_type(&vtop->type); + convert_expression_type(&vtop->type); /* make builtin_constant_p((1,2)) return 0 (like on gcc) */ if ((vtop->r & VT_VALMASK) == VT_CONST && nocode_wanted && !CONST_WANTED) diff --git a/tests/tests2/149_parameter_qualifier_errors.c b/tests/tests2/149_parameter_qualifier_errors.c new file mode 100644 index 00000000..93c853e2 --- /dev/null +++ b/tests/tests2/149_parameter_qualifier_errors.c @@ -0,0 +1,11 @@ +void defined_const(int *pointer); + +void defined_const(int *const pointer) +{ + pointer = 0; +} + +int main(void) +{ + return 0; +} diff --git a/tests/tests2/149_parameter_qualifier_errors.expect b/tests/tests2/149_parameter_qualifier_errors.expect new file mode 100644 index 00000000..dbcdbd0a --- /dev/null +++ b/tests/tests2/149_parameter_qualifier_errors.expect @@ -0,0 +1 @@ +149_parameter_qualifier_errors.c:5: warning: assignment of read-only location diff --git a/tests/tests2/149_parameter_qualifiers.c b/tests/tests2/149_parameter_qualifiers.c new file mode 100644 index 00000000..663592c0 --- /dev/null +++ b/tests/tests2/149_parameter_qualifiers.c @@ -0,0 +1,61 @@ +void pointer_parameters(int *const cp, int *volatile vp, int *restrict rp) +{ + _Static_assert(_Generic(&cp, int *const *: 1, default: 0), + "const pointer parameter remains qualified"); + _Static_assert(_Generic(&vp, int *volatile *: 1, default: 0), + "volatile pointer parameter remains qualified"); + _Static_assert(_Generic(&rp, int *restrict *: 1, default: 0), + "restrict pointer parameter remains qualified"); +} + +void declared_const(int *const pointer); +void declared_const(int *pointer) +{ + _Static_assert(_Generic(&pointer, int **: 1, default: 0), + "declaration qualifier does not affect definition"); + pointer = 0; +} + +void defined_const(int *pointer); +void defined_const(int *const pointer) +{ + _Static_assert(_Generic(&pointer, int *const *: 1, default: 0), + "definition retains const"); +} + +void declared_volatile(int *volatile pointer); +void declared_volatile(int *pointer) +{ + _Static_assert(_Generic(&pointer, int **: 1, default: 0), + "declaration qualifier does not affect definition"); + pointer = 0; +} + +void defined_volatile(int *pointer); +void defined_volatile(int *volatile pointer) +{ + _Static_assert(_Generic(&pointer, int *volatile *: 1, default: 0), + "definition retains volatile"); + pointer = 0; +} + +void declared_restrict(int *restrict pointer); +void declared_restrict(int *pointer) +{ + _Static_assert(_Generic(&pointer, int **: 1, default: 0), + "declaration qualifier does not affect definition"); + pointer = 0; +} + +void defined_restrict(int *pointer); +void defined_restrict(int *restrict pointer) +{ + _Static_assert(_Generic(&pointer, int *restrict *: 1, default: 0), + "definition retains restrict"); + pointer = 0; +} + +int main(void) +{ + return 0; +} diff --git a/tests/tests2/149_parameter_qualifiers.expect b/tests/tests2/149_parameter_qualifiers.expect new file mode 100644 index 00000000..e69de29b