===================================================================
@@ -249,7 +249,7 @@ Objective-C and Objective-C++ Dialects}.
-Wmain -Wmissing-braces -Wmissing-field-initializers @gol
-Wmissing-format-attribute -Wmissing-include-dirs @gol
-Wno-mudflap @gol
--Wno-multichar -Wnonnull -Wno-overflow @gol
+-Wno-multichar -Wnonnull -Wno-overflow @gol -Wmisaligned
-Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded @gol
-Wparentheses -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
-Wpointer-arith -Wno-pointer-to-int-cast @gol
@@ -4317,6 +4317,25 @@ struct bar @{
@end group
@end smallexample
+@item -Wmisaligned
+@opindex Wmisaligned
+@opindex Wno-misaligned
+Warn if an expression can cause misalignment. Commonly it is useful
+for vector operations. If you cast a misaligned memory to a vector
+type it is possible to end up with a segmentation fault. Like in
+the following example.
+
+@smallexample
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+int *array;
+vector (4, int) vec;
+
+array = (int *) malloc (128 * sizeof (int));
+*((vector (4, int) *) &array[1]) = vec;
+@end smallexample
+
@item -Wpacked-bitfield-compat
@opindex Wpacked-bitfield-compat
@opindex Wno-packed-bitfield-compat
===================================================================
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -Wmisaligned" } */
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+typedef int unaligned_intv __attribute__((vector_size(16), aligned(4)));
+
+vector (4, int) *
+loadu (int *p) {
+ return (unaligned_intv *)p; /* { dg-warning "" } */
+}
+
+
+int main (int argc, char *argv[]) {
+ int * array;
+ vector (4, int) v = {argc, 1,2,3};
+
+ array = (int *) __builtin_malloc (137 * sizeof (int));
+ *((vector(4, int) *)(1+ array)) = v; /* { dg-warning "" } */
+ *(loadu (&array[0])) = v;
+
+ return array[argc];
+}
+
+
===================================================================
@@ -4674,6 +4674,17 @@ build_c_cast (location_t loc, tree type,
OPT_Wint_to_pointer_cast, "cast to pointer from integer "
"of different size");
+ if (TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (type)) == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+ {
+ if (TYPE_ALIGN (TREE_TYPE (type))
+ > MAX (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))),
+ get_pointer_alignment (expr, 0)))
+ warning_at (loc, OPT_Wmisaligned,
+ "Possible vector-pointer missaligned cast");
+ }
+
if (warn_strict_aliasing <= 2)
strict_aliasing_warning (otype, type, expr);
===================================================================
@@ -176,6 +176,10 @@ Wpacked
Common Var(warn_packed) Warning
Warn when the packed attribute has no effect on struct layout
+Wmisaligned
+Common Var(warn_misaligned) Warning
+Warn about possible misalignments
+
Wpadded
Common Var(warn_padded) Warning
Warn when padding is required to align structure members
===================================================================
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.
#include "tree-pass.h"
#include "flags.h"
#include "ggc.h"
+#include "diagnostic.h"
/* Need to include rtl.h, expr.h, etc. for optabs. */
#include "expr.h"
@@ -383,6 +384,67 @@ type_for_widest_vector_mode (enum machin
}
}
+
+/* Cache the location for not giving a warning more than once per line. */
+static location_t loc_cache = UNKNOWN_LOCATION;
+
+/* Show warning if alignemnt in vector assignment or alignment in
+ vector-type mem_ref is incorrect. Works only when optimized == 1 */
+static void
+check_alignment (gimple_stmt_iterator *gsi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+ tree lhs, rhs, rtype;
+ location_t loc = gimple_location (stmt);
+
+ if (optimize == 0)
+ return;
+
+ if (gimple_assign_single_p (stmt))
+ {
+ lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
+ rtype = TREE_TYPE (rhs);
+
+ if (TREE_CODE (rhs) == MEM_REF
+ && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
+ {
+ if (TYPE_ALIGN (TREE_TYPE (rhs))
+ > get_object_alignment (rhs, BIGGEST_ALIGNMENT)
+ && loc_cache != loc)
+ warning_at (loc_cache = loc, OPT_Wmisaligned,
+ "Possibly misaligned vector-type memory refernce "
+ "on the assignment right hand side");
+ }
+ }
+ else
+ return;
+
+ if (TREE_CODE (lhs) == MEM_REF
+ && TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
+ {
+ if (TYPE_ALIGN (TREE_TYPE (lhs))
+ > get_object_alignment (lhs, BIGGEST_ALIGNMENT)
+ && loc_cache != loc)
+ warning_at (loc_cache = loc, OPT_Wmisaligned,
+ "Possibly misaligned vector-type memory reference");
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (lhs))
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (lhs))) == VECTOR_TYPE)
+ {
+ if (TREE_CODE (rhs) == ADDR_EXPR
+ && TREE_CODE (TREE_TYPE (rtype)) == VECTOR_TYPE)
+ {
+ if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (lhs)))
+ > get_pointer_alignment (rhs, BIGGEST_ALIGNMENT)
+ && loc_cache != loc)
+ warning_at (loc_cache = loc, OPT_Wmisaligned,
+ "Possibly misalignment vector-pointer assignment");
+ }
+ }
+}
+
/* Process one statement. If we identify a vector operation, expand it. */
static void
@@ -396,6 +458,8 @@ expand_vector_operations_1 (gimple_stmt_
enum gimple_rhs_class rhs_class;
tree new_rhs;
+ check_alignment (gsi);
+
if (gimple_code (stmt) != GIMPLE_ASSIGN)
return;
===================================================================
@@ -3156,7 +3156,7 @@ tree-vect-generic.o : tree-vect-generic.
$(TM_H) $(TREE_FLOW_H) $(GIMPLE_H) tree-iterator.h $(TREE_PASS_H) \
$(FLAGS_H) $(OPTABS_H) $(MACHMODE_H) $(EXPR_H) \
langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \
- coretypes.h insn-codes.h
+ coretypes.h insn-codes.h diagnostic.h
df-core.o : df-core.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) $(FUNCTION_H) $(REGS_H) alloc-pool.h \
hard-reg-set.h $(BASIC_BLOCK_H) $(DF_H) $(BITMAP_H) sbitmap.h $(TIMEVAR_H) \
===================================================================
@@ -60,7 +60,19 @@ convert_to_pointer (tree type, tree expr
addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (type));
addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
- if (to_as == from_as)
+ if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == VECTOR_TYPE)
+ {
+ /* Check whether implicit vector conversion preserves
+ alignment. */
+ if (TREE_CODE (type) == POINTER_TYPE
+ && TYPE_ALIGN (TREE_TYPE (type))
+ > MAX (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (expr))),
+ get_pointer_alignment (expr, 0)))
+ warning_at (loc, OPT_Wmisaligned,
+ "Possible vector-pointer missaligned cast");
+ }
+
+ if (to_as == from_as)
return fold_build1_loc (loc, NOP_EXPR, type, expr);
else
return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);