diff options
author | Richard Guenther <rguenther@suse.de> | 2005-11-24 10:48:15 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2005-11-24 10:48:15 +0000 |
commit | de9c56a4dc72cbf510064de22950ef44835701c7 (patch) | |
tree | 2423af056692fa5b5f531ef395833a9a44b629dd /gcc | |
parent | 349d23dd85821238f764ac9868dcd32fc50db5a9 (diff) | |
download | gcc-de9c56a4dc72cbf510064de22950ef44835701c7.zip gcc-de9c56a4dc72cbf510064de22950ef44835701c7.tar.gz gcc-de9c56a4dc72cbf510064de22950ef44835701c7.tar.bz2 |
re PR c++/14024 (g++ isn't reporting aliasing warnings)
2005-11-24 Richard Guenther <rguenther@suse.de>
Dirk Mueller <dmueller@suse.de>
PR c++/14024
* c-common.h (strict_aliasing_warning): Declare.
* c-common.c (strict_aliasing_warning): New function,
split out from ...
* c-typeck.c (build_c_cast): ... here.
* typeck.c (build_reinterpret_cast_1): Use it.
* g++.dg/warn/Wstrict-aliasing-1.C: New testcase.
* g++.dg/warn/Wstrict-aliasing-2.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-3.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-4.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-5.C: Likewise.
* g++.dg/warn/Wstrict-aliasing-6.C: Likewise.
Co-Authored-By: Dirk Mueller <dmueller@suse.de>
From-SVN: r107459
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-common.c | 36 | ||||
-rw-r--r-- | gcc/c-common.h | 1 | ||||
-rw-r--r-- | gcc/c-typeck.c | 28 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C | 9 |
13 files changed, 139 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c983bce..2efba8c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-11-24 Richard Guenther <rguenther@suse.de> + Dirk Mueller <dmueller@suse.de> + + PR c++/14024 + * c-common.h (strict_aliasing_warning): Declare. + * c-common.c (strict_aliasing_warning): New function, + split out from ... + * c-typeck.c (build_c_cast): ... here. + 2005-11-24 Paolo Bonzini <bonzini@gnu.org> * optabs.c (expand_binop): Use swap_commutative_operands_with_target diff --git a/gcc/c-common.c b/gcc/c-common.c index b843df2..82fe613 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -954,6 +954,42 @@ unsigned_conversion_warning (tree result, tree operand) } } +/* Print a warning about casts that might indicate violation + of strict aliasing rules if -Wstrict-aliasing is used and + strict aliasing mode is in effect. otype is the original + TREE_TYPE of expr, and type the type we're casting to. */ + +void +strict_aliasing_warning(tree otype, tree type, tree expr) +{ + if (flag_strict_aliasing && warn_strict_aliasing + && POINTER_TYPE_P (type) && POINTER_TYPE_P (otype) + && TREE_CODE (expr) == ADDR_EXPR + && (DECL_P (TREE_OPERAND (expr, 0)) + || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF) + && !VOID_TYPE_P (TREE_TYPE (type))) + { + /* Casting the address of an object to non void pointer. Warn + if the cast breaks type based aliasing. */ + if (!COMPLETE_TYPE_P (TREE_TYPE (type))) + warning (OPT_Wstrict_aliasing, "type-punning to incomplete type " + "might break strict-aliasing rules"); + else + { + HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))); + HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type)); + + if (!alias_sets_conflict_p (set1, set2)) + warning (OPT_Wstrict_aliasing, "dereferencing type-punned " + "pointer will break strict-aliasing rules"); + else if (warn_strict_aliasing > 1 + && !alias_sets_might_conflict_p (set1, set2)) + warning (OPT_Wstrict_aliasing, "dereferencing type-punned " + "pointer might break strict-aliasing rules"); + } + } +} + /* Nonzero if constant C has a value that is permissible for type TYPE (an INTEGER_TYPE). */ diff --git a/gcc/c-common.h b/gcc/c-common.h index 96905af..c78f462 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -649,6 +649,7 @@ extern void binary_op_error (enum tree_code); extern tree fix_string_type (tree); struct varray_head_tag; extern void constant_expression_warning (tree); +extern void strict_aliasing_warning(tree, tree, tree); extern tree convert_and_check (tree, tree); extern void overflow_warning (tree); extern void unsigned_conversion_warning (tree, tree); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 2150238..735d9e7 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3441,33 +3441,7 @@ build_c_cast (tree type, tree expr) warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer " "of different size"); - if (flag_strict_aliasing && warn_strict_aliasing - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (expr) == ADDR_EXPR - && (DECL_P (TREE_OPERAND (expr, 0)) - || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF) - && !VOID_TYPE_P (TREE_TYPE (type))) - { - /* Casting the address of an object to non void pointer. Warn - if the cast breaks type based aliasing. */ - if (!COMPLETE_TYPE_P (TREE_TYPE (type))) - warning (OPT_Wstrict_aliasing, "type-punning to incomplete type " - "might break strict-aliasing rules"); - else - { - HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))); - HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type)); - - if (!alias_sets_conflict_p (set1, set2)) - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer will break strict-aliasing rules"); - else if (warn_strict_aliasing > 1 - && !alias_sets_might_conflict_p (set1, set2)) - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer might break strict-aliasing rules"); - } - } + strict_aliasing_warning (otype, type, expr); /* If pedantic, warn for conversions between function and object pointer types, except for converting a null pointer constant diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 046d049..dbf3330 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-11-24 Richard Guenther <rguenther@suse.de> + Dirk Mueller <dmueller@suse.de> + + PR c++/14024 + * typeck.c (build_reinterpret_cast_1): Use + strict_aliasing_warning. + 2005-11-23 Gabriel Dos Reis <gdr@integrable-solutions.net> PR c++/24235 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b3c155a..60ef195 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5011,6 +5011,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype))) { + tree sexpr = expr; + if (!c_cast_p) check_for_casting_away_constness (intype, type, error, "reinterpret_cast"); @@ -5025,6 +5027,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, "target type", intype, type); + /* We need to strip nops here, because the frontend likes to + create (int *)&a for array-to-pointer decay, instead of &a[0]. */ + STRIP_NOPS (sexpr); + strict_aliasing_warning (intype, type, sexpr); + return fold_if_not_in_template (build_nop (type, expr)); } else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9ed97b8..d2bc993 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2005-11-24 Richard Guenther <rguenther@suse.de> + Dirk Mueller <dmueller@suse.de> + + PR c++/14024 + * g++.dg/warn/Wstrict-aliasing-1.C: New testcase. + * g++.dg/warn/Wstrict-aliasing-2.C: Likewise. + * g++.dg/warn/Wstrict-aliasing-3.C: Likewise. + * g++.dg/warn/Wstrict-aliasing-4.C: Likewise. + * g++.dg/warn/Wstrict-aliasing-5.C: Likewise. + * g++.dg/warn/Wstrict-aliasing-6.C: Likewise. + 2005-11-23 Uros Bizjak <uros@kss-loka.si> * g++.dg/other/i386-1.C: Pass if CPU has no SSE2 support. diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C new file mode 100644 index 0000000..3e9db36 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Wstrict-aliasing=2 -O2" } */ + +double x; +int *foo(void) +{ + return (int *)&x; /* { dg-warning "strict-aliasing" } */ +} + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C new file mode 100644 index 0000000..713b354 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Wstrict-aliasing=2 -O2" } */ + +double x; + +template <typename T> +T *foo(void) +{ + return (T *)&x; /* { dg-bogus "strict-aliasing" } */ +} + +template double *foo<double>(void); + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C new file mode 100644 index 0000000..9fc3538 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-Wstrict-aliasing=2 -O2" } */ + +double x; + +template <typename T> +T *foo(void) +{ + return (T *)&x; /* { dg-warning "strict-aliasing" } */ +} + +template int *foo<int>(void); /* { dg-warning "instantiated from here" } */ +template char *foo<char>(void); /* { dg-bogus "instantiated from here" } */ + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C new file mode 100644 index 0000000..e877c70 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Wstrict-aliasing=2 -O2" } */ + +double x; + +template <typename T> +T *foo(void) +{ + int a[2]; + float *y = (float *)a; /* { dg-bogus "strict-aliasing" } */ + return (T *)&x; /* { dg-bogus "strict-aliasing" } */ +} + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C new file mode 100644 index 0000000..a049251 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Wstrict-aliasing=2 -O2" } */ + +float foo () +{ + unsigned int MASK = 0x80000000; + return (float &) MASK; /* { dg-warning "strict-aliasing" } */ +} + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C new file mode 100644 index 0000000..6f935c8 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-Wstrict-aliasing=2 -O2" } */ + +int foo () +{ + char buf[8]; + return *((int *)buf); /* { dg-warning "strict-aliasing" } */ +} + |