From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22229 invoked by alias); 4 Jan 2007 15:23:12 -0000 Received: (qmail 22221 invoked by uid 22791); 4 Jan 2007 15:23:11 -0000 X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.45.13) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 04 Jan 2007 15:23:03 +0000 Received: from zps38.corp.google.com (zps38.corp.google.com [172.25.146.38]) by smtp-out.google.com with ESMTP id l04FN0dl023731 for ; Thu, 4 Jan 2007 07:23:00 -0800 Received: from smtp.corp.google.com (spacemonkey1.corp.google.com [192.168.120.115]) by zps38.corp.google.com with ESMTP id l04FMhcR021038 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Thu, 4 Jan 2007 07:22:43 -0800 Received: from localhost.localdomain.google.com (90.sub-75-209-52.myvzw.com [75.209.52.90]) (authenticated bits=0) by smtp.corp.google.com (8.13.7/8.13.7) with ESMTP id l04FMe6r028566 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT) for ; Thu, 4 Jan 2007 07:22:42 -0800 To: gcc-patches@gcc.gnu.org Subject: PATCH RFA: C++ frontend warning: comparing function pointer to NULL From: Ian Lance Taylor Date: Thu, 04 Jan 2007 15:23:00 -0000 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.4 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-01/txt/msg00234.txt.bz2 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 * typeck.c (build_binary_op): Warn about comparing a non-weak address to NULL. testsuite/ChangeLog: 2007-01-04 Ian Lance Taylor * 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 + +// { 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 + +// { 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); +}