- BugFix: GCC allows arithmetic on function pointers
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sun, 31 Aug 2008 11:32:13 +0000 (11:32 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sun, 31 Aug 2008 11:32:13 +0000 (11:32 +0000)
- implemented -Wpointer-arith

[r21579]

ast2firm.c
parser.c
warning.c
warning.h

index 6735e32..09f48fd 100644 (file)
@@ -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;
        }
 
index f9920b8..e751e1d 100644 (file)
--- 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;
 }
 
index 7329731..375e2c2 100644 (file)
--- 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);
index 431dbd3..e156c40 100644 (file)
--- 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 */