From da1c2bddeba34326ef288302e4f7129584041df1 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Sun, 31 Aug 2008 11:32:13 +0000 Subject: [PATCH] - BugFix: GCC allows arithmetic on function pointers - implemented -Wpointer-arith [r21579] --- ast2firm.c | 6 ++++-- parser.c | 25 ++++++++++++++++++------- warning.c | 3 +++ warning.h | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/ast2firm.c b/ast2firm.c index 6735e32..09f48fd 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -2151,8 +2151,10 @@ static ir_node *adjust_for_pointer_arithmetic(dbg_info *dbgi, type_t *const points_to = skip_typeref(pointer_type->points_to); unsigned elem_size = get_type_size_const(points_to); - /* gcc extension */ - if (elem_size == 0 && is_type_atomic(points_to, ATOMIC_TYPE_VOID)) { + /* gcc extension: allow arithmetic with void * and function * */ + if (elem_size == 0 && + (is_type_atomic(points_to, ATOMIC_TYPE_VOID) || + is_type_function(points_to))) { elem_size = 1; } diff --git a/parser.c b/parser.c index f9920b8..e751e1d 100644 --- a/parser.c +++ b/parser.c @@ -6998,18 +6998,29 @@ static bool check_pointer_arithmetic(const source_position_t *source_position, points_to = skip_typeref(points_to); if (is_type_incomplete(points_to) && - (! (c_mode & _GNUC) - || !is_type_atomic(points_to, ATOMIC_TYPE_VOID))) { + !((c_mode & _GNUC) + && is_type_atomic(points_to, ATOMIC_TYPE_VOID))) { errorf(source_position, - "arithmetic with pointer to incomplete type '%T' not allowed", - orig_pointer_type); + "arithmetic with pointer to incomplete type '%T' not allowed", + orig_pointer_type); return false; - } else if (is_type_function(points_to)) { + } else if (!(c_mode & _GNUC) && is_type_function(points_to)) { errorf(source_position, - "arithmetic with pointer to function type '%T' not allowed", - orig_pointer_type); + "arithmetic with pointer to function type '%T' not allowed", + orig_pointer_type); return false; } + if (warning.pointer_arith) { + if (is_type_atomic(points_to, ATOMIC_TYPE_VOID)) { + warningf(source_position, + "pointer of type '%T' used in arithmetic", + orig_pointer_type); + } else if (is_type_function(points_to)) { + warningf(source_position, + "pointer to a function '%T' used in arithmetic", + orig_pointer_type); + } + } return true; } diff --git a/warning.c b/warning.c index 7329731..375e2c2 100644 --- a/warning.c +++ b/warning.c @@ -41,6 +41,7 @@ warning_t warning = { .nested_externs = false, .nonnull = true, .redundant_decls = true, + .pointer_arith = true, .return_type = true, .s_are_errors = false, .shadow = false, @@ -84,6 +85,7 @@ void set_warning_opt(const char *const opt) SET(main); SET(nonnull); SET(redundant_decls); + SET(pointer_arith); SET(return_type); SET(shadow); SET(sign_compare); @@ -133,6 +135,7 @@ void set_warning_opt(const char *const opt) OPT("nested-externs", nested_externs); OPT("nonnull", nonnull); OPT("redundant-decls", redundant_decls); + OPT("pointer_arith", pointer_arith); OPT("return-type", return_type); OPT("shadow", shadow); OPT("sign-compare", sign_compare); diff --git a/warning.h b/warning.h index 431dbd3..e156c40 100644 --- a/warning.h +++ b/warning.h @@ -71,8 +71,8 @@ typedef struct warning_t { bool packed:1; /**< Warn if a structure is given the packed attribute, but the packed attribute has no effect on the layout or size of the structure */ bool padded:1; /**< Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure */ bool parentheses:1; /**< Warn if parentheses are omitted in certain contexts (assignment where truth value is expected, if-else-braces) */ - bool pointer_arith:1; /**< Warn about anything that depends on the "size of" a function type or of 'void' */ #endif + bool pointer_arith:1; /**< Warn about anything that depends on the "size of" a function type or of 'void' */ bool redundant_decls:1; /**< Warn about redundant declarations */ bool return_type:1; /* TODO not fully implemented */ /**< Warn about function definitions with a return-type that defaults to 'int'. Also warn about any 'return' statement with no return-value in a function whose return-type is not 'void'. */ bool s_are_errors:1; /**< Treat warnings as errors */ -- 2.20.1