From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5607 invoked by alias); 30 May 2010 00:22:34 -0000 Received: (qmail 5595 invoked by uid 22791); 30 May 2010 00:22:32 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp.gentoo.org (HELO smtp.gentoo.org) (140.211.166.183) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 30 May 2010 00:22:19 +0000 Received: from laptop1.localnet (ip1-67.bon.riksnet.se [77.110.8.67]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTP id BD6621B4042 for ; Sun, 30 May 2010 00:22:17 +0000 (UTC) From: Magnus Granberg To: gcc-patches@gcc.gnu.org Subject: Re: [patch] Add new warning -Wtrampolines Date: Sun, 30 May 2010 07:16:00 -0000 User-Agent: KMail/1.12.4 (Linux/2.6.32-gentoo-r6; KDE/4.3.5; x86_64; ; ) References: <201005060146.34151.zorry@gentoo.org> <201005060924.46313.ebotcazou@adacore.com> In-Reply-To: <201005060924.46313.ebotcazou@adacore.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-Id: <201005300221.54165.zorry@gentoo.org> 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: 2010-05/txt/msg02353.txt.bz2 torsdag 06 maj 2010 09.24.46 skrev Eric Botcazou: > It would be better to issue it from > tree-nested.c:convert_tramp_reference_op so that it is attached to the > token that causes it to be created. For extra points, you could even make > it reference the nested function: > > p2.adb: In function 'P2': > p2.adb:17:12: warning: trampoline generated for 'P2.F' > p2.adb:26:11: warning: address taken from here > Have updated the patch to make two warnings one for the trampoline and the second one for makeing the stack executable. Did't add the reference to the nested function for extra points. Could not get the testcase ignore the second warning in the same line. Hardened at gentoo.org Magnus Granberg (Zorry) gcc/ 2010-05-06 Magnus Granberg , Kevin F. Quinn * tree-nested: #include flags.h (convert_tramp_reference_op): if warn_trampolines make a warning. * common.opt: Add -Wtrampolines. * varasm.c: (file_end_indicate_exec_stack): if warn_trampolines make a warning. gcc/doc 2010-05-06 Magnus Granberg * invoke.texi: Add -Wtrampolines. gcc/testsuite/ 2010-05-06 Magnus Granberg * gcc.dg/Wtrampolines.c: New. ---- --- gcc/tree-nested.c.zorry 2009-11-25 11:55:54.000000000 +0100 +++ gcc/tree-nested.c 2010-05-29 14:49:13.000000000 +0200 @@ -36,6 +36,7 @@ #include "langhooks.h" #include "pointer-set.h" #include "ggc.h" +#include "flags.h" /* The object of this pass is to lower the representation of a set of nested @@ -1913,6 +1914,9 @@ x = init_tmp_var (info, x, &wi->gsi); *tp = x; + if (warn_trampolines) + warning (OPT_Wtrampolines, "generating trampoline in object."); + break; default: --- gcc/common.opt.zorry 2010-03-18 04:01:09.000000000 +0100 +++ gcc/common.opt 2010-05-06 00:44:18.000000000 +0200 @@ -192,6 +192,10 @@ Common Var(warn_system_headers) Warning Do not suppress warnings from system headers +Wtrampolines +Common Var(warn_trampolines) Warnings +Warn whenever a trampoline is generated and warn if it requires executable stack to + Wtype-limits Common Var(warn_type_limits) Init(-1) Warning Warn if a comparison is always true or always false due to the limited range of the data type --- gcc/varasm.c.zorry 2010-03-27 12:56:30.000000000 +0100 +++ gcc/varasm.c 2010-05-29 15:06:33.000000000 +0200 @@ -6768,7 +6768,11 @@ { unsigned int flags = SECTION_DEBUG; if (trampolines_created) + { flags |= SECTION_CODE; + if (warn_trampolines) + warning (OPT_Wtrampolines, "setting the stack as executable stack"); + } switch_to_section (get_section (".note.GNU-stack", flags, NULL)); } --- gcc/doc/invoke.texi.zorry 2010-04-06 16:02:22.000000000 +0200 +++ gcc/doc/invoke.texi 2010-05-06 00:20:25.000000000 +0200 @@ -258,8 +258,8 @@ -Wstrict-aliasing -Wstrict-aliasing=n @gol -Wstrict-overflow -Wstrict-overflow=@var{n} @gol -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol --Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized @gol --Wunknown-pragmas -Wno-pragmas @gol +-Wsystem-headers -Wtrampolines -Wtrigraphs -Wtype-limits -Wundef @gol +-Wuninitialized -Wunknown-pragmas -Wno-pragmas @gol -Wunsuffixed-float-constants -Wunused -Wunused-function @gol -Wunused-label -Wunused-parameter -Wno-unused-result -Wunused-value -Wunused-variable @gol -Wvariadic-macros -Wvla @gol @@ -3603,6 +3603,19 @@ option will @emph{not} warn about unknown pragmas in system headers---for that, @option{-Wunknown-pragmas} must also be used. +@item -Wtrampolines +@opindex Wtrampolines +@opindex Wno-trampolines + Warn about trampolines generated for pointers to nested functions. + Warn when the trampoline requires the stack to be made executable. + + A trampoline is a small piece of data or code that is created at run + time on the stack when the address of a nested function is taken, and + is used to call the nested function indirectly. For some targets, it + is made up of data only and thus requires no special treatment. But, + for most targets, it is made up of code and thus requires the stack + to be made executable in order for the program to work properly. + @item -Wfloat-equal @opindex Wfloat-equal @opindex Wno-float-equal --- gcc/testsuite/gcc.dg/Wtrampolines.c.zorry 2010-05-05 12:53:11.000000000 +0200 +++ gcc/testsuite/gcc.dg/Wtrampolines.c 2010-05-06 00:26:05.000000000 +0200 @@ -0,0 +1,58 @@ +/* Origin: trampoline-1.c Waldek Hebisch */ +/* Ported to test -Wtrampolines Magnus Granberg */ + +/* { dg-do compile } */ +/* { dg-require-effective-target trampolines } */ +/* { dg-options "-O2 -Wtrampolines" } */ +/* { dg-warning "trampoline|stack" "" { target i?86-*-* x86_64-*-* } 58 } */ + +#ifndef NO_TRAMPOLINES + +/* This used to fail on various versions of Solaris 2 because the + trampoline couldn't be made executable. */ + +extern void abort(void); +extern double fabs(double); + +void foo (void) +{ + const int correct[1100] = {1, 0, -2, 0, 1, 0, 1, -1, -10, -30, -67}; + int i; + + double x1 (void) {return 1; } + double x2 (void) {return -1;} + double x3 (void) {return -1;} + double x4 (void) {return 1; } + double x5 (void) {return 0; } + + typedef double pfun(void); + + double a (int k, pfun x1, pfun x2, pfun x3, pfun x4, pfun x5) + { + double b (void) + { + k = k - 1; + return a (k, b, x1, x2, x3, x4 ); + } + + if (k <= 0) + return x4 () + x5 (); + else + return b (); + } + + for (i=0; i<=10; i++) + { + if (fabs(a( i, x1, x2, x3, x4, x5 ) - correct [i]) > 0.1) + abort(); + } +} +#endif + +int main (void) +{ +#ifndef NO_TRAMPOLINES + foo (); +#endif + return 0; +}