From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 101805 invoked by alias); 27 Nov 2015 18:55:54 -0000 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 Received: (qmail 101788 invoked by uid 89); 27 Nov 2015 18:55:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 27 Nov 2015 18:55:52 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 1163CC0B7ABD; Fri, 27 Nov 2015 18:55:51 +0000 (UTC) Received: from redhat.com (ovpn-204-108.brq.redhat.com [10.40.204.108]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tARItiUj007817 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 27 Nov 2015 13:55:48 -0500 Date: Fri, 27 Nov 2015 19:02:00 -0000 From: Marek Polacek To: GCC Patches , Joseph Myers , Jakub Jelinek , Richard Biener Subject: [PATCH] Add save_expr langhook (PR c/68513) Message-ID: <20151127185531.GA28072@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-SW-Source: 2015-11/txt/msg03397.txt.bz2 As suggested here and here , this patch adds a new langhook to distinguish whether to call c_save_expr or save_expr from match.pd. Does this look reasonable? I didn't know where to put setting of in_late_processing. With the current placement, we won't (for valid programs) call c_save_expr from c_genericize or c_gimplify_expr. I suppose I should also modify save_expr in fold-const.c to call it via the langhook, if this approach is sane. Dunno. Bootstrapped/regtested on x86_64-linux. 2015-11-27 Marek Polacek PR c/68513 * c-common.c (in_late_processing): New global. (c_common_save_expr): New function. * c-common.h (in_late_processing, c_common_save_expr): Declare. * c-objc-common.h (LANG_HOOKS_SAVE_EXPR): Define. * c-parser.c (c_parser_compound_statement): Set IN_LATE_PROCESSING. * generic-match-head.c: Include "langhooks.h". * genmatch.c (dt_simplify::gen_1): Call save_expr via langhook. * langhooks-def.h (LANG_HOOKS_SAVE_EXPR): Define. * langhooks.h (struct lang_hooks): Add save_expr langhook. * gcc.dg/torture/pr68513.c: New test. diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c index fe0a235..850bee9 100644 --- gcc/c-family/c-common.c +++ gcc/c-family/c-common.c @@ -271,6 +271,12 @@ int c_inhibit_evaluation_warnings; be generated. */ bool in_late_binary_op; +/* When true, all the constant expression checks from parsing should have been + done. This is used so that fold knows whether to call c_save_expr (thus + c_fully_fold is called on the expression), or whether to call save_expr via + c_common_save_expr langhook. */ +bool in_late_processing; + /* Whether lexing has been completed, so subsequent preprocessor errors should use the compiler's input_location. */ bool done_lexing = false; @@ -4928,6 +4934,15 @@ c_save_expr (tree expr) return expr; } +/* The C version of the save_expr langhook. Either call save_expr or c_save_expr, + depending on IN_LATE_PROCESSING. */ + +tree +c_common_save_expr (tree expr) +{ + return in_late_processing ? save_expr (expr) : c_save_expr (expr); +} + /* Return whether EXPR is a declaration whose address can never be NULL. */ diff --git gcc/c-family/c-common.h gcc/c-family/c-common.h index bad8d05..e2d4ba9 100644 --- gcc/c-family/c-common.h +++ gcc/c-family/c-common.h @@ -771,6 +771,7 @@ extern void c_register_addr_space (const char *str, addr_space_t as); /* In c-common.c. */ extern bool in_late_binary_op; +extern bool in_late_processing; extern const char *c_addr_space_name (addr_space_t as); extern tree identifier_global_value (tree); extern tree c_linkage_bindings (tree); @@ -812,6 +813,7 @@ extern tree c_fully_fold (tree, bool, bool *); extern tree decl_constant_value_for_optimization (tree); extern tree c_wrap_maybe_const (tree, bool); extern tree c_save_expr (tree); +extern tree c_common_save_expr (tree); extern tree c_common_truthvalue_conversion (location_t, tree); extern void c_apply_type_quals_to_decl (int, tree); extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int); diff --git gcc/c/c-objc-common.h gcc/c/c-objc-common.h index 50c9f54..9fd3722 100644 --- gcc/c/c-objc-common.h +++ gcc/c/c-objc-common.h @@ -60,6 +60,8 @@ along with GCC; see the file COPYING3. If not see #define LANG_HOOKS_BUILTIN_FUNCTION c_builtin_function #undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE #define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE c_builtin_function_ext_scope +#undef LANG_HOOKS_SAVE_EXPR +#define LANG_HOOKS_SAVE_EXPR c_common_save_expr /* Attribute hooks. */ #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE diff --git gcc/c/c-parser.c gcc/c/c-parser.c index 0259f66..3f7c458 100644 --- gcc/c/c-parser.c +++ gcc/c/c-parser.c @@ -4586,6 +4586,9 @@ c_parser_compound_statement (c_parser *parser) { tree stmt; location_t brace_loc; + + in_late_processing = false; + brace_loc = c_parser_peek_token (parser)->location; if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) { @@ -4598,6 +4601,9 @@ c_parser_compound_statement (c_parser *parser) stmt = c_begin_compound_stmt (true); c_parser_compound_statement_nostart (parser); + /* From now on, the fold machinery shouldn't call c_save_expr. */ + in_late_processing = true; + /* If the compound stmt contains array notations, then we expand them. */ if (flag_cilkplus && contains_array_notation_expr (stmt)) stmt = expand_array_notation_exprs (stmt); diff --git gcc/generic-match-head.c gcc/generic-match-head.c index f55f91e..8fc9d40 100644 --- gcc/generic-match-head.c +++ gcc/generic-match-head.c @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "dumpfile.h" #include "case-cfn-macros.h" +#include "langhooks.h" /* Routine to determine if the types T1 and T2 are effectively diff --git gcc/genmatch.c gcc/genmatch.c index 67d1c66..c73a94d 100644 --- gcc/genmatch.c +++ gcc/genmatch.c @@ -3114,7 +3114,8 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result) continue; if (cinfo.info[i].result_use_count > 1) fprintf_indent (f, indent, - "captures[%d] = save_expr (captures[%d]);\n", + "captures[%d] = lang_hooks.save_expr " + "(captures[%d]);\n", i, i); } for (unsigned j = 0; j < e->ops.length (); ++j) diff --git gcc/langhooks-def.h gcc/langhooks-def.h index 18ac84d..6f5babe 100644 --- gcc/langhooks-def.h +++ gcc/langhooks-def.h @@ -120,6 +120,7 @@ extern bool lhd_omp_mappable_type (tree); #define LANG_HOOKS_BLOCK_MAY_FALLTHRU hook_bool_const_tree_true #define LANG_HOOKS_EH_USE_CXA_END_CLEANUP false #define LANG_HOOKS_DEEP_UNSHARING false +#define LANG_HOOKS_SAVE_EXPR save_expr /* Attribute hooks. */ #define LANG_HOOKS_ATTRIBUTE_TABLE NULL @@ -313,7 +314,8 @@ extern void lhd_end_section (void); LANG_HOOKS_EH_PROTECT_CLEANUP_ACTIONS, \ LANG_HOOKS_BLOCK_MAY_FALLTHRU, \ LANG_HOOKS_EH_USE_CXA_END_CLEANUP, \ - LANG_HOOKS_DEEP_UNSHARING \ + LANG_HOOKS_DEEP_UNSHARING, \ + LANG_HOOKS_SAVE_EXPR \ } #endif /* GCC_LANG_HOOKS_DEF_H */ diff --git gcc/langhooks.h gcc/langhooks.h index d8d01fa..18f332d 100644 --- gcc/langhooks.h +++ gcc/langhooks.h @@ -488,6 +488,9 @@ struct lang_hooks gimplification. */ bool deep_unsharing; + /* Used by the fold machinery to either call save_expr or c_save_expr. */ + tree (*save_expr) (tree); + /* Whenever you add entries here, make sure you adjust langhooks-def.h and langhooks.c accordingly. */ }; diff --git gcc/testsuite/gcc.dg/torture/pr68513.c gcc/testsuite/gcc.dg/torture/pr68513.c index e69de29..4e08b29 100644 --- gcc/testsuite/gcc.dg/torture/pr68513.c +++ gcc/testsuite/gcc.dg/torture/pr68513.c @@ -0,0 +1,13 @@ +/* PR c/68513 */ +/* { dg-do compile } */ + +int i; +unsigned u; +volatile unsigned int *e; + +void +fn1 (void) +{ + (short) ((i ? *e : 0) & ~u | i & u); + (short) (((0, 0) ? *e : 0) & ~u | i & u); +} Marek