aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-common.c36
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/c-typeck.c28
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-1.C9
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-2.C13
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-3.C14
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-4.C13
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-5.C9
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-6.C9
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" } */
+}
+