summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-24 10:48:15 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2005-11-24 10:48:15 +0000
commitbcf223713db30eae936f8aaea769646d47a41cfc (patch)
tree2423af056692fa5b5f531ef395833a9a44b629dd /gcc/c-common.c
parente2ac3a1833dd076e8f8f1bc172b16e44542ff12f (diff)
downloadgcc-bcf223713db30eae936f8aaea769646d47a41cfc.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107459 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index b843df25935..82fe6131c1d 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). */