From: Christoph Mallon Date: Wed, 3 Dec 2008 21:00:43 +0000 (+0000) Subject: Repair semantic of return-statements for C and implement them for C++. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=1b76577e19cec561f08312a015128dad9d7534f3;p=cparser Repair semantic of return-statements for C and implement them for C++. [r24274] --- diff --git a/parser.c b/parser.c index dde9319..d23d7bf 100644 --- a/parser.c +++ b/parser.c @@ -10370,34 +10370,54 @@ static statement_t *parse_return(void) assert(is_type_function(func_type)); type_t *const return_type = skip_typeref(func_type->function.return_type); + source_position_t const *const pos = &statement->base.source_position; if (return_value != NULL) { type_t *return_value_type = skip_typeref(return_value->base.type); - if (is_type_atomic(return_type, ATOMIC_TYPE_VOID) && - !is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) { - if (warning.other) { - warningf(&statement->base.source_position, - "'return' with a value, in function returning void"); + if (is_type_atomic(return_type, ATOMIC_TYPE_VOID)) { + if (is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) { + /* ISO/IEC 14882:1998(E) §6.6.3:2 */ + /* Only warn in C mode, because GCC does the same */ + if (c_mode & _CXX || strict_mode) { + errorf(pos, + "'return' with a value, in function returning 'void'"); + } else if (warning.other) { + warningf(pos, + "'return' with a value, in function returning 'void'"); + } + } else if (!(c_mode & _CXX)) { /* ISO/IEC 14882:1998(E) §6.6.3:3 */ + /* Only warn in C mode, because GCC does the same */ + if (strict_mode) { + errorf(pos, + "'return' with expression in function return 'void'"); + } else if (warning.other) { + warningf(pos, + "'return' with expression in function return 'void'"); + } } - return_value = NULL; } else { assign_error_t error = semantic_assign(return_type, return_value); report_assign_error(error, return_type, return_value, "'return'", - &statement->base.source_position); - return_value = create_implicit_cast(return_value, return_type); + pos); } + return_value = create_implicit_cast(return_value, return_type); /* check for returning address of a local var */ if (warning.other && return_value != NULL && return_value->base.kind == EXPR_UNARY_TAKE_ADDRESS) { const expression_t *expression = return_value->unary.value; if (expression_is_local_variable(expression)) { - warningf(&statement->base.source_position, - "function returns address of local variable"); + warningf(pos, "function returns address of local variable"); } } } else if (warning.other && !is_type_atomic(return_type, ATOMIC_TYPE_VOID)) { - warningf(&statement->base.source_position, - "'return' without value, in function returning non-void"); + /* ISO/IEC 14882:1998(E) §6.6.3:3 */ + if (c_mode & _CXX || strict_mode) { + errorf(pos, + "'return' without value, in function returning non-void"); + } else { + warningf(pos, + "'return' without value, in function returning non-void"); + } } statement->returns.value = return_value;