re PR c++/14024 (g++ isn't reporting aliasing warnings)

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.

	* typeck.c (build_reinterpret_cast_1): Use it.

	* 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.

Co-Authored-By: Dirk Mueller <dmueller@suse.de>

From-SVN: r107459
This commit is contained in:
Richard Guenther 2005-11-24 10:48:15 +00:00 committed by Richard Biener
parent 349d23dd85
commit de9c56a4dc
13 changed files with 139 additions and 27 deletions

View File

@ -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

View File

@ -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). */

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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.

View File

@ -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" } */
}

View File

@ -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);

View File

@ -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" } */

View File

@ -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" } */
}

View File

@ -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" } */
}

View File

@ -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" } */
}