From 66ecb059c9d77cfcfb06cbdc3cac6a63b9e67f3d Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 2 Mar 2021 11:12:50 -0700 Subject: PR c++/99251 - inconsistent -Wnonnull warning behaviour with dynamic_cast gcc/cp/ChangeLog: PR c++/99251 * class.c (build_base_path): Call build_if_nonnull. * cp-tree.h (build_if_nonnull): Declare. * rtti.c (ifnonnull): Rename... (build_if_nonnull): ...to this. Set no-warning bit on COND_EXPR. (build_dynamic_cast_1): Adjust to name change. gcc/testsuite/ChangeLog: PR c++/99251 * g++.dg/warn/Wnonnull9.C: Expect no warnings. * g++.dg/warn/Wnonnull12.C: New test. --- gcc/cp/rtti.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'gcc/cp/rtti.c') diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index b41d954..5a33b83 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -121,7 +121,6 @@ vec *unemitted_tinfo_decls; and are generated as needed. */ static GTY (()) vec *tinfo_descs; -static tree ifnonnull (tree, tree, tsubst_flags_t); static tree tinfo_name (tree, bool); static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t); static tree throw_bad_cast (void); @@ -529,16 +528,23 @@ get_typeid (tree type, tsubst_flags_t complain) /* Check whether TEST is null before returning RESULT. If TEST is used in RESULT, it must have previously had a save_expr applied to it. */ -static tree -ifnonnull (tree test, tree result, tsubst_flags_t complain) +tree +build_if_nonnull (tree test, tree result, tsubst_flags_t complain) { - tree cond = build2 (NE_EXPR, boolean_type_node, test, - cp_convert (TREE_TYPE (test), nullptr_node, complain)); + tree null_ptr = cp_convert (TREE_TYPE (test), nullptr_node, complain); + tree cond = build2 (NE_EXPR, boolean_type_node, test, null_ptr); + /* This is a compiler generated comparison, don't emit e.g. -Wnonnull-compare warning for it. */ TREE_NO_WARNING (cond) = 1; - return build3 (COND_EXPR, TREE_TYPE (result), cond, result, - cp_convert (TREE_TYPE (result), nullptr_node, complain)); + + null_ptr = cp_convert (TREE_TYPE (result), nullptr_node, complain); + cond = build3 (COND_EXPR, TREE_TYPE (result), cond, result, null_ptr); + + /* Likewise, don't emit -Wnonnull for using the result to call + a member function. */ + TREE_NO_WARNING (cond) = 1; + return cond; } /* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working @@ -671,7 +677,7 @@ build_dynamic_cast_1 (location_t loc, tree type, tree expr, expr1 = build_headof (expr); if (TREE_TYPE (expr1) != type) expr1 = build1 (NOP_EXPR, type, expr1); - return ifnonnull (expr, expr1, complain); + return build_if_nonnull (expr, expr1, complain); } else { @@ -786,7 +792,7 @@ build_dynamic_cast_1 (location_t loc, tree type, tree expr, /* Now back to the type we want from a void*. */ result = cp_convert (type, result, complain); - return ifnonnull (expr, result, complain); + return build_if_nonnull (expr, result, complain); } } else -- cgit v1.1