From 7f26f7df904d3894d726e36a57d5f004eef71a74 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 18 Jan 2016 10:54:14 -0500 Subject: [PATCH] re PR c++/68767 (spurious warning: null argument where non-null required) PR c++/68767 gcc/c-family/ * c-common.c (check_function_arguments_recurse): Fold the whole COND_EXPR, not just the condition. gcc/cp/ * cp-gimplify.c (cp_fold) [COND_EXPR]: Simplify. Do fold COND_EXPR. (contains_label_1, contains_label_p): Remove. From-SVN: r232522 --- gcc/c-family/ChangeLog | 6 ++ gcc/c-family/c-common.c | 22 ++++--- gcc/cp/ChangeLog | 6 ++ gcc/cp/cp-gimplify.c | 86 ++++----------------------- gcc/testsuite/g++.dg/warn/Wnonnull2.C | 9 +++ 5 files changed, 45 insertions(+), 84 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wnonnull2.C diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 33f28845fe7..a22485fcbd6 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2016-01-18 Jason Merrill + + PR c++/68767 + * c-common.c (check_function_arguments_recurse): Fold the whole + COND_EXPR, not just the condition. + 2016-01-18 Tom de Vries * c-omp.c (c_oacc_split_loop_clauses): Don't copy OMP_CLAUSE_REDUCTION, diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 0bfa1f6879e..1a2c21b8939 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -9765,15 +9765,19 @@ check_function_arguments_recurse (void (*callback) if (TREE_CODE (param) == COND_EXPR) { - tree cond = fold_for_warn (TREE_OPERAND (param, 0)); - /* Check both halves of the conditional expression. */ - if (!integer_zerop (cond)) - check_function_arguments_recurse (callback, ctx, - TREE_OPERAND (param, 1), param_num); - if (!integer_nonzerop (cond)) - check_function_arguments_recurse (callback, ctx, - TREE_OPERAND (param, 2), param_num); - return; + /* Simplify to avoid warning for an impossible case. */ + param = fold_for_warn (param); + if (TREE_CODE (param) == COND_EXPR) + { + /* Check both halves of the conditional expression. */ + check_function_arguments_recurse (callback, ctx, + TREE_OPERAND (param, 1), + param_num); + check_function_arguments_recurse (callback, ctx, + TREE_OPERAND (param, 2), + param_num); + return; + } } (*callback) (ctx, param, param_num); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6b7e81b0733..0ae29124658 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-01-18 Jason Merrill + + PR c++/68767 + * cp-gimplify.c (cp_fold) [COND_EXPR]: Simplify. Do fold COND_EXPR. + (contains_label_1, contains_label_p): Remove. + 2016-01-16 Patrick Palka PR c++/69091 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index c0ee8e43466..e151753b3e4 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1851,38 +1851,6 @@ cxx_omp_disregard_value_expr (tree decl, bool shared) && DECL_OMP_PRIVATIZED_MEMBER (decl); } -/* Callback for walk_tree, looking for LABEL_EXPR. Return *TP if it is - a LABEL_EXPR; otherwise return NULL_TREE. Do not check the subtrees - of GOTO_EXPR. */ - -static tree -contains_label_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) -{ - switch (TREE_CODE (*tp)) - { - case LABEL_EXPR: - return *tp; - - case GOTO_EXPR: - *walk_subtrees = 0; - - /* ... fall through ... */ - - default: - return NULL_TREE; - } -} - -/* Return whether the sub-tree ST contains a label which is accessible from - outside the sub-tree. */ - -static bool -contains_label_p (tree st) -{ - return - walk_tree_without_duplicates (&st, contains_label_1 , NULL) != NULL_TREE; -} - /* Perform folding on expression X. */ tree @@ -2110,54 +2078,22 @@ cp_fold (tree x) case VEC_COND_EXPR: case COND_EXPR: + /* Don't bother folding a void condition, since it can't produce a + constant value. Also, some statement-level uses of COND_EXPR leave + one of the branches NULL, so folding would crash. */ + if (VOID_TYPE_P (TREE_TYPE (x))) + return x; + loc = EXPR_LOCATION (x); op0 = cp_fold_rvalue (TREE_OPERAND (x, 0)); - - if (TREE_SIDE_EFFECTS (op0)) - break; - op1 = cp_fold (TREE_OPERAND (x, 1)); op2 = cp_fold (TREE_OPERAND (x, 2)); - if (TREE_CODE (op0) == INTEGER_CST) - { - tree un; - - if (integer_zerop (op0)) - { - un = op1; - r = op2; - } - else - { - un = op2; - r = op1; - } - - if ((!TREE_SIDE_EFFECTS (un) || !contains_label_p (un)) - && (! VOID_TYPE_P (TREE_TYPE (r)) || VOID_TYPE_P (x))) - { - if (CAN_HAVE_LOCATION_P (r) - && EXPR_LOCATION (r) != loc - && !(TREE_CODE (r) == SAVE_EXPR - || TREE_CODE (r) == TARGET_EXPR - || TREE_CODE (r) == BIND_EXPR)) - { - r = copy_node (r); - SET_EXPR_LOCATION (r, loc); - } - x = r; - } - - break; - } - - if (VOID_TYPE_P (TREE_TYPE (x))) - break; - - x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2); - - if (code != COND_EXPR) + if (op0 != TREE_OPERAND (x, 0) + || op1 != TREE_OPERAND (x, 1) + || op2 != TREE_OPERAND (x, 2)) + x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2); + else x = fold (x); break; diff --git a/gcc/testsuite/g++.dg/warn/Wnonnull2.C b/gcc/testsuite/g++.dg/warn/Wnonnull2.C new file mode 100644 index 00000000000..6757437de12 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wnonnull2.C @@ -0,0 +1,9 @@ +// PR c++/68767 +// { dg-options "-Wnonnull" } + +extern int len (const char*) __attribute__ ((__nonnull__ (1))); + +int f (int x) +{ + return len ((x ? "x" : 0) ? (x ? "x" : 0) : "x"); +} -- 2.30.2