Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 251617) +++ gcc/c/c-typeck.c (working copy) @@ -5578,7 +5578,7 @@ build_c_cast (location_t loc, tree type, } /* Warn about possible alignment problems. */ - if (STRICT_ALIGNMENT + if ((STRICT_ALIGNMENT || warn_cast_align == 2) && TREE_CODE (type) == POINTER_TYPE && TREE_CODE (otype) == POINTER_TYPE && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE @@ -5587,7 +5587,8 @@ build_c_cast (location_t loc, tree type, restriction is unknown. */ && !(RECORD_OR_UNION_TYPE_P (TREE_TYPE (otype)) && TYPE_MODE (TREE_TYPE (otype)) == VOIDmode) - && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) + && min_align_of_type (TREE_TYPE (type)) + > min_align_of_type (TREE_TYPE (otype))) warning_at (loc, OPT_Wcast_align, "cast increases required alignment of target type"); Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 251617) +++ gcc/common.opt (working copy) @@ -564,6 +564,10 @@ Wcast-align Common Var(warn_cast_align) Warning Warn about pointer casts which increase alignment. +Wcast-align=strict +Common Var(warn_cast_align,2) Warning +Warn about pointer casts which increase alignment. + Wcpp Common Var(warn_cpp) Init(1) Warning Warn when a #warning directive is encountered. Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 251617) +++ gcc/cp/typeck.c (working copy) @@ -7265,15 +7265,16 @@ build_reinterpret_cast_1 (tree type, tre complain)) return error_mark_node; /* Warn about possible alignment problems. */ - if (STRICT_ALIGNMENT && warn_cast_align - && (complain & tf_warning) + if ((STRICT_ALIGNMENT || warn_cast_align == 2) + && (complain & tf_warning) && !VOID_TYPE_P (type) && TREE_CODE (TREE_TYPE (intype)) != FUNCTION_TYPE && COMPLETE_TYPE_P (TREE_TYPE (type)) && COMPLETE_TYPE_P (TREE_TYPE (intype)) - && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (intype))) + && min_align_of_type (TREE_TYPE (type)) + > min_align_of_type (TREE_TYPE (intype))) warning (OPT_Wcast_align, "cast from %qH to %qI " - "increases required alignment of target type", intype, type); + "increases required alignment of target type", intype, type); /* We need to strip nops here, because the front end likes to create (int *)&a for array-to-pointer decay, instead of &a[0]. */ @@ -7447,6 +7448,14 @@ build_const_cast_1 (tree dst_type, tree the user is making a potentially unsafe cast. */ check_for_casting_away_constness (src_type, dst_type, CAST_EXPR, complain); + /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN. */ + if ((STRICT_ALIGNMENT || warn_cast_align == 2) + && (complain & tf_warning) + && min_align_of_type (TREE_TYPE (dst_type)) + > min_align_of_type (TREE_TYPE (src_type))) + warning (OPT_Wcast_align, "cast from %qH to %qI " + "increases required alignment of target type", + src_type, dst_type); } if (reference_type) { Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 251617) +++ gcc/doc/invoke.texi (working copy) @@ -266,7 +266,8 @@ Objective-C and Objective-C++ Dialects}. -Wno-attributes -Wbool-compare -Wbool-operation @gol -Wno-builtin-declaration-mismatch @gol -Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol --Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol +-Wc++-compat -Wc++11-compat -Wc++14-compat @gol +-Wcast-align -Wcast-align=strict -Wcast-qual @gol -Wchar-subscripts -Wchkp -Wcatch-value -Wcatch-value=@var{n} @gol -Wclobbered -Wcomment -Wconditionally-supported @gol -Wconversion -Wcoverage-mismatch -Wno-cpp -Wdangling-else -Wdate-time @gol @@ -5923,6 +5924,12 @@ target is increased. For example, warn if a @code an @code{int *} on machines where integers can only be accessed at two- or four-byte boundaries. +@item -Wcast-align=strict +@opindex Wcast-align=strict +Warn whenever a pointer is cast such that the required alignment of the +target is increased. For example, warn if a @code{char *} is cast to +an @code{int *} regardless of the target machine. + @item -Wwrite-strings @opindex Wwrite-strings @opindex Wno-write-strings Index: gcc/testsuite/c-c++-common/Wcast-align.c =================================================================== --- gcc/testsuite/c-c++-common/Wcast-align.c (revision 0) +++ gcc/testsuite/c-c++-common/Wcast-align.c (working copy) @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Wcast-align=strict" } */ + +typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c; +typedef struct __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) +{ + char x; +} d; + +char *x; +c *y; +d *z; +struct s { long long x; } *p; +struct t { double x; } *q; + +void +foo (void) +{ + y = (c *) x; /* { dg-warning "alignment" } */ + z = (d *) x; /* { dg-warning "alignment" } */ + (long long *) p; /* { dg-bogus "alignment" } */ + (double *) q; /* { dg-bogus "alignment" } */ +}