From patchwork Wed Dec 22 15:54:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 76428 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 1A0BBB70AF for ; Thu, 23 Dec 2010 02:54:29 +1100 (EST) Received: (qmail 30275 invoked by alias); 22 Dec 2010 15:54:26 -0000 Received: (qmail 30259 invoked by uid 22791); 22 Dec 2010 15:54:25 -0000 X-SWARE-Spam-Status: No, hits=0.9 required=5.0 tests=AWL, BAYES_80, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST, TW_CX X-Spam-Check-By: sourceware.org Received: from mail-qw0-f47.google.com (HELO mail-qw0-f47.google.com) (209.85.216.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 22 Dec 2010 15:54:18 +0000 Received: by qwg5 with SMTP id 5so5206415qwg.20 for ; Wed, 22 Dec 2010 07:54:16 -0800 (PST) MIME-Version: 1.0 Received: by 10.229.190.147 with SMTP id di19mr6219712qcb.209.1293033255991; Wed, 22 Dec 2010 07:54:15 -0800 (PST) Received: by 10.229.137.136 with HTTP; Wed, 22 Dec 2010 07:54:15 -0800 (PST) In-Reply-To: References: <4D1204AB.40603@gmail.com> Date: Wed, 22 Dec 2010 16:54:15 +0100 Message-ID: Subject: Re: [patch c, c++, i386]:PR/15774 - Conflicting function decls not diagnosed From: Kai Tietz To: Gabriel Dos Reis Cc: Dave Korn , GCC Patches , "Joseph S. Myers" , Jason Merrill , Richard Henderson X-IsSubscribed: yes 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 2010/12/22 Gabriel Dos Reis : > On Wed, Dec 22, 2010 at 9:34 AM, Kai Tietz wrote: >> 2010/12/22 Gabriel Dos Reis : >>> Any reason why is_first is of type `int' as opposed to `bool'? >>> rename pp_c_attributes_calling_convention to >>> pp_c_calling_convention_attributes. >>> You should probably modify cp/cxx-pretty-print.c too >> >> Well, I was first think here to implement logic different, but you are >> right, bool is better here. I adjusted patch. Also renamed function. >> >>> I really prefer we don't add pretty printing code to cp/error.c. >>> Rather, we should be deferring to the pretty printers in >>> cp/cxx-pretty-print.c.  But, I suspect that is a battle for >>> another day. >> >> Well, I tried to do thing here first in cxx-pretty-print.c, but it >> doesn't had any effect for function pointers, so I did it just in >> error.c file.  This seems to be a different battle for a different >> day. > > The problem is we are going to have the same regression when > the cp/error.c to what it should be (as originally plan). > So, my suggestion to is to add similar code to cp/cxx-pretty-print.c. > Patch approved with that modification. > Good, I added code to cp/cxx-pretty-print.c (pp_cxx_ptr_operator). Regards, Kai Index: gcc/gcc/c-family/c-pretty-print.c =================================================================== --- gcc.orig/gcc/c-family/c-pretty-print.c 2010-12-22 16:29:55.231892000 +0100 +++ gcc/gcc/c-family/c-pretty-print.c 2010-12-22 16:39:57.923249700 +0100 @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. #include "tree-pretty-print.h" #include "tree-iterator.h" #include "diagnostic.h" +#include "target.h" /* Translate if being used for diagnostics, but not for dump files or __PRETTY_FUNCTION. */ @@ -460,6 +461,7 @@ pp_c_specifier_qualifier_list (c_pretty_ { pp_c_whitespace (pp); pp_c_left_paren (pp); + pp_c_calling_convention_attributes (pp, TYPE_ATTRIBUTES (pointee)); } else if (!c_dialect_cxx ()) pp_c_whitespace (pp); @@ -790,6 +792,45 @@ pp_c_attributes (c_pretty_printer *pp, t pp_c_right_paren (pp); } +/* Pretty-print ATTRIBUTES using GNU C extension syntax for calling + convention affecting attributes. */ + +void +pp_c_calling_convention_attributes (c_pretty_printer *pp, tree a) +{ + bool is_first = true; + + if (a == NULL_TREE) + return; + + for (; a != NULL_TREE; a = TREE_CHAIN (a)) + { + if (!targetm.attribute_affects_calling_convention (TREE_PURPOSE (a))) + continue; + if (is_first) + { + pp_c_ws_string (pp, "__attribute__"); + pp_c_left_paren (pp); + pp_c_left_paren (pp); + is_first = false; + } + else + { + pp_separate_with (pp, ','); + } + pp_tree_identifier (pp, TREE_PURPOSE (a)); + if (TREE_VALUE (a)) + pp_c_call_argument_list (pp, TREE_VALUE (a)); + } + + if (!is_first) + { + pp_c_right_paren (pp); + pp_c_right_paren (pp); + pp_c_whitespace (pp); + } +} + /* function-definition: declaration-specifiers declarator compound-statement */ Index: gcc/gcc/cp/error.c =================================================================== --- gcc.orig/gcc/cp/error.c 2010-12-22 16:29:55.237892000 +0100 +++ gcc/gcc/cp/error.c 2010-12-22 16:39:58.001375200 +0100 @@ -661,6 +661,8 @@ dump_type_prefix (tree t, int flags) { pp_cxx_whitespace (cxx_pp); pp_cxx_left_paren (cxx_pp); + pp_c_calling_convention_attributes (pp_c_base (cxx_pp), + TYPE_ATTRIBUTES (sub)); } if (TREE_CODE (t) == POINTER_TYPE) pp_character(cxx_pp, '*'); Index: gcc/gcc/c-family/c-pretty-print.h =================================================================== --- gcc.orig/gcc/c-family/c-pretty-print.h 2010-12-22 16:29:55.232892000 +0100 +++ gcc/gcc/c-family/c-pretty-print.h 2010-12-22 16:39:58.032625400 +0100 @@ -176,6 +176,7 @@ void pp_c_space_for_pointer_operator (c_ void pp_c_tree_decl_identifier (c_pretty_printer *, tree); void pp_c_function_definition (c_pretty_printer *, tree); void pp_c_attributes (c_pretty_printer *, tree); +void pp_c_calling_convention_attributes (c_pretty_printer *, tree); void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type); void pp_c_type_qualifier_list (c_pretty_printer *, tree); void pp_c_parameter_type_list (c_pretty_printer *, tree); Index: gcc/gcc/config/i386/i386.c =================================================================== --- gcc.orig/gcc/config/i386/i386.c 2010-12-22 16:29:55.235892000 +0100 +++ gcc/gcc/config/i386/i386.c 2010-12-22 16:39:58.048250500 +0100 @@ -5116,6 +5116,46 @@ ix86_function_ok_for_sibcall (tree decl, return true; } +static bool +ix86_attribute_affects_calling_convention (tree name) +{ + int ident_len; + const char *p; + + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + p = IDENTIFIER_POINTER (name); + ident_len = IDENTIFIER_LENGTH (name); + + if (ident_len > 4 && p[0] == '_' && p[1] == '_' && p[ident_len - 1] == '_' + && p[ident_len - 2] == '_') + { + ident_len -= 4; + p += 2; + } + switch (ident_len) + { + case 5: + if (!strncmp (p, "cdecl", 5)) + return true; + break; + case 6: + if (!strncmp (p, "ms_abi", 6)) + return true; + break; + case 7: + if (!strncmp (p, "regparm", 7) || !strncmp (p, "stdcall", 7)) + return true; + break; + case 8: + if (!strncmp (p, "thiscall", 8) || !strncmp (p, "fastcall", 8) + || !strncmp (p, "sysv_abi", 8)) + return true; + break; + } + + return false; +} + /* Handle "cdecl", "stdcall", "fastcall", "regparm", "thiscall", and "sseregparm" calling convention attributes; arguments as in struct attribute_spec.handler. */ @@ -34813,6 +34853,10 @@ ix86_autovectorize_vector_sizes (void) #undef TARGET_CONDITIONAL_REGISTER_USAGE #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage +#undef TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION +#define TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION \ + ix86_attribute_affects_calling_convention + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-i386.h" Index: gcc/gcc/doc/tm.texi =================================================================== --- gcc.orig/gcc/doc/tm.texi 2010-12-22 16:29:55.239892000 +0100 +++ gcc/gcc/doc/tm.texi 2010-12-22 16:39:58.157626200 +0100 @@ -9765,6 +9765,10 @@ to perform initial processing of the @sa @file{i386/i386.c}, for example. @end deftypefn +@deftypefn {Target Hook} bool TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION (const_tree @var{name}) +Returns @code{true} if given attribute by its @var{name} affects calling convention, otherwise @code{false}. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_VALID_DLLIMPORT_ATTRIBUTE_P (const_tree @var{decl}) @var{decl} is a variable or function with @code{__attribute__((dllimport))} specified. Use this hook if the target needs to add extra validation checks to @code{handle_dll_attribute}. @end deftypefn Index: gcc/gcc/doc/tm.texi.in =================================================================== --- gcc.orig/gcc/doc/tm.texi.in 2010-12-22 16:29:55.241892000 +0100 +++ gcc/gcc/doc/tm.texi.in 2010-12-22 16:39:58.282627000 +0100 @@ -9729,6 +9729,8 @@ to perform initial processing of the @sa @file{i386/i386.c}, for example. @end deftypefn +@hook TARGET_ATTRIBUTE_AFFECTS_CALLING_CONVENTION + @hook TARGET_VALID_DLLIMPORT_ATTRIBUTE_P @defmac TARGET_DECLSPEC Index: gcc/gcc/target.def =================================================================== --- gcc.orig/gcc/target.def 2010-12-22 16:29:55.243892000 +0100 +++ gcc/gcc/target.def 2010-12-22 16:39:58.282627000 +0100 @@ -1113,6 +1113,14 @@ DEFHOOK tree, (tree olddecl, tree newdecl), merge_decl_attributes) +/* Return true iff attribute NAME affects calling convention. */ +DEFHOOK +(attribute_affects_calling_convention, + "Returns @code{true} if given attribute by its @var{name} affects calling\ + convention, otherwise @code{false}.", + bool, (const_tree name), + hook_bool_const_tree_false) + /* Given two types, merge their attributes and return the result. */ DEFHOOK (merge_type_attributes, Index: gcc/gcc/cp/cxx-pretty-print.c =================================================================== --- gcc.orig/gcc/cp/cxx-pretty-print.c 2010-12-22 12:10:20.000000000 +0100 +++ gcc/gcc/cp/cxx-pretty-print.c 2010-12-22 16:48:14.020174700 +0100 @@ -1323,6 +1323,9 @@ pp_cxx_ptr_operator (cxx_pretty_printer if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t))) pp_cxx_ptr_operator (pp, TREE_TYPE (t)); + pp_c_calling_convention_attributes (pp_c_base (pp), + TYPE_ATTRIBUTES (TREE_TYPE (t))); + if (TREE_CODE (t) == POINTER_TYPE) { pp_star (pp);