Commit 03ca8fb3 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/69922 (Bogus -Wnonnull-compare for: ... ? static_cast<T*>(this) : nullptr)

	PR c++/69922
	* class.c (build_base_path): Set TREE_NO_WARNING on the null_test.
	Avoid folding it.
	* init.c (build_vec_delete_1, build_delete): Don't fold the non-NULL
	tests.
	* cp-gimplify.c (cp_fold): For TREE_NO_WARNING comparisons with NULL,
	unless they are folded into INTEGER_CST, error_mark_node or some
	comparison with NULL, avoid folding them and use either the original
	comparison or non-folded comparison of folded arguments.
	* cp-ubsan.c (cp_ubsan_instrument_vptr): Set TREE_NO_WARNING on the
	comparison, don't fold the comparison right away.

	* g++.dg/warn/Wnonnull-compare-6.C: New test.
	* g++.dg/warn/Wnonnull-compare-7.C: New test.
	* g++.dg/ubsan/pr69922.C: New test.

From-SVN: r233684
parent 0b05329b
2016-02-24 Jakub Jelinek <jakub@redhat.com>
PR c++/69922
* class.c (build_base_path): Set TREE_NO_WARNING on the null_test.
Avoid folding it.
* init.c (build_vec_delete_1, build_delete): Don't fold the non-NULL
tests.
* cp-gimplify.c (cp_fold): For TREE_NO_WARNING comparisons with NULL,
unless they are folded into INTEGER_CST, error_mark_node or some
comparison with NULL, avoid folding them and use either the original
comparison or non-folded comparison of folded arguments.
* cp-ubsan.c (cp_ubsan_instrument_vptr): Set TREE_NO_WARNING on the
comparison, don't fold the comparison right away.
2016-02-24 Jason Merrill <jason@redhat.com>
PR c++/69323
......
......@@ -392,8 +392,11 @@ build_base_path (enum tree_code code,
if (null_test)
{
tree zero = cp_convert (TREE_TYPE (expr), nullptr_node, complain);
null_test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
expr, zero);
null_test = build2_loc (input_location, NE_EXPR, boolean_type_node,
expr, zero);
/* This is a compiler generated comparison, don't emit
e.g. -Wnonnull-compare warning for it. */
TREE_NO_WARNING (null_test) = 1;
}
/* If this is a simple base reference, express it as a COMPONENT_REF. */
......
......@@ -2069,8 +2069,24 @@ cp_fold (tree x)
x = fold (x);
if (TREE_NO_WARNING (org_x)
&& TREE_CODE (x) == TREE_CODE (org_x))
TREE_NO_WARNING (x) = 1;
&& warn_nonnull_compare
&& COMPARISON_CLASS_P (org_x))
{
if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
;
else if (COMPARISON_CLASS_P (x))
TREE_NO_WARNING (x) = 1;
/* Otherwise give up on optimizing these, let GIMPLE folders
optimize those later on. */
else if (op0 != TREE_OPERAND (org_x, 0)
|| op1 != TREE_OPERAND (org_x, 1))
{
x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
TREE_NO_WARNING (x) = 1;
}
else
x = org_x;
}
break;
case VEC_COND_EXPR:
......
......@@ -70,10 +70,15 @@ cp_ubsan_instrument_vptr (location_t loc, tree op, tree type, bool is_addr,
vptr = fold_convert_loc (loc, pointer_sized_int_node, vptr);
vptr = fold_convert_loc (loc, uint64_type_node, vptr);
if (ckind == UBSAN_DOWNCAST_POINTER)
vptr = fold_build3 (COND_EXPR, uint64_type_node,
fold_build2 (NE_EXPR, boolean_type_node, op,
build_zero_cst (TREE_TYPE (op))),
vptr, build_int_cst (uint64_type_node, 0));
{
tree cond = build2_loc (loc, NE_EXPR, boolean_type_node, op,
build_zero_cst (TREE_TYPE (op)));
/* This is a compiler generated comparison, don't emit
e.g. -Wnonnull-compare warning for it. */
TREE_NO_WARNING (cond) = 1;
vptr = build3_loc (loc, COND_EXPR, uint64_type_node, cond,
vptr, build_int_cst (uint64_type_node, 0));
}
tree ti_decl = get_tinfo_decl (type);
mark_used (ti_decl);
tree ptype = build_pointer_type (type);
......
......@@ -3678,15 +3678,13 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
body = integer_zero_node;
/* Outermost wrapper: If pointer is null, punt. */
tree cond
= fold_build2_loc (input_location, NE_EXPR, boolean_type_node, base,
fold_convert (TREE_TYPE (base), nullptr_node));
tree cond = build2_loc (input_location, NE_EXPR, boolean_type_node, base,
fold_convert (TREE_TYPE (base), nullptr_node));
/* This is a compiler generated comparison, don't emit
e.g. -Wnonnull-compare warning for it. */
if (TREE_CODE (cond) == NE_EXPR)
TREE_NO_WARNING (cond) = 1;
body = fold_build3_loc (input_location, COND_EXPR, void_type_node,
cond, body, integer_zero_node);
TREE_NO_WARNING (cond) = 1;
body = build3_loc (input_location, COND_EXPR, void_type_node,
cond, body, integer_zero_node);
body = build1 (NOP_EXPR, void_type_node, body);
if (controller)
......@@ -4523,9 +4521,8 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
{
/* Handle deleting a null pointer. */
warning_sentinel s (warn_address);
ifexp = fold (cp_build_binary_op (input_location,
NE_EXPR, addr, nullptr_node,
complain));
ifexp = cp_build_binary_op (input_location, NE_EXPR, addr,
nullptr_node, complain);
if (ifexp == error_mark_node)
return error_mark_node;
/* This is a compiler generated comparison, don't emit
......
2016-02-24 Jakub Jelinek <jakub@redhat.com>
PR c++/69922
* g++.dg/warn/Wnonnull-compare-6.C: New test.
* g++.dg/warn/Wnonnull-compare-7.C: New test.
* g++.dg/ubsan/pr69922.C: New test.
2016-02-24 Marek Polacek <polacek@redhat.com>
PR c/69819
......
// PR c++/69922
// { dg-do compile }
// { dg-options "-fsanitize=vptr -Wnonnull-compare" }
struct S { virtual ~S (); };
struct T : S { T *bar (); T *baz (); T *q; bool b; };
T *
T::bar ()
{
return static_cast<T*>(reinterpret_cast<S*>(this)); // { dg-bogus "nonnull argument" }
}
T *
T::baz ()
{
return static_cast<T*>(reinterpret_cast<S*>(b ? this : q)); // { dg-bogus "nonnull argument" }
}
// PR c++/69922
// { dg-do compile }
// { dg-options "-Wnonnull-compare" }
struct T { virtual ~T (); };
struct S { virtual ~S (); T *f (bool); };
struct U : S, T {};
T *
S::f (bool b)
{
return b ? static_cast<U *> (this) : (U *) 0; // { dg-bogus "nonnull argument" }
}
// PR c++/69922
// { dg-do compile }
// { dg-options "-Wnonnull-compare" }
struct S { virtual ~S (); };
struct T { virtual ~T (); };
bool b, c;
S *p;
T *q, *r;
S::~S ()
{
delete (b ? this : p); // { dg-bogus "nonnull argument" }
}
T::~T ()
{
delete (b ? (c ? this : q) : r); // { dg-bogus "nonnull argument" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment