From patchwork Wed Nov 2 14:55:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 59788 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3E1F6385737E for ; Wed, 2 Nov 2022 14:56:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3E1F6385737E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1667401010; bh=k8wO1sMaAt/DgmfuMczL0UWCMQyeGz8Dmf7m8wuIluc=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=cxf4/5kugPS1dvE1Pf1b9b6qerC9SbHWihFHV1gIHR9Dj99fR5UZpsRq9Bl6FxfAz hLa2QYnWVkllP+uKguAjBwZMSWMn7Po3Uh4S1ZtRQWm7jBM9FHvhaCn/BNPcFllpsk gXWUI2Gwqv00SDiRyRTrEYJw0RWioB83uIlTRYP0= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-oi1-x233.google.com (mail-oi1-x233.google.com [IPv6:2607:f8b0:4864:20::233]) by sourceware.org (Postfix) with ESMTPS id B4D2D38576B2 for ; Wed, 2 Nov 2022 14:56:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B4D2D38576B2 Received: by mail-oi1-x233.google.com with SMTP id t62so8630604oib.12 for ; Wed, 02 Nov 2022 07:56:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=k8wO1sMaAt/DgmfuMczL0UWCMQyeGz8Dmf7m8wuIluc=; b=LAdXQ9kvejxi3eYOIp5jlMAdg9wE84HdRF/BghM0B4ULxI9BSGamth32qIydtQeR7D LvD2wRXYMeuJI105kdmc5du60Boq+Vj9H8LiIPiy5mI4hhkbz1aSgjpYTDYFd5JUNglM 7i3cK27jc3dTMPn2L6bkeJl5uR/UEAQMNKqhP4PTnhxeLK39SWoJLF5n0aX+b3PFHvyp V4L1R0Jf+nk38FVIBq7SQ8M+4gPJru74MokFMWs3JOWph1qxRIjKFh7zK0Zrr3aoUdVF bNOiks8Hw6LZ5hZP2N3pvnRm1fBi1s3rZlhG61cS7hoZORR+3N7PznaPXLoYN+Cufps0 /kfg== X-Gm-Message-State: ACrzQf0g+wSryGSIvpH88l5QhvC16a9mVnnkOCFDqfwaHtOYK3zByaeU lPOkQwF4olg7M9iFAOYAA0I85aQfe5avxzSm X-Google-Smtp-Source: AMsMyM5fLvhk9WJ3CvCFYxc21Rl7lil9FD8ewPFhFNYO36dAW8fphQjqdlBU8/pdR2F7m06cXyUQAw== X-Received: by 2002:a05:6808:218c:b0:355:231d:54a6 with SMTP id be12-20020a056808218c00b00355231d54a6mr13707834oib.4.1667400975639; Wed, 02 Nov 2022 07:56:15 -0700 (PDT) Received: from mandiga.. ([2804:1b3:a7c0:a9f4:967f:f7c:c187:85d7]) by smtp.gmail.com with ESMTPSA id 37-20020a9d0328000000b00661af2f9a1asm5205767otv.49.2022.11.02.07.56.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Nov 2022 07:56:15 -0700 (PDT) To: libc-alpha@sourceware.org, Fangrui Song Subject: [PATCH v2 3/4] stdlib: Remove if inline asm context casts if compiler does not support it Date: Wed, 2 Nov 2022 11:55:58 -0300 Message-Id: <20221102145559.1962008-4-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221102145559.1962008-1-adhemerval.zanella@linaro.org> References: <20221102145559.1962008-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, 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 X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" The inline asm constraints lvalue casts on longlong.h are not fully supported on all compilers. The clang rejects the code by default: error: invalid use of a cast in a inline asm context requiring an lvalue: remove the cast or build with -fheinous-gnu-extensions And even using -fheinous-gnu-extensions it does not seem to be a long-term solution, since clang accepts it but still throws an warning: warning: invalid use of a cast in an inline asm context requiring an lvalue: accepted due to -fheinous-gnu-extensions, but clang may remove support for this in the future And clang also does not provide a a -Wno-heinous-gnu-extensions to suppress it. For GCC the cast acts as a limited form of typechecking where if the cast can be removed, then the output operand had a type of the proper width, otherwise compiler issue an error. That's the main reason why the casts are still kept in GCC [1], although there are a long-standing bug report to actually remove them [2]. To enable longlong.h support on clang this patch uses a simple mechanism to remove casts them if compiler does not fully support it. The script uses simple string substitution to remove the cast if the asm constraint is found. For GCC it should be a no-op, the longlong.h is copies as-is. Checked on a build for all affected ABIs. [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581722.html [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=2803 --- Makerules | 13 ++++ configure | 29 ++++++++ configure.ac | 22 ++++++ scripts/filter-asm-inline-cast.py | 102 +++++++++++++++++++++++++++ stdlib/{longlong.h => longlong.h.in} | 0 stdlib/strtod_l.c | 2 +- 6 files changed, 167 insertions(+), 1 deletion(-) create mode 100755 scripts/filter-asm-inline-cast.py rename stdlib/{longlong.h => longlong.h.in} (100%) diff --git a/Makerules b/Makerules index 09c0cf8357..1ca16bf080 100644 --- a/Makerules +++ b/Makerules @@ -351,6 +351,19 @@ $(common-objpfx)$(lib-names-stmp-abi): $(..)scripts/lib-names.awk \ endif common-generated += $(lib-names-h-abi) $(lib-names-stmp-abi) endif + +# The inline asm constraints lvalue casts on longlong.h are not fully +# supported on all compilers. However, the cast acts as a limited form of +# typechecking where if the cast can be removed, then the output operand +# had a type of the proper width, otherwise compiler issue an error. +# For the case compiler does not fully support the script tries to remove +# it. +before-compile += $(common-objpfx)stdlib/longlong.h +$(common-objpfx)stdlib/longlong.h: $(..)stdlib/longlong.h.in $(..)scripts/filter-asm-inline-cast.py + $(make-target-directory) + $(PYTHON) $(..)scripts/filter-asm-inline-cast.py --filter $(config-remove-cast-inline-asm) $< $@.tmp + mv -f $@.tmp $@ +common-generated += $(common-objpfx)stdlib/longlong.h ############################################################################### # NOTE! Everything adding to before-compile needs to come before this point! # diff --git a/configure b/configure index e23ea95a49..045a51cfba 100755 --- a/configure +++ b/configure @@ -6376,6 +6376,35 @@ $as_echo "$libc_cv_wno_ignored_attributes" >&6; } config_vars="$config_vars config-cflags-wno-ignored-attributes = $libc_cv_wno_ignored_attributes" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if cast in inline asm context is supported" >&5 +$as_echo_n "checking if cast in inline asm context is supported... " >&6; } +if ${libc_cv_cast_inline_asm_context+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then + libc_cv_remove_cast_inline_asm=yes +fi +rm -f conftest.* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cast_inline_asm_context" >&5 +$as_echo "$libc_cv_cast_inline_asm_context" >&6; } +config_vars="$config_vars +config-remove-cast-inline-asm = $libc_cv_remove_cast_inline_asm" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc puts quotes around section names" >&5 $as_echo_n "checking whether cc puts quotes around section names... " >&6; } if ${libc_cv_have_section_quotes+:} false; then : diff --git a/configure.ac b/configure.ac index 7275b53345..238a7267ef 100644 --- a/configure.ac +++ b/configure.ac @@ -1426,6 +1426,28 @@ rm -f conftest*]) LIBC_CONFIG_VAR([config-cflags-wno-ignored-attributes], [$libc_cv_wno_ignored_attributes]) +dnl clang emits and error for cast usage in inline asm context and although +dnl -fheinous-gnu-extensions option allows to just instruct it to emit an +dnl warning, clang also explicit warns that the option might be removed in +dnl the future. +AC_CACHE_CHECK([if cast in inline asm context is supported], + libc_cv_cast_inline_asm_context, [dnl +cat > conftest.c < conftest.c <. + +import argparse +import sys +import re + +# Each asm constraint where the cast occurs. +CONSTRAINT_LIST=( + '\"%0\"', + '\"%1\"', + '\"%dI\"' + '\"%rJ\"', + '\"%r\"', + '\"0\"', + '\"1\"', + '\"=&g\"', + '\"=&r\"', + '\"=a\"', + '\"=d\"', + '\"=g\"', + '\"=r\"', + '\"dI\"', + '\"g\"', + '\"rICal\"', + '\"rI\"', + '\"rJ\"', + '\"%rJ\"', + '\"rM\"', + '\"rQR\"', + '\"r\"', + '\"rm\"', + '\"rme\"', + '\"x\"', + '\"d\"', + '\"=&d\"', + '\"dmi\"', + '\"%rM\"', +) + +# The cast type used in lvalue asm contraint input. +REPLACE_CASTS = ( + "(UDItype)", + "(USItype)", + "(unsigned int)", +) + +def multireplace(string, repl): + if not repl: + return string + + # Place longer string first, to avoid shorter substring to match first. + rep_sorted = sorted(repl, key=len, reverse=True) + rep_escaped = map(re.escape, rep_sorted) + pattern = re.compile("|".join(rep_escaped), 0) + + return pattern.sub(lambda match: "", string) + + +def get_parser(): + def strbool(string): + return True if string.lower() == 'yes' else False + + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--filter', dest='filter', + help='Filter out inoine asm casts', + type=strbool) + parser.add_argument('input', help='Input file') + parser.add_argument('output', help='Ouput file') + return parser + + +def main(argv): + """The main entry point.""" + parser = get_parser() + opts = parser.parse_args(argv) + with open(opts.input, 'r') as i_file, open(opts.output, 'w') as o_file: + for line in i_file: + replace = REPLACE_CASTS \ + if opts.filter and any(substring in line for substring in CONSTRAINT_LIST) \ + else None + o_file.write(multireplace(line, replace)) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/stdlib/longlong.h b/stdlib/longlong.h.in similarity index 100% rename from stdlib/longlong.h rename to stdlib/longlong.h.in diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index 3ebb491e22..fe59907cb2 100644 --- a/stdlib/strtod_l.c +++ b/stdlib/strtod_l.c @@ -81,7 +81,7 @@ extern double ____strtod_l_internal (const char *, char **, int, locale_t); #include #include #include "gmp-impl.h" -#include "longlong.h" +#include #include "fpioconst.h" #include