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/c-common.c | |
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/c-common.c')
-rw-r--r-- | gcc/c-common.c | 36 |
1 files changed, 36 insertions, 0 deletions
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). */ |