From patchwork Wed Aug 9 18:20:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 133410 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp2991626vqr; Wed, 9 Aug 2023 11:23:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEvWTrA8Rl8QoC3SnzmodUxn5j3iKfLFlXO8KGhaYGbG0kCKAj9AiMxsoyLdq2vJc4EMIna X-Received: by 2002:a2e:9084:0:b0:2b9:e230:25d0 with SMTP id l4-20020a2e9084000000b002b9e23025d0mr5291ljg.14.1691605391661; Wed, 09 Aug 2023 11:23:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691605391; cv=none; d=google.com; s=arc-20160816; b=WPzV320modBy3BUI8dCoMz5VbLsXc3FGEs6PUkNW8osQ0vqcgxAX91cKbw2hbi4OTX Ej9kdVvLhOBmurJjcrxqW/m9Ov0XMLfEGLzoPGoU7YkC08sZ7NqsW++vZOsDaGulJXf3 ztINz47jqdV4GRV9Cl0UQtgcV+duQJ9sUgg6Efver3c3rqQZK5TvXlbdPP5jeMER4Y7D Vlif8fl9yVzOPekgJ00mWuMqu72rRqkQbWBv+wSJtnjg42S1qCRjWmYH6J0jRBt741iy EY/97AMNMW4eBHfQA9erXMmrhIBZOido+bjeBFG0aowNCrkwDotucZaO4PBxJZR7nU2X 1ucA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:mime-version:message-id:subject:cc:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=ZiPojcxdLk3G1xFtO90aBUCS7C4gGvGCKnbi38EmBpE=; fh=fteJLpb59VrvFh/kM75rW7nRpNe+RexDgs4c2irEcIM=; b=ivfudb0GHbwRewylbF2foyVQdyntka9/shv+6RxS4q9re63m51oq+L4oOPKVcBZvYj ySJ4eekCKxog+ZavD8fHu+TlKEWMKwt2Z1kQxNVWNv8cGBZ6MtGAvQhusNtGLDrxkx2c DUVrXMXgZstKTJA1LCMgXO4TEfAgRjtG0i2niTvSQ0/ZoZ/I6E68xKbnhSFEU1sTWM7N 6/JzZYkeKjnRWBLb7H31XdE2iiOBLm+czNzp5j3sT//YLKUP6uZRgkzKhHciUd9kXRzs fhDWXqO2XYTxeeqcUtxayCTBYDSzyKVpNRTV54UtNyB1gt8SRtEIEh4OSqncIEDyNMlQ iXoQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="FLg/C23v"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id t2-20020a1709063e4200b00993325b159csi8920220eji.659.2023.08.09.11.23.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 09 Aug 2023 11:23:11 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="FLg/C23v"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 92A3A3857016 for ; Wed, 9 Aug 2023 18:23:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 92A3A3857016 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691605382; bh=ZiPojcxdLk3G1xFtO90aBUCS7C4gGvGCKnbi38EmBpE=; h=Date:To:Cc:Subject:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=FLg/C23v+1ye06gIf1CAg7hhGVgejnTnt2Aym42ch2MfXrScpFjrflTtKgJmUR6kB 95oLfnb6ZV89f5nXllsiL5rvi+cPWrTFjzCSnu5bD4mHo/0TUIsDpmIkUqSCwu/uQW u1+w8bYM4e0VF9B5qlH5vnWGDSQW6B/+dEzvdA88= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 2AE0A3858023 for ; Wed, 9 Aug 2023 18:20:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2AE0A3858023 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-339-xZj7Cr_DOTOa5GezoZx_JA-1; Wed, 09 Aug 2023 14:20:41 -0400 X-MC-Unique: xZj7Cr_DOTOa5GezoZx_JA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 28D0E101A52E; Wed, 9 Aug 2023 18:20:41 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.18]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E221D40C6F4E; Wed, 9 Aug 2023 18:20:40 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 379IKcHH2042946 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Wed, 9 Aug 2023 20:20:38 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 379IKbXc2042945; Wed, 9 Aug 2023 20:20:37 +0200 Date: Wed, 9 Aug 2023 20:20:37 +0200 To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 7/12] ubsan: _BitInt -fsanitize=undefined support [PR102989] Message-ID: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773776815128822290 X-GMAIL-MSGID: 1773776815128822290 Hi! The following patch introduces some -fsanitize=undefined support for _BitInt, but some of the diagnostics is limited by lack of proper support in the library. I've filed https://github.com/llvm/llvm-project/issues/64100 to request proper support, for now some of the diagnostics might have less or more confusing or inaccurate wording but UB should still be diagnosed when it happens. 2023-08-09 Jakub Jelinek PR c/102989 gcc/ * internal-fn.cc (expand_ubsan_result_store): Add LHS, MODE and DO_ERROR arguments. For non-mode precision BITINT_TYPE results check if all padding bits up to mode precision are zeros or sign bit copies and if not, jump to DO_ERROR. (expand_addsub_overflow, expand_neg_overflow, expand_mul_overflow): Adjust expand_ubsan_result_store callers. * ubsan.cc: Include target.h and langhooks.h. (ubsan_encode_value): Pass BITINT_TYPE values which fit into pointer size converted to pointer sized integer, pass BITINT_TYPE values which fit into TImode (if supported) or DImode as those integer types or otherwise for now punt (pass 0). (ubsan_type_descriptor): Handle BITINT_TYPE. For pstyle of UBSAN_PRINT_FORCE_INT use TK_Integer (0x0000) mode with a TImode/DImode precision rather than TK_Unknown used otherwise for large/huge BITINT_TYPEs. (instrument_si_overflow): Instrument BITINT_TYPE operations even when they don't have mode precision. * ubsan.h (enum ubsan_print_style): New enumerator. gcc/c-family/ * c-ubsan.cc (ubsan_instrument_shift): Use UBSAN_PRINT_FORCE_INT for type0 type descriptor. Jakub --- gcc/ubsan.cc.jj 2023-08-08 15:54:35.443599459 +0200 +++ gcc/ubsan.cc 2023-08-08 16:12:02.329939798 +0200 @@ -50,6 +50,8 @@ along with GCC; see the file COPYING3. #include "gimple-fold.h" #include "varasm.h" #include "realmpfr.h" +#include "target.h" +#include "langhooks.h" /* Map from a tree to a VAR_DECL tree. */ @@ -125,6 +127,25 @@ tree ubsan_encode_value (tree t, enum ubsan_encode_value_phase phase) { tree type = TREE_TYPE (t); + if (TREE_CODE (type) == BITINT_TYPE) + { + if (TYPE_PRECISION (type) <= POINTER_SIZE) + { + type = pointer_sized_int_node; + t = fold_build1 (NOP_EXPR, type, t); + } + else + { + scalar_int_mode arith_mode + = (targetm.scalar_mode_supported_p (TImode) ? TImode : DImode); + if (TYPE_PRECISION (type) > GET_MODE_PRECISION (arith_mode)) + return build_zero_cst (pointer_sized_int_node); + type + = build_nonstandard_integer_type (GET_MODE_PRECISION (arith_mode), + TYPE_UNSIGNED (type)); + t = fold_build1 (NOP_EXPR, type, t); + } + } scalar_mode mode = SCALAR_TYPE_MODE (type); const unsigned int bitsize = GET_MODE_BITSIZE (mode); if (bitsize <= POINTER_SIZE) @@ -355,14 +376,32 @@ ubsan_type_descriptor (tree type, enum u { /* See through any typedefs. */ type = TYPE_MAIN_VARIANT (type); + tree type3 = type; + if (pstyle == UBSAN_PRINT_FORCE_INT) + { + /* Temporary hack for -fsanitize=shift with _BitInt(129) and more. + libubsan crashes if it is not TK_Integer type. */ + if (TREE_CODE (type) == BITINT_TYPE) + { + scalar_int_mode arith_mode + = (targetm.scalar_mode_supported_p (TImode) + ? TImode : DImode); + if (TYPE_PRECISION (type) > GET_MODE_PRECISION (arith_mode)) + type3 = build_qualified_type (type, TYPE_QUAL_CONST); + } + if (type3 == type) + pstyle = UBSAN_PRINT_NORMAL; + } - tree decl = decl_for_type_lookup (type); + tree decl = decl_for_type_lookup (type3); /* It is possible that some of the earlier created DECLs were found unused, in that case they weren't emitted and varpool_node::get returns NULL node on them. But now we really need them. Thus, renew them here. */ if (decl != NULL_TREE && varpool_node::get (decl)) - return build_fold_addr_expr (decl); + { + return build_fold_addr_expr (decl); + } tree dtype = ubsan_get_type_descriptor_type (); tree type2 = type; @@ -370,6 +409,7 @@ ubsan_type_descriptor (tree type, enum u pretty_printer pretty_name; unsigned char deref_depth = 0; unsigned short tkind, tinfo; + char tname_bitint[sizeof ("unsigned _BitInt(2147483647)")]; /* Get the name of the type, or the name of the pointer type. */ if (pstyle == UBSAN_PRINT_POINTER) @@ -403,8 +443,18 @@ ubsan_type_descriptor (tree type, enum u } if (tname == NULL) - /* We weren't able to determine the type name. */ - tname = ""; + { + if (TREE_CODE (type2) == BITINT_TYPE) + { + snprintf (tname_bitint, sizeof (tname_bitint), + "%s_BitInt(%d)", TYPE_UNSIGNED (type2) ? "unsigned " : "", + TYPE_PRECISION (type2)); + tname = tname_bitint; + } + else + /* We weren't able to determine the type name. */ + tname = ""; + } pp_quote (&pretty_name); @@ -472,6 +522,18 @@ ubsan_type_descriptor (tree type, enum u case INTEGER_TYPE: tkind = 0x0000; break; + case BITINT_TYPE: + { + /* FIXME: libubsan right now only supports _BitInts which + fit into DImode or TImode. */ + scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode) + ? TImode : DImode); + if (TYPE_PRECISION (eltype) <= GET_MODE_PRECISION (arith_mode)) + tkind = 0x0000; + else + tkind = 0xffff; + } + break; case REAL_TYPE: /* FIXME: libubsan right now only supports float, double and long double type formats. */ @@ -486,7 +548,17 @@ ubsan_type_descriptor (tree type, enum u tkind = 0xffff; break; } - tinfo = get_ubsan_type_info_for_type (eltype); + tinfo = tkind == 0xffff ? 0 : get_ubsan_type_info_for_type (eltype); + + if (pstyle == UBSAN_PRINT_FORCE_INT) + { + tkind = 0x0000; + scalar_int_mode arith_mode = (targetm.scalar_mode_supported_p (TImode) + ? TImode : DImode); + tree t = lang_hooks.types.type_for_mode (arith_mode, + TYPE_UNSIGNED (eltype)); + tinfo = get_ubsan_type_info_for_type (t); + } /* Create a new VAR_DECL of type descriptor. */ const char *tmp = pp_formatted_text (&pretty_name); @@ -522,7 +594,7 @@ ubsan_type_descriptor (tree type, enum u varpool_node::finalize_decl (decl); /* Save the VAR_DECL into the hash table. */ - decl_for_type_insert (type, decl); + decl_for_type_insert (type3, decl); return build_fold_addr_expr (decl); } @@ -1604,8 +1676,9 @@ instrument_si_overflow (gimple_stmt_iter Also punt on bit-fields. */ if (!INTEGRAL_TYPE_P (lhsinner) || TYPE_OVERFLOW_WRAPS (lhsinner) - || maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)), - TYPE_PRECISION (lhsinner))) + || (TREE_CODE (lhsinner) != BITINT_TYPE + && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (lhsinner)), + TYPE_PRECISION (lhsinner)))) return; switch (code) --- gcc/ubsan.h.jj 2023-08-08 15:54:35.460599221 +0200 +++ gcc/ubsan.h 2023-08-08 16:12:02.329939798 +0200 @@ -39,7 +39,8 @@ enum ubsan_null_ckind { enum ubsan_print_style { UBSAN_PRINT_NORMAL, UBSAN_PRINT_POINTER, - UBSAN_PRINT_ARRAY + UBSAN_PRINT_ARRAY, + UBSAN_PRINT_FORCE_INT }; /* This controls ubsan_encode_value behavior. */ --- gcc/internal-fn.cc.jj 2023-08-08 15:55:06.709161614 +0200 +++ gcc/internal-fn.cc 2023-08-08 16:22:09.404440148 +0200 @@ -981,8 +981,38 @@ expand_arith_overflow_result_store (tree /* Helper for expand_*_overflow. Store RES into TARGET. */ static void -expand_ubsan_result_store (rtx target, rtx res) +expand_ubsan_result_store (tree lhs, rtx target, scalar_int_mode mode, + rtx res, rtx_code_label *do_error) { + if (TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE + && TYPE_PRECISION (TREE_TYPE (lhs)) < GET_MODE_PRECISION (mode)) + { + int uns = TYPE_UNSIGNED (TREE_TYPE (lhs)); + int prec = TYPE_PRECISION (TREE_TYPE (lhs)); + int tgtprec = GET_MODE_PRECISION (mode); + rtx resc = gen_reg_rtx (mode), lres; + emit_move_insn (resc, res); + if (uns) + { + rtx mask + = immed_wide_int_const (wi::shifted_mask (0, prec, false, tgtprec), + mode); + lres = expand_simple_binop (mode, AND, res, mask, NULL_RTX, + true, OPTAB_LIB_WIDEN); + } + else + { + lres = expand_shift (LSHIFT_EXPR, mode, res, tgtprec - prec, + NULL_RTX, 1); + lres = expand_shift (RSHIFT_EXPR, mode, lres, tgtprec - prec, + NULL_RTX, 0); + } + if (lres != res) + emit_move_insn (res, lres); + do_compare_rtx_and_jump (res, resc, + NE, true, mode, NULL_RTX, NULL, do_error, + profile_probability::very_unlikely ()); + } if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target)) /* If this is a scalar in a register that is stored in a wider mode than the declared mode, compute the result into its declared mode @@ -1431,7 +1461,7 @@ expand_addsub_overflow (location_t loc, if (lhs) { if (is_ubsan) - expand_ubsan_result_store (target, res); + expand_ubsan_result_store (lhs, target, mode, res, do_error); else { if (do_xor) @@ -1528,7 +1558,7 @@ expand_neg_overflow (location_t loc, tre if (lhs) { if (is_ubsan) - expand_ubsan_result_store (target, res); + expand_ubsan_result_store (lhs, target, mode, res, do_error); else expand_arith_overflow_result_store (lhs, target, mode, res); } @@ -2414,7 +2450,7 @@ expand_mul_overflow (location_t loc, tre if (lhs) { if (is_ubsan) - expand_ubsan_result_store (target, res); + expand_ubsan_result_store (lhs, target, mode, res, do_error); else expand_arith_overflow_result_store (lhs, target, mode, res); } --- gcc/c-family/c-ubsan.cc.jj 2023-08-08 15:54:33.596625322 +0200 +++ gcc/c-family/c-ubsan.cc 2023-08-08 16:12:02.332939756 +0200 @@ -256,8 +256,8 @@ ubsan_instrument_shift (location_t loc, tt = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0); else { - tree data = ubsan_create_data ("__ubsan_shift_data", 1, &loc, - ubsan_type_descriptor (type0), + tree utd0 = ubsan_type_descriptor (type0, UBSAN_PRINT_FORCE_INT); + tree data = ubsan_create_data ("__ubsan_shift_data", 1, &loc, utd0, ubsan_type_descriptor (type1), NULL_TREE, NULL_TREE); data = build_fold_addr_expr_loc (loc, data);