Harald van Dijk <truedfx@xxxxxxxxxx> writes: > int main() { > int a = 1; > short *b = (short *) (char *) &a; > *b = 2; > return a; > } > > This simple program returns 1 when compiled with -O2 > -fstrict-aliasing, and 2 when compiled with -O2 > -fno-strict-aliasing. It does not produce any warnings with > -Wstrict-aliasing=2. According to the documentation: > > `-Wstrict-aliasing=2' > This option is only active when `-fstrict-aliasing' is active. It > warns about all code which might break the strict aliasing rules > that the compiler is using for optimization. This warning catches > all cases, but it will also give a warning for some ambiguous > cases that are safe. > > Is this a bug? If so, what is the bug? Is the warning missing, or is > the optimization invalid? And are there any alternative options that > really catch every aliasing problem? There should be a warning here. The warning code is confused by the double cast. If you cast directly to short *, you should get the warning. I'm going to test this patch to fix this problem. Anybody see anything wrong with it? Ian 2005-07-26 Ian Lance Taylor <ian@xxxxxxxx> * c-typeck.c (build_c_cast): For warn_strict_aliasing warnings, use STRIP_NOPS on the operand. Index: c-typeck.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v retrieving revision 1.467 diff -p -c -r1.467 c-typeck.c *** c-typeck.c 20 Jul 2005 01:18:06 -0000 1.467 --- c-typeck.c 27 Jul 2005 02:36:51 -0000 *************** build_c_cast (tree type, tree expr) *** 3306,3334 **** 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"); } } --- 3306,3341 ---- if (flag_strict_aliasing && warn_strict_aliasing && TREE_CODE (type) == POINTER_TYPE ! && TREE_CODE (otype) == POINTER_TYPE) ! { ! tree e = expr; ! STRIP_NOPS (e); ! if (TREE_CODE (e) == ADDR_EXPR ! && (DECL_P (TREE_OPERAND (e, 0)) ! || TREE_CODE (TREE_OPERAND (e, 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, set2; ! ! set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (e, 0))); ! 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"); ! } } }