From patchwork Mon Aug 20 05:48:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 178662 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 1FDA12C0085 for ; Mon, 20 Aug 2012 15:49:13 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1346046554; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject: References:In-Reply-To:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=2mTW3hO9cIB0Yzdrwl1Mp9BmryA=; b=tvqqTE0bdXKCzDR Vz9aTLI6he1HC1lSGFvQXyg22McH4eyC7fkxe0p+3xWoojh1a6iUQTqPqbi3ddmY 0NQVFwrEi7oollqKMNdSJGOVKrVMFlimixWA5utiD/e2I3OHKPMEvUHztZVbJl8R 3FuKJciQCN4DXJG3s717Z3Dx69TQ= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=CePIyCoYP7oC7pj6hs7ci2OHZ8/1mKTQOHExPZlInSqMDS5sZYV+pH+Z/twvbL ZxzgP7jvQPvaZexmIHI1+jGdyy0t1WkSBpUR5i7n8BGkMZr6ow/cFqjvrWViYjll OtQsNf4DSFNw5xHPWJu6WsMicMjNtTQx0FE4BylA4stcQ=; Received: (qmail 25566 invoked by alias); 20 Aug 2012 05:49:03 -0000 Received: (qmail 25534 invoked by uid 22791); 20 Aug 2012 05:49:01 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RCVD_IN_DNSWL_NONE, RCVD_IN_HOSTKARMA_NO X-Spam-Check-By: sourceware.org Received: from mx02.qsc.de (HELO mx02.qsc.de) (213.148.130.14) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 20 Aug 2012 05:48:46 +0000 Received: from [192.168.178.22] (port-92-204-67-8.dynamic.qsc.de [92.204.67.8]) by mx02.qsc.de (Postfix) with ESMTP id 1C8C827983; Mon, 20 Aug 2012 07:48:44 +0200 (CEST) Message-ID: <5031CFBC.5020306@net-b.de> Date: Mon, 20 Aug 2012 07:48:44 +0200 From: Tobias Burnus User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:14.0) Gecko/20120713 Thunderbird/14.0 MIME-Version: 1.0 To: Thomas Koenig CC: fortran@gcc.gnu.org, gcc-patches Subject: Re: [Patch, Fortran] PR54301 - add warning for pointer might outlive its target References: <50311112.3060908@net-b.de> <50313C4B.4040801@netcologne.de> <50313E08.6070600@net-b.de> <503161AB.4090802@netcologne.de> In-Reply-To: <503161AB.4090802@netcologne.de> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Am 19.08.2012 23:59, schrieb Thomas Koenig: > OK for trunk then. You'll find your patch no longer applies > cleanly, because I have changed the same spot(s) in invoke.texi > and gfortran.h with my recent commit, but I think you'll manage :-) Thanks for the review. I committed the re-diffed patch as Rev. 190522. Tobias 2012-08-20 Tobias Burnus PR fortran/54301 * expr.c (gfc_check_pointer_assign): Warn when the pointer might outlive its target. * gfortran.h (struct gfc_option_t): Add warn_target_lifetime. * options.c (gfc_init_options, set_wall, gfc_handle_option): handle it. * invoke.texi (-Wtarget-lifetime): Document it. (-Wall): Implied it. * lang.opt (-Wtarget-lifetime): New flag. 2012-08-20 Tobias Burnus PR fortran/54301 * gfortran.dg/warn_target_lifetime_1.f90: New. diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c index 7d74528..6f1283d 100644 --- a/gcc/fortran/expr.c +++ b/gcc/fortran/expr.c @@ -3659,6 +3659,38 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue) } } + /* Warn if it is the LHS pointer may lives longer than the RHS target. */ + if (gfc_option.warn_target_lifetime + && rvalue->expr_type == EXPR_VARIABLE + && !rvalue->symtree->n.sym->attr.save + && !attr.pointer && !rvalue->symtree->n.sym->attr.host_assoc + && !rvalue->symtree->n.sym->attr.in_common + && !rvalue->symtree->n.sym->attr.use_assoc + && !rvalue->symtree->n.sym->attr.dummy) + { + bool warn; + gfc_namespace *ns; + + warn = lvalue->symtree->n.sym->attr.dummy + || lvalue->symtree->n.sym->attr.result + || lvalue->symtree->n.sym->attr.host_assoc + || lvalue->symtree->n.sym->attr.use_assoc + || lvalue->symtree->n.sym->attr.in_common; + + if (rvalue->symtree->n.sym->ns->proc_name + && rvalue->symtree->n.sym->ns->proc_name->attr.flavor != FL_PROCEDURE + && rvalue->symtree->n.sym->ns->proc_name->attr.flavor != FL_PROGRAM) + for (ns = rvalue->symtree->n.sym->ns; + ns->proc_name && ns->proc_name->attr.flavor != FL_PROCEDURE; + ns = ns->parent) + if (ns->parent == lvalue->symtree->n.sym->ns) + warn = true; + + if (warn) + gfc_warning ("Pointer at %L in pointer assignment might outlive the " + "pointer target", &lvalue->where); + } + return SUCCESS; } diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index c005151..e796ffe 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h unsigned select_type_temporary:1; @@ -2226,6 +2231,7 @@ typedef struct int warn_realloc_lhs; int warn_realloc_lhs_all; int warn_compare_reals; + int warn_target_lifetime; int max_errors; int flag_all_intrinsics; diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index d962ca0..dfd4ca7 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -147,7 +147,7 @@ and warnings}. -Wimplicit-procedure -Wintrinsic-shadow -Wintrinsics-std @gol -Wline-truncation -Wno-align-commons -Wno-tabs -Wreal-q-constant @gol -Wsurprising -Wunderflow -Wunused-parameter -Wrealloc-lhs Wrealloc-lhs-all @gol --fmax-errors=@var{n} -fsyntax-only -pedantic -pedantic-errors +-Wtarget-lifetime -fmax-errors=@var{n} -fsyntax-only -pedantic -pedantic-errors } @item Debugging Options @@ -729,8 +729,8 @@ we recommend avoiding and that we believe are easy to avoid. This currently includes @option{-Waliasing}, @option{-Wampersand}, @option{-Wconversion}, @option{-Wcompare-reals}, @option{-Wsurprising}, @option{-Wintrinsics-std}, @option{-Wno-tabs}, @option{-Wintrinsic-shadow}, -@option{-Wline-truncation}, @option{-Wreal-q-constant} and -@option{-Wunused}. +@option{-Wline-truncation}, @option{-Wtarget-lifetime}, +@option{-Wreal-q-constant} and @option{-Wunused}. @item -Waliasing @opindex @code{Waliasing} @@ -941,6 +941,11 @@ allocatable variable; this includes scalars and derived types. Warn when comparing real or complex types for equality or inequality. Enabled by @option{-Wall}. +@item -Wtarget-lifetime +@opindex @code{Wtargt-lifetime} +Warn if the pointer in a pointer assignment might be longer than the its +target. This option is implied by @option{-Wall}. + @item -Werror @opindex @code{Werror} @cindex warnings, to errors diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index e0c7cf7..b38b1e8 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -262,6 +262,10 @@ Wrealloc-lhs-all Fortran Warning Warn when a left-hand-side variable is reallocated +Wtarget-lifetime +Fortran Warning +Warn if the pointer in a pointer assignment might outlive its target + Wreturn-type Fortran Warning ; Documented in C diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index 3e4444d..cbec705 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -114,6 +114,7 @@ gfc_init_options (unsigned int decoded_options_count, gfc_option.warn_realloc_lhs = 0; gfc_option.warn_realloc_lhs_all = 0; gfc_option.warn_compare_reals = 0; + gfc_option.warn_target_lifetime = 0; gfc_option.max_errors = 25; gfc_option.flag_all_intrinsics = 0; @@ -475,6 +476,7 @@ set_Wall (int setting) gfc_option.warn_real_q_constant = setting; gfc_option.warn_unused_dummy_argument = setting; gfc_option.warn_compare_reals = setting; + gfc_option.warn_target_lifetime = setting; warn_return_type = setting; warn_switch = setting; @@ -688,6 +690,10 @@ gfc_handle_option (size_t scode, const char *arg, int value, gfc_option.warn_tabs = value; break; + case OPT_Wtarget_lifetime: + gfc_option.warn_target_lifetime = value; + break; + case OPT_Wunderflow: gfc_option.warn_underflow = value; break; --- /dev/null 2012-08-16 07:16:46.391724752 +0200 +++ gcc/gcc/testsuite/gfortran.dg/warn_target_lifetime_1.f90 2012-08-19 16:12:58.000000000 +0200 @@ -0,0 +1,47 @@ +! { dg-do compile } +! { dg-options "-Wtarget-lifetime" } +! +! PR fortran/54301 +! +function f () result (ptr) + integer, pointer :: ptr(:) + integer, allocatable, target :: a(:) + allocate(a(5)) + + ptr => a ! { dg-warning "Pointer at .1. in pointer assignment might outlive the pointer target" } + a = [1,2,3,4,5] +end function + + +subroutine foo() + integer, pointer :: ptr(:) + call bar () +contains + subroutine bar () + integer, target :: tgt(5) + ptr => tgt ! { dg-warning "Pointer at .1. in pointer assignment might outlive the pointer target" } + end subroutine bar +end subroutine foo + +function foo3(tgt) + integer, target :: tgt + integer, pointer :: foo3 + foo3 => tgt +end function + +subroutine sub() + implicit none + integer, pointer :: ptr + integer, target :: tgt + ptr => tgt + + block + integer, pointer :: p2 + integer, target :: tgt2 + p2 => tgt2 + p2 => tgt + ptr => p2 + ptr => tgt + ptr => tgt2 ! { dg-warning "Pointer at .1. in pointer assignment might outlive the pointer target" } + end block +end subroutine sub