From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by sourceware.org (Postfix) with ESMTPS id C9EE73887F58; Sat, 12 Nov 2022 23:45:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C9EE73887F58 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-x436.google.com with SMTP id j15so11174710wrq.3; Sat, 12 Nov 2022 15:45:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=euAEkroHDF9ZrysehMQWRPmbvvXsU0rToCnB47jsM/8=; b=Mxi8uugygaJFN2m1DBj8A/zpE2bVfuqtfFAmjj2+WV2QZNb3nkz/yA15OadVNrCI4S aLO1ooCraRfQ2C5X8oEWA2MWUV2yvNQU8pjQpUz3c6GR/uBzg3GJFkvPpMtFTfZii2xh XRUrh6LUlUJMByimzvxJycwraAc9a3R9CE3HoS0ZrWH40xDTmZiCwjfpuqNGcIpb205O KhRbN9DeW5LoUmu20+pJKJPpdTwU4zj1BY1ZEEKyeQFOOo0Hc/yK9/AmgOOuP3PsvXfT EklcL8Oi74cDLbbuGSzqKpxWXZudrvNGyH4mGqdOEJBDwhDNbU2iFYUyFcftefADYFZr YE7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=euAEkroHDF9ZrysehMQWRPmbvvXsU0rToCnB47jsM/8=; b=LoigYdF3NZmVM3sdMwhcFERvzRRt+sp5AwUSKRP9ZWtaLVv7jQyVxVE0diqQbdH/2Z x8Ck9SC8uYMp2hnyiIX4hbgb86j+yGqOgryXQ6+PGEy3QyH0DvIuoE+0f+1j314grCYL PyOuhwwKTVlRdvTHWzBy8Qvt8Ym/MKNpRn4oGDKDzYey0fe1gjwFcDlRd+8CLV6jozA7 hciNoV811wbwfQFgtkI2u1SWrEjkeF4EmJFQS79XTYZFITyKcOAaXnuF+Bg615dtDyz4 3A4Nh0wa6FM1nGuGzIaEyGgEs7jmHmqrVs9dtCtoTU6M/RM7g/dCRKF5Z6acA6wP32dn RU6Q== X-Gm-Message-State: ANoB5pnLy0cofABIuiooOD/rsmYOYHfUvyMnGtavV/N3fxKIWEJJn+j8 z8N0L0ZAHHvrkKNbdVcUXkKyKMtrDNo= X-Google-Smtp-Source: AA0mqf5P9t9KTECCUUc2Iw/Yqx0Bet8Sb9XireAmr62A5Av5b58y5NqvUzUMZzZLCvFOOy7eXmuNgg== X-Received: by 2002:a5d:5914:0:b0:236:6a5b:5610 with SMTP id v20-20020a5d5914000000b002366a5b5610mr4273495wrd.195.1668296748494; Sat, 12 Nov 2022 15:45:48 -0800 (PST) Received: from nbbrfq ([2001:871:227:81c4:d7ff:3a0e:48da:5fe3]) by smtp.gmail.com with ESMTPSA id m16-20020a05600c3b1000b003a3170a7af9sm8456544wms.4.2022.11.12.15.45.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 12 Nov 2022 15:45:45 -0800 (PST) From: Bernhard Reutner-Fischer X-Google-Original-From: Bernhard Reutner-Fischer Received: from b by nbbrfq with local (Exim 4.96) (envelope-from ) id 1ou0C0-000Opl-3D; Sun, 13 Nov 2022 00:45:44 +0100 To: gcc-patches@gcc.gnu.org Cc: Bernhard Reutner-Fischer , Bernhard Reutner-Fischer , fortran@gcc.gnu.org, David Malcolm , Aldy Hernandez , Jason Merrill Subject: [PATCH 0/5] function result decl location; type demotion Date: Sun, 13 Nov 2022 00:45:38 +0100 Message-Id: <20221112234543.95441-1-aldot@gcc.gnu.org> X-Mailer: git-send-email 2.38.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi! The location of function result declarations was not set. The first two patches set the location of normal functions in C and C++. Jason, Nathan, I failed to support C++ template functions, see below. TL;DR. Why all this? PR78798 noted that we should use narrower function return types if feasable. So one idea to bring that idea forward is to determine the range a function can return and match that range against the range provided by the actual return type. If we waste bits, warn and, ideally, suggest a better alternative. Ideally with a fix-it hint for the narrower type and with a patch. David's tremendously useful work on diagnostics makes both user-facing aspecs rather easy to achieve (thanks, once again, David!). Ideally, one would be able to accumulate such suggested fix-it hints driven patches by stating something like: ... -Wtype-demotion -fdiagnostics-generate-patch=>>/tmp/hmz.patch i.e. have ways to direct the ...-generate-patch to creat/append to some given path. But that doesn't seem to work for me or i did not read the documentation carefully enough. awk to the rescue for the full buildlog output to extract the patch(es) but not all that userfriendly i fear. How would i write a combined patch out to some given path, David? Patch 1 handles locations for the C FE, this works perfectly fine. Patch 2 handles locations for normal, non-template functions in C++ and these work fine, too. Patch 3, the actual Fortran bits work fine and are sound (good job, Aldy and Andrew!) Patch 4 is a way to print the actual range to some diagnostics. I wrote this about a year ago when only irange was available. And from what i've heared, it's doubtful if such an as_string() is considered useful. So i post it just for reference and don't ask for inclusion of such a facility. Nevertheless i think that would be useful if not just for debugging and dumping (but please to a buffer, too, so one can hijack it ;) Patch5 is not to be merged for obvious reasons. It is way too chatty, doesn't run in IPA so probably ruins any "comparer" like function. I've compiled one or two userspace, integer programs and it is not completely off, from the looks. C++ template functions. ======================= I couldn't make this work, the mechanics in start_preparsed_function are beyond what i could grok in a couple of evenings TBH. Can you maybe help, Json or Nathan? I tried several spots. Directly in start_preparsed_function, in grokmethod, grokfndecl after type = build_cp_fntype_variant, in grokfndecl if (funcdef_flag), in finish_function but to no avail. To me it seems that most locations are unset/ broken in the C++ FE for the template path, or, more likely, i'm unable to operate them properly to be fair. I even tried the enterprise-level idea to get something vaguely around the result decl in a template by (please don't cite me): @@ -18214,6 +18260,17 @@ grokmethod (cp_decl_specifier_seq *declspecs, DECL_NO_INLINE_WARNING_P (fndecl) = 1; } + /* Set the location of the result decl, approximately. */ + tree result; + if ((result = DECL_RESULT (fndecl)) + && DECL_SOURCE_LOCATION (result) == UNKNOWN_LOCATION) + for (int i = (int)ds_first; i != (int)ds_last; ++i) + if (location_t loc = declspecs->locations[i]) + { + DECL_SOURCE_LOCATION (result) = loc; + break; + } + but there's nothing much there in my POV? My C++ template based testcase was this: $ cat return-narrow-2.cc ; echo EOF namespace std { template < typename, typename > struct pair; } template < typename > struct __mini_vector { int _M_finish; unsigned long _M_space_left() { return _M_finish != 0; } }; template class __mini_vector< std::pair< long, long > >; template class __mini_vector< int >; EOF Where the locations are all confused (maybe a tad different on trunk): $ ../gcc/xg++ -B../gcc -c -o /tmp/foo.o return-narrow-2.cc -O -Wtype-demotion return-narrow-2.cc: In member function ‘long unsigned int __mini_vector< >::_M_space_left() [with = std::pair]’: return-narrow-2.cc:6:3: warning: Function ‘_M_space_left’ could return ‘bool’ [-Wtype-demotion] 6 | _M_space_left() | ^~~~~~~~~~~~~ | bool return-narrow-2.cc:6:3: note: with a range of [0,1] return-narrow-2.cc: In member function ‘long unsigned int __mini_vector< >::_M_space_left() [with = int]’: return-narrow-2.cc:6:3: warning: Function ‘_M_space_left’ could return ‘bool’ [-Wtype-demotion] 6 | _M_space_left() | ^~~~~~~~~~~~~ | bool return-narrow-2.cc:6:3: note: with a range of [0,1] The normal C function and C++ function (non-template) dummy tests are all fine and work as i had expected: $ cat return-narrow.cc ; echo EOF int xyz (int param1, int param2, int param3) { if (param1 == 42) return 1; if (param2 == 17) return 1; if (param3 == 99) return 1; return 0; } int abc (int param1, int param2, int param3) { if (param1 == 42) return 0; if (param2 == 17) return 0; if (param3 == 99) return 0; return 0; } const void *const * pointer_thingie (void *i) { return (const void *const *)((long)i & 1); } int comparer (int param1, int param2, int param3) /* signed char */ { if (param1 >= 42) return 1; if (param2 == 17) return 1; if (param3 <= 99) return -1; return 0; } int zero_to_two (int i) /* suggest: unsigned char */ { if (i < 0) return 0; if (i > 0) return 2; return 0; } int main (void) // dg-bogus "Function .main. could return .bool." { return 0; } _Pragma("GCC visibility push(hidden)") int my_main (int argc, char**argv) __attribute__(( visibility("default") )); int my_main (int, char**) { return 0; } int hidden_main (int, char**) { return 1; } _Pragma("GCC visibility pop") int i64c(int i) { /* returns [46,122] */ i &= 0x3f; if (i == 0) return '.'; if (i == 1) return '/'; if (i < 12) return ('0' - 2 + i); if (i < 38) return ('A' - 12 + i); return ('a' - 38 + i); } EOF Which gives for the normal C-flavour hunks: $ ../gcc/xg++ -B../gcc -c -o /tmp/foo.o return-narrow.cc -O1 -Wall return-narrow.cc: In function ‘int xyz(int, int, int)’: return-narrow.cc:1:1: warning: Function ‘xyz’ could return ‘bool’ [-Wtype-demotion] 1 | int xyz (int param1, int param2, int param3) | ^~~ | bool return-narrow.cc:1:1: note: with a range of [0,1] return-narrow.cc: In function ‘int abc(int, int, int)’: return-narrow.cc:11:1: warning: Function ‘abc’ could return ‘bool’ [-Wtype-demotion] 11 | int abc (int param1, int param2, int param3) | ^~~ | bool return-narrow.cc:11:1: note: with a range of [0,0] return-narrow.cc: In function ‘const void* const* pointer_thingie(void*)’: return-narrow.cc:21:7: warning: Function ‘pointer_thingie’ could return ‘bool’ [-Wtype-demotion] 21 | const void *const * pointer_thingie (void *i) | ^~~~ | bool return-narrow.cc:21:7: note: with a range of [0B,1B] return-narrow.cc: In function ‘int comparer(int, int, int)’: return-narrow.cc:25:1: warning: Function ‘comparer’ could return ‘signed char’ [-Wtype-demotion] 25 | int comparer (int param1, int param2, int param3) /* signed char */ | ^~~ | signed char return-narrow.cc:25:1: note: with a range of [-1,1] return-narrow.cc: In function ‘int zero_to_two(int)’: return-narrow.cc:35:1: warning: Function ‘zero_to_two’ could return ‘unsigned char’ [-Wtype-demotion] 35 | int | ^~~ | unsigned char return-narrow.cc:35:1: note: with a range of [0,2] return-narrow.cc: In function ‘int my_main(int, char**)’: return-narrow.cc:51:1: warning: Function ‘my_main’ could return ‘bool’ [-Wtype-demotion] 51 | int my_main (int, char**) { return 0; } | ^~~ | bool return-narrow.cc:51:1: note: with a range of [0,0] return-narrow.cc: In function ‘int hidden_main(int, char**)’: return-narrow.cc:52:1: warning: Function ‘hidden_main’ could return ‘bool’ [-Wtype-demotion] 52 | int hidden_main (int, char**) { return 1; } | ^~~ | bool return-narrow.cc:52:1: note: with a range of [1,1] return-narrow.cc: In function ‘int i64c(int)’: return-narrow.cc:55:1: warning: Function ‘i64c’ could return ‘unsigned char’ [-Wtype-demotion] 55 | int i64c(int i) | ^~~ | unsigned char return-narrow.cc:55:1: note: with a range of [46,122] So, any help wrt the template case? -- many TIA! Bernhard Reutner-Fischer (5): c: Set the locus of the function result decl c++: Set the locus of the function result decl Fortran: Narrow return types [PR78798] value-range: Add as_string diagnostics helper gimple: Add pass to note possible type demotions; IPA pro/demotion gcc/Makefile.in | 1 + gcc/c-family/c.opt | 6 + gcc/c/c-decl.cc | 6 +- gcc/cp/decl.cc | 15 +- gcc/fortran/arith.cc | 4 +- gcc/fortran/arith.h | 4 +- gcc/fortran/array.cc | 8 +- gcc/fortran/check.cc | 2 +- gcc/fortran/cpp.cc | 3 +- gcc/fortran/cpp.h | 2 +- gcc/fortran/dependency.cc | 8 +- gcc/fortran/dependency.h | 6 +- gcc/fortran/expr.cc | 6 +- gcc/fortran/gfortran.h | 51 ++-- gcc/fortran/intrinsic.cc | 6 +- gcc/fortran/io.cc | 13 +- gcc/fortran/misc.cc | 2 +- gcc/fortran/parse.cc | 2 +- gcc/fortran/parse.h | 2 +- gcc/fortran/primary.cc | 4 +- gcc/fortran/resolve.cc | 22 +- gcc/fortran/scanner.cc | 20 +- gcc/fortran/symbol.cc | 2 +- gcc/fortran/target-memory.cc | 6 +- gcc/fortran/trans-array.cc | 2 +- gcc/fortran/trans-decl.cc | 2 +- gcc/fortran/trans-types.cc | 6 +- gcc/fortran/trans-types.h | 6 +- gcc/fortran/trans.h | 2 +- gcc/gimple-warn-types.cc | 441 +++++++++++++++++++++++++++++++++++ gcc/passes.def | 1 + gcc/tree-pass.h | 1 + gcc/value-range.cc | 56 +++++ gcc/value-range.h | 3 + 34 files changed, 618 insertions(+), 103 deletions(-) create mode 100644 gcc/gimple-warn-types.cc -- 2.38.1