* PATCH RFA: C++ frontend warning: comparing function pointer to NULL @ 2007-01-04 15:23 Ian Lance Taylor 2007-01-04 18:47 ` Andrew Pinski 0 siblings, 1 reply; 14+ messages in thread From: Ian Lance Taylor @ 2007-01-04 15:23 UTC (permalink / raw) To: gcc-patches If you write code like this: extern int foo(); if (foo == 0) ... the C frontend will issue a warning: the address of 'foo' will never be NULL This is useful for the case where somebody wrote "foo" instead of "foo()". The C++ frontend does not issue this warning. This patch adds the warning to the C++ frontend. In the testsuite I added a couple of tests for if (foo) which is a warning which the C++ frontend already generates. Tested with bootstrap and testsuite run on i686-pc-linux-gnu. OK for mainline? Ian cp/ChangeLog: 2007-01-04 Ian Lance Taylor <iant@google.com> * typeck.c (build_binary_op): Warn about comparing a non-weak address to NULL. testsuite/ChangeLog: 2007-01-04 Ian Lance Taylor <iant@google.com> * g++.dg/warn/Walways-true-1.C: New test. * g++.dg/warn/Walways-true-2.C: New test. Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 120376) +++ gcc/cp/typeck.c (working copy) @@ -3334,10 +3334,24 @@ build_binary_op (enum tree_code code, tr "comparison"); else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) && null_ptr_cst_p (op1)) - result_type = type0; + { + if (TREE_CODE (op0) == ADDR_EXPR + && DECL_P (TREE_OPERAND (op0, 0)) + && !DECL_WEAK (TREE_OPERAND (op0, 0))) + warning (OPT_Walways_true, "the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); + result_type = type0; + } else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1)) && null_ptr_cst_p (op0)) - result_type = type1; + { + if (TREE_CODE (op1) == ADDR_EXPR + && DECL_P (TREE_OPERAND (op1, 0)) + && !DECL_WEAK (TREE_OPERAND (op1, 0))) + warning (OPT_Walways_true, "the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); + result_type = type1; + } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; Index: gcc/testsuite/g++.dg/warn/Walways-true-1.C =================================================================== --- gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0) +++ gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0) @@ -0,0 +1,30 @@ +// Test -Walways-true for testing an address against NULL. +// Origin: Ian Lance Taylor <iant@google.com> + +// { dg-do compile} +// { dg-options "-Walways-true" } + +extern int foo (int); + +int i; + +void +bar () +{ + if (foo) // { dg-warning "always evaluate as" "correct warning" } + foo (0); + if (foo (1)) + foo (1); + if (&i) // { dg-warning "always evaluate as" "correct warning" } + foo (2); + if (i) + foo (3); + if (foo == 0) // { dg-warning "never be NULL" "correct warning" } + foo (4); + if (foo (1) == 0) + foo (5); + if (&i == 0) // { dg-warning "never be NULL" "correct warning" } + foo (6); + if (i == 0) + foo (7); +} Index: gcc/testsuite/g++.dg/warn/Walways-true-2.C =================================================================== --- gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0) +++ gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0) @@ -0,0 +1,33 @@ +// Make sure we don't assume that a weak symbol is always non-NULL. +// This is just like Walways-true-1.C, except that it uses a weak +// symbol. +// Origin: Ian Lance Taylor <iant@google.com> + +// { dg-do compile} +// { dg-options "-Walways-true" } +// { dg-require-weak "" } + +extern int foo (int) __attribute__ ((weak)); + +int i __attribute__ ((weak)); + +void +bar () +{ + if (foo) + foo (0); + if (foo (1)) + foo (1); + if (&i) + foo (2); + if (i) + foo (3); + if (foo == 0) + foo (4); + if (foo (1) == 0) + foo (5); + if (&i == 0) + foo (6); + if (i == 0) + foo (7); +} ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-04 15:23 PATCH RFA: C++ frontend warning: comparing function pointer to NULL Ian Lance Taylor @ 2007-01-04 18:47 ` Andrew Pinski 2007-01-05 2:42 ` Ian Lance Taylor 0 siblings, 1 reply; 14+ messages in thread From: Andrew Pinski @ 2007-01-04 18:47 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: gcc-patches > > Ian > > > cp/ChangeLog: > 2007-01-04 Ian Lance Taylor <iant@google.com> > > * typeck.c (build_binary_op): Warn about comparing a non-weak > address to NULL. > > testsuite/ChangeLog: > 2007-01-04 Ian Lance Taylor <iant@google.com> > > * g++.dg/warn/Walways-true-1.C: New test. > * g++.dg/warn/Walways-true-2.C: New test. > > > Index: gcc/cp/typeck.c > =================================================================== > --- gcc/cp/typeck.c (revision 120376) > +++ gcc/cp/typeck.c (working copy) > @@ -3334,10 +3334,24 @@ build_binary_op (enum tree_code code, tr > "comparison"); > else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) > && null_ptr_cst_p (op1)) > - result_type = type0; > + { > + if (TREE_CODE (op0) == ADDR_EXPR > + && DECL_P (TREE_OPERAND (op0, 0)) > + && !DECL_WEAK (TREE_OPERAND (op0, 0))) > + warning (OPT_Walways_true, "the address of %qD will never be NULL", > + TREE_OPERAND (op0, 0)); I remember when the C code was added for this warning (which looked almost the same), we would ICE for code like: int f(int a) { return (&a) == 0; } Looking at the above code looks like we would ICE in the C++ code with the above testcase. The C front-end checks for PARM and LABEL decls too: if (TREE_CODE (op0) == ADDR_EXPR && DECL_P (TREE_OPERAND (op0, 0)) && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL || !DECL_WEAK (TREE_OPERAND (op0, 0)))) Could you add a testcase for the argument and label cases and make sure we don't ICE on them? Thanks, Andrew Pinski ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-04 18:47 ` Andrew Pinski @ 2007-01-05 2:42 ` Ian Lance Taylor 2007-01-05 5:14 ` Mark Mitchell 2007-01-05 6:48 ` Gabriel Dos Reis 0 siblings, 2 replies; 14+ messages in thread From: Ian Lance Taylor @ 2007-01-05 2:42 UTC (permalink / raw) To: Andrew Pinski; +Cc: gcc-patches Andrew Pinski <pinskia@physics.uc.edu> writes: > I remember when the C code was added for this warning (which looked almost > the same), we would ICE for code like: > > int f(int a) > { > return (&a) == 0; > } > > Looking at the above code looks like we would ICE in the C++ code with the > above testcase. > The C front-end checks for PARM and LABEL decls too: > if (TREE_CODE (op0) == ADDR_EXPR > && DECL_P (TREE_OPERAND (op0, 0)) > && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL > || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL > || !DECL_WEAK (TREE_OPERAND (op0, 0)))) > > Could you add a testcase for the argument and label cases and make sure > we don't ICE on them? You're absolutely right. Thanks a lot for the pointer. Here is the updated, retested, patch. Ian Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 120376) +++ gcc/cp/typeck.c (working copy) @@ -3334,10 +3334,28 @@ build_binary_op (enum tree_code code, tr "comparison"); else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) && null_ptr_cst_p (op1)) - result_type = type0; + { + if (TREE_CODE (op0) == ADDR_EXPR + && DECL_P (TREE_OPERAND (op0, 0)) + && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL + || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL + || !DECL_WEAK (TREE_OPERAND (op0, 0)))) + warning (OPT_Walways_true, "the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); + result_type = type0; + } else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1)) && null_ptr_cst_p (op0)) - result_type = type1; + { + if (TREE_CODE (op1) == ADDR_EXPR + && DECL_P (TREE_OPERAND (op1, 0)) + && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL + || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL + || !DECL_WEAK (TREE_OPERAND (op0, 0)))) + warning (OPT_Walways_true, "the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); + result_type = type1; + } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; Index: gcc/testsuite/g++.dg/warn/Walways-true-1.C =================================================================== --- gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0) +++ gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0) @@ -0,0 +1,43 @@ +// Test -Walways-true for testing an address against NULL. +// Origin: Ian Lance Taylor <iant@google.com> + +// { dg-do compile} +// { dg-options "-Walways-true" } + +extern int foo (int); + +int i; + +void +bar (int a) +{ + lab: + if (foo) // { dg-warning "always evaluate as" "correct warning" } + foo (0); + if (foo (1)) + foo (1); + if (&i) // { dg-warning "always evaluate as" "correct warning" } + foo (2); + if (i) + foo (3); + if (&a) // { dg-warning "always evaluate as" "correct warning" } + foo (4); + if (a) + foo (5); + if (&&lab) // { dg-warning "always evaluate as" "correct warning" } + foo (6); + if (foo == 0) // { dg-warning "never be NULL" "correct warning" } + foo (7); + if (foo (1) == 0) + foo (9); + if (&i == 0) // { dg-warning "never be NULL" "correct warning" } + foo (9); + if (i == 0) + foo (10); + if (&a == 0) // { dg-warning "never be NULL" "correct warning" } + foo (11); + if (a == 0) + foo (12); + if (&&lab == 0) // { dg-warning "never be NULL" "correct warning" } + foo (13); +} Index: gcc/testsuite/g++.dg/warn/Walways-true-2.C =================================================================== --- gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0) +++ gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0) @@ -0,0 +1,46 @@ +// Make sure we don't assume that a weak symbol is always non-NULL. +// This is just like Walways-true-1.C, except that it uses a weak +// symbol. +// Origin: Ian Lance Taylor <iant@google.com> + +// { dg-do compile} +// { dg-options "-Walways-true" } +// { dg-require-weak "" } + +extern int foo (int) __attribute__ ((weak)); + +int i __attribute__ ((weak)); + +void +bar (int a) +{ + lab: + if (foo) + foo (0); + if (foo (1)) + foo (1); + if (&i) + foo (2); + if (i) + foo (3); + if (&a) // { dg-warning "always evaluate as" "correct warning" } + foo (4); + if (a) + foo (5); + if (&&lab) // { dg-warning "always evaluate as" "correct warning" } + foo (6); + if (foo == 0) + foo (7); + if (foo (1) == 0) + foo (9); + if (&i == 0) + foo (9); + if (i == 0) + foo (10); + if (&a == 0) // { dg-warning "never be NULL" "correct warning" } + foo (11); + if (a == 0) + foo (12); + if (&&lab == 0) // { dg-warning "never be NULL" "correct warning" } + foo (13); +} ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-05 2:42 ` Ian Lance Taylor @ 2007-01-05 5:14 ` Mark Mitchell 2007-01-05 6:58 ` Ian Lance Taylor 2007-01-05 6:48 ` Gabriel Dos Reis 1 sibling, 1 reply; 14+ messages in thread From: Mark Mitchell @ 2007-01-05 5:14 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: Andrew Pinski, gcc-patches Ian Lance Taylor wrote: > You're absolutely right. Thanks a lot for the pointer. > > Here is the updated, retested, patch. > > Ian > > Index: gcc/cp/typeck.c > =================================================================== > --- gcc/cp/typeck.c (revision 120376) > +++ gcc/cp/typeck.c (working copy) > @@ -3334,10 +3334,28 @@ build_binary_op (enum tree_code code, tr > "comparison"); > else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) > && null_ptr_cst_p (op1)) > - result_type = type0; > + { > + if (TREE_CODE (op0) == ADDR_EXPR > + && DECL_P (TREE_OPERAND (op0, 0)) > + && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL > + || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL > + || !DECL_WEAK (TREE_OPERAND (op0, 0)))) > + warning (OPT_Walways_true, "the address of %qD will never be NULL", > + TREE_OPERAND (op0, 0)); > + result_type = type0; > + } I hate to be niggly, but it looks like you've introduced two copies of the same test here (modulo op0 vs. op1), and it sounds like the C front end has at least one more copy. Would you mind creating a function, shared as widely as possible? Thanks, -- Mark Mitchell CodeSourcery mark@codesourcery.com (650) 331-3385 x713 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-05 5:14 ` Mark Mitchell @ 2007-01-05 6:58 ` Ian Lance Taylor 2007-01-05 17:45 ` Mark Mitchell 0 siblings, 1 reply; 14+ messages in thread From: Ian Lance Taylor @ 2007-01-05 6:58 UTC (permalink / raw) To: Mark Mitchell; +Cc: gcc-patches Mark Mitchell <mark@codesourcery.com> writes: > I hate to be niggly, but it looks like you've introduced two copies of > the same test here (modulo op0 vs. op1), and it sounds like the C front > end has at least one more copy. Would you mind creating a function, > shared as widely as possible? How about this version? Since I changed the C frontend, I added C test cases too (they are actually exactly the same as the C++ test cases, except for comment syntax). Bootstrapped on i686-pc-linux-gnu, testsuite run in progress. Ian Index: gcc/c-common.c =================================================================== --- gcc/c-common.c (revision 120376) +++ gcc/c-common.c (working copy) @@ -2591,6 +2591,18 @@ pointer_int_sum (enum tree_code resultco return fold_build2 (resultcode, result_type, ptrop, intop); } \f +/* Return whether EXPR is a declaration whose address can never be + NULL. */ + +bool +decl_with_nonnull_addr_p (tree expr) +{ + return (DECL_P (expr) + && (TREE_CODE (expr) == PARM_DECL + || TREE_CODE (expr) == LABEL_DECL + || !DECL_WEAK (expr))); +} + /* Prepare expr to be an argument of a TRUTH_NOT_EXPR, or for an `if' or `while' statement or ?..: exp. It should already have been validated to be of suitable type; otherwise, a bad @@ -2656,23 +2668,22 @@ c_common_truthvalue_conversion (tree exp case ADDR_EXPR: { tree inner = TREE_OPERAND (expr, 0); - if (DECL_P (inner) - && (TREE_CODE (inner) == PARM_DECL - || TREE_CODE (inner) == LABEL_DECL - || !DECL_WEAK (inner))) + if (decl_with_nonnull_addr_p (inner)) { - /* Common Ada/Pascal programmer's mistake. We always warn - about this since it is so bad. */ - warning (OPT_Walways_true, "the address of %qD will always evaluate as %<true%>", + /* Common Ada/Pascal programmer's mistake. */ + warning (OPT_Walways_true, + "the address of %qD will always evaluate as %<true%>", inner); return truthvalue_true_node; } - /* If we are taking the address of an external decl, it might be - zero if it is weak, so we cannot optimize. */ - if (DECL_P (inner) - && DECL_EXTERNAL (inner)) - break; + /* If we still have a decl, it is possible for its address to + be NULL, so we cannot optimize. */ + if (DECL_P (inner)) + { + gcc_assert (DECL_WEAK (inner)); + break; + } if (TREE_SIDE_EFFECTS (inner)) return build2 (COMPOUND_EXPR, truthvalue_type_node, Index: gcc/c-typeck.c =================================================================== --- gcc/c-typeck.c (revision 120376) +++ gcc/c-typeck.c (working copy) @@ -8013,10 +8013,7 @@ build_binary_op (enum tree_code code, tr else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) { if (TREE_CODE (op0) == ADDR_EXPR - && DECL_P (TREE_OPERAND (op0, 0)) - && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL - || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL - || !DECL_WEAK (TREE_OPERAND (op0, 0)))) + && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) warning (OPT_Walways_true, "the address of %qD will never be NULL", TREE_OPERAND (op0, 0)); result_type = type0; @@ -8024,10 +8021,7 @@ build_binary_op (enum tree_code code, tr else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) { if (TREE_CODE (op1) == ADDR_EXPR - && DECL_P (TREE_OPERAND (op1, 0)) - && (TREE_CODE (TREE_OPERAND (op1, 0)) == PARM_DECL - || TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL - || !DECL_WEAK (TREE_OPERAND (op1, 0)))) + && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) warning (OPT_Walways_true, "the address of %qD will never be NULL", TREE_OPERAND (op1, 0)); result_type = type1; Index: gcc/c-common.h =================================================================== --- gcc/c-common.h (revision 120376) +++ gcc/c-common.h (working copy) @@ -652,6 +652,7 @@ extern tree c_common_unsigned_type (tree extern tree c_common_signed_type (tree); extern tree c_common_signed_or_unsigned_type (int, tree); extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int); +extern bool decl_with_nonnull_addr_p (tree); extern tree c_common_truthvalue_conversion (tree); extern void c_apply_type_quals_to_decl (int, tree); extern tree c_sizeof_or_alignof_type (tree, bool, int); Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 120376) +++ gcc/cp/typeck.c (working copy) @@ -3334,10 +3334,22 @@ build_binary_op (enum tree_code code, tr "comparison"); else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) && null_ptr_cst_p (op1)) - result_type = type0; + { + if (TREE_CODE (op0) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) + warning (OPT_Walways_true, "the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); + result_type = type0; + } else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1)) && null_ptr_cst_p (op0)) - result_type = type1; + { + if (TREE_CODE (op1) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) + warning (OPT_Walways_true, "the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); + result_type = type1; + } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; Index: gcc/testsuite/gcc.dg/Walways-true-1.c =================================================================== --- gcc/testsuite/gcc.dg/Walways-true-1.c (revision 0) +++ gcc/testsuite/gcc.dg/Walways-true-1.c (revision 0) @@ -0,0 +1,57 @@ +/* Test -Walways-true for testing an address against NULL. + Origin: Ian Lance Taylor <iant@google.com>. */ + +/* { dg-do compile} */ +/* { dg-options "-Walways-true" } */ + +extern int foo (int); + +int i; + +void +bar (int a) +{ + lab: + if (foo) /* { dg-warning "always evaluate as" "correct warning" } */ + foo (0); + if (foo (1)) + ; + if (&i) /* { dg-warning "always evaluate as" "correct warning" } */ + foo (2); + if (i) + foo (3); + if (&a) /* { dg-warning "always evaluate as" "correct warning" } */ + foo (4); + if (a) + foo (5); + if (&&lab) /* { dg-warning "always evaluate as" "correct warning" } */ + foo (6); + if (foo == 0) /* { dg-warning "never be NULL" "correct warning" } */ + foo (7); + if (foo (1) == 0) + foo (8); + if (&i == 0) /* { dg-warning "never be NULL" "correct warning" } */ + foo (9); + if (i == 0) + foo (10); + if (&a == 0) /* { dg-warning "never be NULL" "correct warning" } */ + foo (11); + if (a == 0) + foo (12); + if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */ + foo (13); + if (0 == foo) /* { dg-warning "never be NULL" "correct warning" } */ + foo (14); + if (0 == foo (1)) + foo (15); + if (0 == &i) /* { dg-warning "never be NULL" "correct warning" } */ + foo (16); + if (0 == i) + foo (17); + if (0 == &a) /* { dg-warning "never be NULL" "correct warning" } */ + foo (18); + if (0 == a) + foo (19); + if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */ + foo (20); +} Index: gcc/testsuite/gcc.dg/Walways-true-2.c =================================================================== --- gcc/testsuite/gcc.dg/Walways-true-2.c (revision 0) +++ gcc/testsuite/gcc.dg/Walways-true-2.c (revision 0) @@ -0,0 +1,60 @@ +/* Make sure we don't assume that a weak symbol is always non-NULL. + This is just like Walways-true-1.C, except that it uses a weak + symbol. + Origin: Ian Lance Taylor <iant@google.com>. */ + +/* { dg-do compile} */ +/* { dg-options "-Walways-true" } */ +/* { dg-require-weak "" } */ + +extern int foo (int) __attribute__ ((weak)); + +int i __attribute__ ((weak)); + +void +bar (int a) +{ + lab: + if (foo) + foo (0); + if (foo (1)) + ; + if (&i) + foo (2); + if (i) + foo (3); + if (&a) /* { dg-warning "always evaluate as" "correct warning" } */ + foo (4); + if (a) + foo (5); + if (&&lab) /* { dg-warning "always evaluate as" "correct warning" } */ + foo (6); + if (foo == 0) + foo (7); + if (foo (1) == 0) + foo (8); + if (&i == 0) + foo (9); + if (i == 0) + foo (10); + if (&a == 0) /* { dg-warning "never be NULL" "correct warning" } */ + foo (11); + if (a == 0) + foo (12); + if (&&lab == 0) /* { dg-warning "never be NULL" "correct warning" } */ + foo (13); + if (0 == foo) + foo (14); + if (0 == foo (1)) + foo (15); + if (0 == &i) + foo (16); + if (0 == i) + foo (17); + if (0 == &a) /* { dg-warning "never be NULL" "correct warning" } */ + foo (18); + if (0 == a) + foo (19); + if (0 == &&lab) /* { dg-warning "never be NULL" "correct warning" } */ + foo (20); +} Index: gcc/testsuite/g++.dg/warn/Walways-true-1.C =================================================================== --- gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0) +++ gcc/testsuite/g++.dg/warn/Walways-true-1.C (revision 0) @@ -0,0 +1,57 @@ +// Test -Walways-true for testing an address against NULL. +// Origin: Ian Lance Taylor <iant@google.com> + +// { dg-do compile} +// { dg-options "-Walways-true" } + +extern int foo (int); + +int i; + +void +bar (int a) +{ + lab: + if (foo) // { dg-warning "always evaluate as" "correct warning" } + foo (0); + if (foo (1)) + ; + if (&i) // { dg-warning "always evaluate as" "correct warning" } + foo (2); + if (i) + foo (3); + if (&a) // { dg-warning "always evaluate as" "correct warning" } + foo (4); + if (a) + foo (5); + if (&&lab) // { dg-warning "always evaluate as" "correct warning" } + foo (6); + if (foo == 0) // { dg-warning "never be NULL" "correct warning" } + foo (7); + if (foo (1) == 0) + foo (8); + if (&i == 0) // { dg-warning "never be NULL" "correct warning" } + foo (9); + if (i == 0) + foo (10); + if (&a == 0) // { dg-warning "never be NULL" "correct warning" } + foo (11); + if (a == 0) + foo (12); + if (&&lab == 0) // { dg-warning "never be NULL" "correct warning" } + foo (13); + if (0 == foo) // { dg-warning "never be NULL" "correct warning" } + foo (14); + if (0 == foo (1)) + foo (15); + if (0 == &i) // { dg-warning "never be NULL" "correct warning" } + foo (16); + if (0 == i) + foo (17); + if (0 == &a) // { dg-warning "never be NULL" "correct warning" } + foo (18); + if (0 == a) + foo (19); + if (0 == &&lab) // { dg-warning "never be NULL" "correct warning" } + foo (20); +} Index: gcc/testsuite/g++.dg/warn/Walways-true-2.C =================================================================== --- gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0) +++ gcc/testsuite/g++.dg/warn/Walways-true-2.C (revision 0) @@ -0,0 +1,60 @@ +// Make sure we don't assume that a weak symbol is always non-NULL. +// This is just like Walways-true-1.C, except that it uses a weak +// symbol. +// Origin: Ian Lance Taylor <iant@google.com> + +// { dg-do compile} +// { dg-options "-Walways-true" } +// { dg-require-weak "" } + +extern int foo (int) __attribute__ ((weak)); + +int i __attribute__ ((weak)); + +void +bar (int a) +{ + lab: + if (foo) + foo (0); + if (foo (1)) + ; + if (&i) + foo (2); + if (i) + foo (3); + if (&a) // { dg-warning "always evaluate as" "correct warning" } + foo (4); + if (a) + foo (5); + if (&&lab) // { dg-warning "always evaluate as" "correct warning" } + foo (6); + if (foo == 0) + foo (7); + if (foo (1) == 0) + foo (8); + if (&i == 0) + foo (9); + if (i == 0) + foo (10); + if (&a == 0) // { dg-warning "never be NULL" "correct warning" } + foo (11); + if (a == 0) + foo (12); + if (&&lab == 0) // { dg-warning "never be NULL" "correct warning" } + foo (13); + if (0 == foo) + foo (14); + if (0 == foo (1)) + foo (15); + if (0 == &i) + foo (16); + if (0 == i) + foo (17); + if (0 == &a) // { dg-warning "never be NULL" "correct warning" } + foo (18); + if (0 == a) + foo (19); + if (0 == &&lab) // { dg-warning "never be NULL" "correct warning" } + foo (20); +} ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-05 6:58 ` Ian Lance Taylor @ 2007-01-05 17:45 ` Mark Mitchell 0 siblings, 0 replies; 14+ messages in thread From: Mark Mitchell @ 2007-01-05 17:45 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: gcc-patches Ian Lance Taylor wrote: > Mark Mitchell <mark@codesourcery.com> writes: > >> I hate to be niggly, but it looks like you've introduced two copies of >> the same test here (modulo op0 vs. op1), and it sounds like the C front >> end has at least one more copy. Would you mind creating a function, >> shared as widely as possible? > > How about this version? Since I changed the C frontend, I added C > test cases too (they are actually exactly the same as the C++ test > cases, except for comment syntax). OK, and thanks for going along with the niggle. -- Mark Mitchell CodeSourcery mark@codesourcery.com (650) 331-3385 x713 ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-05 2:42 ` Ian Lance Taylor 2007-01-05 5:14 ` Mark Mitchell @ 2007-01-05 6:48 ` Gabriel Dos Reis 1 sibling, 0 replies; 14+ messages in thread From: Gabriel Dos Reis @ 2007-01-05 6:48 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: Andrew Pinski, gcc-patches Ian Lance Taylor <iant@google.com> writes: | Andrew Pinski <pinskia@physics.uc.edu> writes: | | > I remember when the C code was added for this warning (which looked almost | > the same), we would ICE for code like: | > | > int f(int a) | > { | > return (&a) == 0; | > } | > | > Looking at the above code looks like we would ICE in the C++ code with the | > above testcase. | > The C front-end checks for PARM and LABEL decls too: | > if (TREE_CODE (op0) == ADDR_EXPR | > && DECL_P (TREE_OPERAND (op0, 0)) | > && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL | > || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL | > || !DECL_WEAK (TREE_OPERAND (op0, 0)))) | > | > Could you add a testcase for the argument and label cases and make sure | > we don't ICE on them? | | You're absolutely right. Thanks a lot for the pointer. | | Here is the updated, retested, patch. | | Ian | | Index: gcc/cp/typeck.c | =================================================================== | --- gcc/cp/typeck.c (revision 120376) | +++ gcc/cp/typeck.c (working copy) | @@ -3334,10 +3334,28 @@ build_binary_op (enum tree_code code, tr | "comparison"); | else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0)) | && null_ptr_cst_p (op1)) | - result_type = type0; | + { | + if (TREE_CODE (op0) == ADDR_EXPR | + && DECL_P (TREE_OPERAND (op0, 0)) | + && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL | + || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL | + || !DECL_WEAK (TREE_OPERAND (op0, 0)))) | + warning (OPT_Walways_true, "the address of %qD will never be NULL", | + TREE_OPERAND (op0, 0)); | + result_type = type0; | + } | else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1)) | && null_ptr_cst_p (op0)) | - result_type = type1; | + { | + if (TREE_CODE (op1) == ADDR_EXPR | + && DECL_P (TREE_OPERAND (op1, 0)) | + && (TREE_CODE (TREE_OPERAND (op0, 0)) == PARM_DECL | + || TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL | + || !DECL_WEAK (TREE_OPERAND (op0, 0)))) | + warning (OPT_Walways_true, "the address of %qD will never be NULL", | + TREE_OPERAND (op1, 0)); | + result_type = type1; You get brownie point, if you could abstract that check into a separate (static inline) function. Otherwise, OK. -- Gaby ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL @ 2007-01-07 13:30 Manuel López-Ibáñez 2007-01-07 13:42 ` Gabriel Dos Reis 2007-01-07 19:28 ` Ian Lance Taylor 0 siblings, 2 replies; 14+ messages in thread From: Manuel López-Ibáñez @ 2007-01-07 13:30 UTC (permalink / raw) To: gcc-patches Cc: Gabriel Dos Reis, Ian Lance Taylor, Andrew Pinski, Mark Mitchell (Sorry for taking so much time to bring this up.) Ian added 2 testcases for Walways-true in revision 120493. There are at least 3 existing testcases that also deal with Walways-true: * gcc.dg/20031012-1.c * gcc.dg/weak/weak-3.c * g++.old-deja/g++.mike/warn8.C They were added in revision 108689. Wouldn't it be appropriate to integrate them into the testcases added by Ian and remove any duplicated tests? Cheers, Manuel. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-07 13:30 Manuel López-Ibáñez @ 2007-01-07 13:42 ` Gabriel Dos Reis 2007-01-07 19:28 ` Ian Lance Taylor 1 sibling, 0 replies; 14+ messages in thread From: Gabriel Dos Reis @ 2007-01-07 13:42 UTC (permalink / raw) To: Manuel López-Ibáñez Cc: gcc-patches, Ian Lance Taylor, Andrew Pinski, Mark Mitchell "Manuel López-Ibáñez" <lopezibanez@gmail.com> writes: | (Sorry for taking so much time to bring this up.) | | Ian added 2 testcases for Walways-true in revision 120493. There are | at least 3 existing testcases that also deal with Walways-true: | | * gcc.dg/20031012-1.c | * gcc.dg/weak/weak-3.c | * g++.old-deja/g++.mike/warn8.C | | They were added in revision 108689. | | Wouldn't it be appropriate to integrate them into the testcases added | by Ian and remove any duplicated tests? Yes, that sounds good to me. -- Gaby ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-07 13:30 Manuel López-Ibáñez 2007-01-07 13:42 ` Gabriel Dos Reis @ 2007-01-07 19:28 ` Ian Lance Taylor 2007-01-07 21:12 ` Manuel López-Ibáñez 1 sibling, 1 reply; 14+ messages in thread From: Ian Lance Taylor @ 2007-01-07 19:28 UTC (permalink / raw) To: Manuel López-Ibáñez Cc: gcc-patches, Gabriel Dos Reis, Andrew Pinski, Mark Mitchell "Manuel López-Ibáñez" <lopezibanez@gmail.com> writes: > Ian added 2 testcases for Walways-true in revision 120493. There are > at least 3 existing testcases that also deal with Walways-true: > > * gcc.dg/20031012-1.c > * gcc.dg/weak/weak-3.c > * g++.old-deja/g++.mike/warn8.C > > They were added in revision 108689. > > Wouldn't it be appropriate to integrate them into the testcases added > by Ian and remove any duplicated tests? Sure. Ian ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-07 19:28 ` Ian Lance Taylor @ 2007-01-07 21:12 ` Manuel López-Ibáñez 2007-01-07 22:09 ` Joseph S. Myers 2007-01-08 4:18 ` Ian Lance Taylor 0 siblings, 2 replies; 14+ messages in thread From: Manuel López-Ibáñez @ 2007-01-07 21:12 UTC (permalink / raw) To: Ian Lance Taylor Cc: gcc-patches, Gabriel Dos Reis, Andrew Pinski, Mark Mitchell On 07 Jan 2007 11:27:59 -0800, Ian Lance Taylor <iant@google.com> wrote: > "Manuel López-Ibáñez" <lopezibanez@gmail.com> writes: > > > Ian added 2 testcases for Walways-true in revision 120493. There are > > at least 3 existing testcases that also deal with Walways-true: > > > > * gcc.dg/20031012-1.c > > * gcc.dg/weak/weak-3.c > > * g++.old-deja/g++.mike/warn8.C > > > > They were added in revision 108689. > > > > Wouldn't it be appropriate to integrate them into the testcases added > > by Ian and remove any duplicated tests? > > Sure. Sorry for being such a bother but does this mean "Sure, I will do it" or "Sure, go ahead and do it" ? Also, perhaps we could consider this something to take into account before sending patches that add new testcases. Most of the time, a simple grep on the option name or a representative part of the expected output will bring up similar (and thus redundant) testcases. Maybe this could be commented somewhere... Cheers, Manuel. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-07 21:12 ` Manuel López-Ibáñez @ 2007-01-07 22:09 ` Joseph S. Myers 2007-01-07 22:41 ` Manuel López-Ibáñez 2007-01-08 4:18 ` Ian Lance Taylor 1 sibling, 1 reply; 14+ messages in thread From: Joseph S. Myers @ 2007-01-07 22:09 UTC (permalink / raw) To: Manuel Lopez-Ibanez Cc: Ian Lance Taylor, gcc-patches, Gabriel Dos Reis, Andrew Pinski, Mark Mitchell On Sun, 7 Jan 2007, Manuel Lopez-Ibanez wrote: > Also, perhaps we could consider this something to take into account > before sending patches that add new testcases. Most of the time, a > simple grep on the option name or a representative part of the > expected output will bring up similar (and thus redundant) testcases. > Maybe this could be commented somewhere... It's generally a mistake to consider testcases redundant unless actually identical. While two testcases may appear to test the same thing with the current implementation while the compiler is working correctly, a reimplementation of a feature or diagnostic could cause them to take different code paths, and a regression could break one similar case but not the other. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-07 22:09 ` Joseph S. Myers @ 2007-01-07 22:41 ` Manuel López-Ibáñez 0 siblings, 0 replies; 14+ messages in thread From: Manuel López-Ibáñez @ 2007-01-07 22:41 UTC (permalink / raw) To: Joseph S. Myers Cc: Ian Lance Taylor, gcc-patches, Gabriel Dos Reis, Andrew Pinski, Mark Mitchell On 07/01/07, Joseph S. Myers <joseph@codesourcery.com> wrote: > On Sun, 7 Jan 2007, Manuel Lopez-Ibanez wrote: > > > Also, perhaps we could consider this something to take into account > > before sending patches that add new testcases. Most of the time, a > > simple grep on the option name or a representative part of the > > expected output will bring up similar (and thus redundant) testcases. > > Maybe this could be commented somewhere... > > It's generally a mistake to consider testcases redundant unless actually > identical. While two testcases may appear to test the same thing with the > current implementation while the compiler is working correctly, a > reimplementation of a feature or diagnostic could cause them to take > different code paths, and a regression could break one similar case but > not the other. Of course, being strict, unless the two testcase files are byte-wise identical, anything may happen. But I guess that there may be some practical assumptions about the equivalence of testcases that allows to avoid testing every possible variation of any random testcase. For example, I would consider that it is generally safe to assume from a practical point of view that if two testcases vary only in whitespace, then they may be considered equivalent. I would go a bit further and consider that if two testcases vary only on the names of identifiers, then they may be considered equivalent. I guess we could find more practical assumptions. Of course, equivalence should be decided for each testcase. What I wished to say is that it should be taken into account. Or perhaps not, if we don't care about the testsuite size, regression testing time and testcases getting silently obsolete. It was more a subtle question that a firm proposal. Here is another question, if I find a testcase in g++.old-deja that is relevant for a patch that I am going to submit, would it be appropriate to move it to g++.dg/X and give it an apter name? For example, if I am preparing testcases such Wsuperwarning-1.C, Wsuperwarning-2.C and I find that g++.old-deja/g++.mike/warn19.C is relevant for -Wsuperwarning, should I do "mv g++.old-deja/g++.mike/warn19.C g++.dg/warn/Wsuperwarning-3.C ? Cheers, Manuel. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: PATCH RFA: C++ frontend warning: comparing function pointer to NULL 2007-01-07 21:12 ` Manuel López-Ibáñez 2007-01-07 22:09 ` Joseph S. Myers @ 2007-01-08 4:18 ` Ian Lance Taylor 1 sibling, 0 replies; 14+ messages in thread From: Ian Lance Taylor @ 2007-01-08 4:18 UTC (permalink / raw) To: Manuel López-Ibáñez Cc: gcc-patches, Gabriel Dos Reis, Andrew Pinski, Mark Mitchell "Manuel López-Ibáñez" <lopezibanez@gmail.com> writes: > On 07 Jan 2007 11:27:59 -0800, Ian Lance Taylor <iant@google.com> wrote: > > "Manuel López-Ibáñez" <lopezibanez@gmail.com> writes: > > > > > Ian added 2 testcases for Walways-true in revision 120493. There are > > > at least 3 existing testcases that also deal with Walways-true: > > > > > > * gcc.dg/20031012-1.c > > > * gcc.dg/weak/weak-3.c > > > * g++.old-deja/g++.mike/warn8.C > > > > > > They were added in revision 108689. > > > > > > Wouldn't it be appropriate to integrate them into the testcases added > > > by Ian and remove any duplicated tests? > > > > Sure. > > Sorry for being such a bother but does this mean "Sure, I will do it" > or "Sure, go ahead and do it" ? Well, I meant "sure, go ahead and do it." But it's also true, as Mark alluded to, that it's inadvisable to modify an existing test (it's OK to modify the tests I just added). I personally think it's OK to actually remove an old test. But I also think you need to run the idea past Janis, the testsuite maintainer. I did look a bit for existing tests, but I managed to miss the ones you mentioned. I didn't even realize there was a gcc.dg/weak subdirectory. Ian ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2007-01-08 4:18 UTC | newest] Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-01-04 15:23 PATCH RFA: C++ frontend warning: comparing function pointer to NULL Ian Lance Taylor 2007-01-04 18:47 ` Andrew Pinski 2007-01-05 2:42 ` Ian Lance Taylor 2007-01-05 5:14 ` Mark Mitchell 2007-01-05 6:58 ` Ian Lance Taylor 2007-01-05 17:45 ` Mark Mitchell 2007-01-05 6:48 ` Gabriel Dos Reis 2007-01-07 13:30 Manuel López-Ibáñez 2007-01-07 13:42 ` Gabriel Dos Reis 2007-01-07 19:28 ` Ian Lance Taylor 2007-01-07 21:12 ` Manuel López-Ibáñez 2007-01-07 22:09 ` Joseph S. Myers 2007-01-07 22:41 ` Manuel López-Ibáñez 2007-01-08 4:18 ` Ian Lance Taylor
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).