summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorSilvius Rus <rus@google.com>2007-05-11 16:20:08 +0000
committerSilvius Rus <rus@gcc.gnu.org>2007-05-11 16:20:08 +0000
commit79bedddc8fed70d3ebbab016aae285bac9dbbfea (patch)
treef0873ca8d26c98fe6770ac353fa336c975e5e22a /gcc/c-common.c
parent8339896e55eb0538ddf35cb22f7de5b5b126259c (diff)
downloadgcc-79bedddc8fed70d3ebbab016aae285bac9dbbfea.tar.gz
Makefile.in (OBJS-common): Add tree-ssa-alias-warnings.o.
gcc/ * Makefile.in (OBJS-common): Add tree-ssa-alias-warnings.o. * c-common.c (strict_aliasing_warning): Modify -Wstrict-aliasing logic. * c-common.h (strict_aliasing_warning): Change return type. * c-opts.c (c_common_handle_option): Add call to set_Wstrict_aliasing. * c-typeck.c (build_indirect_ref): Add call to strict_aliasing_warning. (build_c_cast): Condition call to strict_aliasing_warning. * doc/invoke.texi: Update description of -Wstrict-aliasing[=n]. * flags.h (set_Wstrict_aliasing): Declare. * opts.c (set_Wstrict_alising): Define, add call to. * tree-flow.h (strict_aliasing_warning_backend): Declare. * tree-ssa-alias-warnings.c: New file. * tree-ssa-alias.c (compute_may_aliases): Add call to strict_aliasing_warning_backend. gcc/cp * cp/typeck.c (build_indirect_ref): Add call to strict_aliasing_warning. (build_reinterpret_cast_1): Condition call to strict_aliasing_warning. gcc/testsuite * gcc.dg/Wstrict-aliasing-bogus-const-ptr-nonconst-ptr.c: New test. * gcc.dg/Wstrict-aliasing-bogus-never-dereferenced.c: New test. * gcc.dg/Wstrict-aliasing-bogus-struct-included.c: New test. * gcc.dg/Wstrict-aliasing-converted-assigned.c: New test. * gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c: New test. * gcc.dg/alias-1.c: Update option: -Wstrict-aliasing=2. * gcc.dg/alias-9.c: Update option: -Wstrict-aliasing=2. * g++.dg/warn/Wstrict-aliasing-7.C: Update option: -Wstrict-aliasing=2. * g++.dg/warn/Wstrict-aliasing-bogus-base-derived.C: New test. * g++.dg/warn/Wstrict-aliasing-bogus-char-1.C: New test. * g++.dg/warn/Wstrict-aliasing-bogus-const.C: New test. * g++.dg/warn/Wstrict-aliasing-bogus-nested-arrays.C: New test. * g++.dg/warn/Wstrict-aliasing-bogus-signed-unsigned.C: New test. * g++.dg/warn/Wstrict-aliasing-bogus-struct-included.C: New test. * g++.dg/warn/Wstrict-aliasing-bogus-union.C: New test. * g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C: New test. From-SVN: r124622
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index f93cac5f696..17a0067378e 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1014,35 +1014,67 @@ warn_logical_operator (enum tree_code code, tree arg1, tree
strict aliasing mode is in effect. OTYPE is the original
TREE_TYPE of EXPR, and TYPE the type we're casting to. */
-void
+bool
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
+ if (!(flag_strict_aliasing && POINTER_TYPE_P (type)
+ && POINTER_TYPE_P (otype) && !VOID_TYPE_P (TREE_TYPE (type))))
+ return false;
+
+ if ((warn_strict_aliasing > 1) && TREE_CODE (expr) == ADDR_EXPR
&& (DECL_P (TREE_OPERAND (expr, 0))
- || handled_component_p (TREE_OPERAND (expr, 0)))
- && !VOID_TYPE_P (TREE_TYPE (type)))
+ || handled_component_p (TREE_OPERAND (expr, 0))))
{
/* 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");
+ if (!COMPLETE_TYPE_P (TREE_TYPE (type)) && warn_strict_aliasing == 2)
+ {
+ warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
+ "might break strict-aliasing rules");
+ return true;
+ }
else
{
- HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ /* warn_strict_aliasing >= 3. This includes the default (3).
+ Only warn if the cast is dereferenced immediately. */
+ 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");
+ {
+ warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+ "pointer will break strict-aliasing rules");
+ return true;
+ }
+ else if (warn_strict_aliasing == 2
+ && !alias_sets_might_conflict_p (set1, set2))
+ {
+ warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+ "pointer might break strict-aliasing rules");
+ return true;
+ }
}
}
+ else
+ if ((warn_strict_aliasing == 1) && !VOID_TYPE_P (TREE_TYPE (otype)))
+ {
+ /* At this level, warn for any conversions, even if an address is
+ not taken in the same statement. This will likely produce many
+ false positives, but could be useful to pinpoint problems that
+ are not revealed at higher levels. */
+ HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (otype));
+ HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
+ if (!COMPLETE_TYPE_P(type)
+ || !alias_sets_might_conflict_p (set1, set2))
+ {
+ warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
+ "pointer might break strict-aliasing rules");
+ return true;
+ }
+ }
+
+ return false;
}
/* Print a warning about if (); or if () .. else; constructs