From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by sourceware.org (Postfix) with ESMTPS id 66460383302C for ; Wed, 30 Jun 2021 09:00:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 66460383302C Received: by mail-ed1-x52e.google.com with SMTP id i5so2187657eds.1 for ; Wed, 30 Jun 2021 02:00:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=d6LsTxF3oZHrhF+TRjMrkhvjLLEy9k1xcdSiKl6r7vY=; b=S/iVKkFMImDCXEpWqQ/XyDxr1XyHlxTnOsC6kTE1A8qPr2d5zVcP0rERmiZLcf5iL+ XPmu1NlS5XbNk8Xt303+kNGCsETZ4sHoZ1kPcM+odtMuKOrzQovMtDdzsbrw091/uzXD ZNDAXhY16pHOjB0dgwlAbApuFi1sm7DuNeSFz49BVKmiekp+o6k1MX8QyibeMnSaUwew fibropIWeHeidby1HcSRUqZEnze+hyjvWUXNBMslmlfE0wSFTL3N1MIoxcMjbJm8Qx3s NX6rQ+9h8QGUGFo1/2Wi8BWQy9g34VGcEGF4qCQwKDYLisUBz2jHvAVWooraj/FxaALI umVQ== X-Gm-Message-State: AOAM532kSjpEJgfUQFXRCxmHO2XR68CpTtTKMmGJtDRq8KChC0BckzzQ L1gRPgtMTdwzXDOGKGcRk2wpihJw1pDiJL0auUo= X-Google-Smtp-Source: ABdhPJzsDFK87dfjxqRuT+5WKPPCdWQZJy/fsZfs2ww9n09qAdHIbybqj0fFlAxwPhmhHQG0KHuJk8QXxqH1LbreQXE= X-Received: by 2002:a05:6402:42c9:: with SMTP id i9mr45564068edc.61.1625043648243; Wed, 30 Jun 2021 02:00:48 -0700 (PDT) MIME-Version: 1.0 References: <20210630053529.26581-1-tbsaunde@tbsaunde.org> <20210630053529.26581-2-tbsaunde@tbsaunde.org> In-Reply-To: <20210630053529.26581-2-tbsaunde@tbsaunde.org> From: Richard Biener Date: Wed, 30 Jun 2021 11:00:37 +0200 Message-ID: Subject: Re: [PATCH 2/4] allow poisoning input_location in ranges it should not be used To: Trevor Saunders Cc: GCC Patches Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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-List-Received-Date: Wed, 30 Jun 2021 09:00:52 -0000 On Wed, Jun 30, 2021 at 7:37 AM Trevor Saunders wrote: > > This makes it possible to assert if input_location is used during the lifetime > of a scope. This will allow us to find places that currently use it within a > function and its callees, or prevent adding uses within the lifetime of a > function after all existing uses are removed. > > bootstrapped and regtested on x86_64-linux-gnu, ok? I'm not sure about the general approach but I have comments about input_location. IMHO a good first step would be to guard the input_location declaration with sth like #ifndef GCC_NEED_INPUT_LOCATION extern location_t input_location; #endif and "white-list" it in the few files that refer to it. (but not in coretypes.h or rtl.h which seem to include input.h). Richard. > Trev > > gcc/cp/ChangeLog: > > * call.c (add_builtin_candidate): Adjust. > * decl.c (compute_array_index_type_loc): Likewise. > * decl2.c (get_guard_cond): Likewise. > (one_static_initialization_or_destruction): Likewise. > (do_static_initialization_or_destruction): Likewise. > * init.c (build_new_1): Likewise. > (build_vec_init): Likewise. > * module.cc (finish_module_processing): Likewise. > * parser.c (cp_convert_range_for): Likewise. > (cp_parser_perform_range_for_lookup): Likewise. > (cp_parser_omp_for_incr): Likewise. > (cp_convert_omp_range_for): Likewise. > * pt.c (fold_expression): Likewise. > (tsubst_copy_and_build): Likewise. > * typeck.c (common_pointer_type): Likewise. > (cp_build_array_ref): Likewise. > (get_member_function_from_ptrfunc): Likewise. > (cp_build_unary_op): Likewise. > (convert_ptrmem): Likewise. > (cp_build_modify_expr): Likewise. > (build_ptrmemfunc): Likewise. > > gcc/ChangeLog: > > * diagnostic.c (internal_error): Remove use of input_location. > * input.c (input_location): Change type to poisonable. > * input.h (input_location): Adjust prototype. > > gcc/objc/ChangeLog: > > * objc-next-runtime-abi-02.c (build_v2_objc_method_fixup_call): Adjust. > --- > gcc/cp/call.c | 2 +- > gcc/cp/decl.c | 2 +- > gcc/cp/decl2.c | 12 +++++------ > gcc/cp/init.c | 14 ++++++------ > gcc/cp/module.cc | 2 +- > gcc/cp/parser.c | 11 +++++----- > gcc/cp/pt.c | 4 ++-- > gcc/cp/typeck.c | 33 ++++++++++++++++------------- > gcc/diagnostic.c | 2 +- > gcc/input.c | 2 +- > gcc/input.h | 3 ++- > gcc/objc/objc-next-runtime-abi-02.c | 2 +- > 12 files changed, 47 insertions(+), 42 deletions(-) > > diff --git a/gcc/cp/call.c b/gcc/cp/call.c > index e4df72ec1a3..c94fe0b3bd2 100644 > --- a/gcc/cp/call.c > +++ b/gcc/cp/call.c > @@ -3126,7 +3126,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, > { > if (TYPE_PTR_OR_PTRMEM_P (type1)) > { > - tree cptype = composite_pointer_type (input_location, > + tree cptype = composite_pointer_type (op_location_t (input_location), > type1, type2, > error_mark_node, > error_mark_node, > diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c > index fa6af6fec11..84e2bdae6bf 100644 > --- a/gcc/cp/decl.c > +++ b/gcc/cp/decl.c > @@ -10884,7 +10884,7 @@ compute_array_index_type_loc (location_t name_loc, tree name, tree size, > cp_build_binary_op will be appropriately folded. */ > { > processing_template_decl_sentinel s; > - itype = cp_build_binary_op (input_location, > + itype = cp_build_binary_op (op_location_t (input_location), > MINUS_EXPR, > cp_convert (ssizetype, size, complain), > cp_convert (ssizetype, integer_one_node, > diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c > index 090a83bd670..ddb7e248c63 100644 > --- a/gcc/cp/decl2.c > +++ b/gcc/cp/decl2.c > @@ -3386,7 +3386,7 @@ get_guard_cond (tree guard, bool thread_safe) > guard_value = integer_one_node; > if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard))) > guard_value = fold_convert (TREE_TYPE (guard), guard_value); > - guard = cp_build_binary_op (input_location, > + guard = cp_build_binary_op (location_t (input_location), > BIT_AND_EXPR, guard, guard_value, > tf_warning_or_error); > } > @@ -3394,7 +3394,7 @@ get_guard_cond (tree guard, bool thread_safe) > guard_value = integer_zero_node; > if (!same_type_p (TREE_TYPE (guard_value), TREE_TYPE (guard))) > guard_value = fold_convert (TREE_TYPE (guard), guard_value); > - return cp_build_binary_op (input_location, > + return cp_build_binary_op (location_t (input_location), > EQ_EXPR, guard, guard_value, > tf_warning_or_error); > } > @@ -4056,7 +4056,7 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp) > last to destroy the variable. */ > else if (initp) > guard_cond > - = cp_build_binary_op (input_location, > + = cp_build_binary_op (location_t (input_location), > EQ_EXPR, > cp_build_unary_op (PREINCREMENT_EXPR, > guard, > @@ -4066,7 +4066,7 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp) > tf_warning_or_error); > else > guard_cond > - = cp_build_binary_op (input_location, > + = cp_build_binary_op (location_t (input_location), > EQ_EXPR, > cp_build_unary_op (PREDECREMENT_EXPR, > guard, > @@ -4132,7 +4132,7 @@ do_static_initialization_or_destruction (tree vars, bool initp) > /* Build the outer if-stmt to check for initialization or destruction. */ > init_if_stmt = begin_if_stmt (); > cond = initp ? integer_one_node : integer_zero_node; > - cond = cp_build_binary_op (input_location, > + cond = cp_build_binary_op (location_t (input_location), > EQ_EXPR, > initialize_p_decl, > cond, > @@ -4176,7 +4176,7 @@ do_static_initialization_or_destruction (tree vars, bool initp) > /* Conditionalize this initialization on being in the right priority > and being initializing/finalizing appropriately. */ > priority_if_stmt = begin_if_stmt (); > - cond = cp_build_binary_op (input_location, > + cond = cp_build_binary_op (location_t (input_location), > EQ_EXPR, > priority_decl, > build_int_cst (NULL_TREE, priority), > diff --git a/gcc/cp/init.c b/gcc/cp/init.c > index 88f6f90a800..d9acdefae7c 100644 > --- a/gcc/cp/init.c > +++ b/gcc/cp/init.c > @@ -2907,7 +2907,7 @@ build_new_1 (vec **placement, tree type, tree nelts, > nelts = error_mark_node; > } > if (nelts != error_mark_node) > - nelts = cp_build_binary_op (input_location, > + nelts = cp_build_binary_op (location_t (input_location), > MULT_EXPR, nelts, > inner_nelts_cst, > complain); > @@ -3428,7 +3428,7 @@ build_new_1 (vec **placement, tree type, tree nelts, > } > init_expr > = build_vec_init (data_addr, > - cp_build_binary_op (input_location, > + cp_build_binary_op (location_t (input_location), > MINUS_EXPR, outer_nelts, > integer_one_node, > complain), > @@ -3600,12 +3600,12 @@ build_new_1 (vec **placement, tree type, tree nelts, > { > if (check_new) > { > - tree ifexp = cp_build_binary_op (input_location, > + tree ifexp = cp_build_binary_op (location_t (input_location), > NE_EXPR, alloc_node, > nullptr_node, > complain); > - rval = build_conditional_expr (input_location, ifexp, rval, > - alloc_node, complain); > + rval = build_conditional_expr (location_t (input_location), ifexp, > + rval, alloc_node, complain); > } > > /* Perform the allocation before anything else, so that ALLOC_NODE > @@ -4612,14 +4612,14 @@ build_vec_init (tree base, tree maxindex, tree init, > && from_array != 2) > { > tree e; > - tree m = cp_build_binary_op (input_location, > + tree m = cp_build_binary_op (location_t (input_location), > MINUS_EXPR, maxindex, iterator, > complain); > > /* Flatten multi-dimensional array since build_vec_delete only > expects one-dimensional array. */ > if (TREE_CODE (type) == ARRAY_TYPE) > - m = cp_build_binary_op (input_location, > + m = cp_build_binary_op (location_t (input_location), > MULT_EXPR, m, > /* Avoid mixing signed and unsigned. */ > convert (TREE_TYPE (m), > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc > index f259515a498..72f32487e51 100644 > --- a/gcc/cp/module.cc > +++ b/gcc/cp/module.cc > @@ -19852,7 +19852,7 @@ finish_module_processing (cpp_reader *reader) > elf_out to (fd, e); > if (to.begin ()) > { > - auto loc = input_location; > + location_t loc = input_location; > /* So crashes finger-point the module decl. */ > input_location = state->loc; > state->write (&to, reader); > diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c > index 02daa7a6f6a..e90ee873a94 100644 > --- a/gcc/cp/parser.c > +++ b/gcc/cp/parser.c > @@ -13206,7 +13206,7 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr, > finish_init_stmt (statement); > > /* The new for condition. */ > - condition = build_x_binary_op (input_location, NE_EXPR, > + condition = build_x_binary_op (location_t (input_location), NE_EXPR, > begin, ERROR_MARK, > end, ERROR_MARK, > NULL, tf_warning_or_error); > @@ -13326,7 +13326,7 @@ cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end) > if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end)))) > { > if (cxx_dialect >= cxx17 > - && (build_x_binary_op (input_location, NE_EXPR, > + && (build_x_binary_op (location_t (input_location), NE_EXPR, > *begin, ERROR_MARK, > *end, ERROR_MARK, > NULL, tf_none) > @@ -39961,8 +39961,9 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl) > tf_warning_or_error); > } > else > - lhs = build_x_binary_op (input_location, op, lhs, ERROR_MARK, rhs, > - ERROR_MARK, NULL, tf_warning_or_error); > + lhs = build_x_binary_op (location_t (input_location), op, lhs, > + ERROR_MARK, rhs, ERROR_MARK, NULL, > + tf_warning_or_error); > } > } > while (token->type == CPP_PLUS || token->type == CPP_MINUS); > @@ -40309,7 +40310,7 @@ cp_convert_omp_range_for (tree &this_pre_body, vec *for_block, > if (CLASS_TYPE_P (iter_type)) > cond = build2 (NE_EXPR, boolean_type_node, begin, end); > else > - cond = build_x_binary_op (input_location, NE_EXPR, > + cond = build_x_binary_op (location_t (input_location), NE_EXPR, > begin, ERROR_MARK, > end, ERROR_MARK, > NULL, tf_warning_or_error); > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index f2039e09cd7..b679e34bfa4 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -12624,7 +12624,7 @@ fold_expression (tree t, tree left, tree right, tsubst_flags_t complain) > case COMPOUND_EXPR: > return build_x_compound_expr (input_location, left, right, complain); > default: > - return build_x_binary_op (input_location, code, > + return build_x_binary_op (location_t (input_location), code, > left, TREE_CODE (left), > right, TREE_CODE (right), > /*overload=*/NULL, > @@ -19854,7 +19854,7 @@ tsubst_copy_and_build (tree t, > warning_sentinel s4(warn_tautological_compare, was_dep); > > tree r = build_x_binary_op > - (input_location, TREE_CODE (t), > + (location_t (input_location), TREE_CODE (t), > op0, > (warning_suppressed_p (TREE_OPERAND (t, 0)) > ? ERROR_MARK > diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c > index a483e1f988d..98aa9e69612 100644 > --- a/gcc/cp/typeck.c > +++ b/gcc/cp/typeck.c > @@ -982,7 +982,7 @@ common_pointer_type (tree t1, tree t2) > || (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2)) > || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2))); > > - return composite_pointer_type (input_location, t1, t2, > + return composite_pointer_type (location_t (input_location), t1, t2, > error_mark_node, error_mark_node, > CPO_CONVERSION, tf_warning_or_error); > } > @@ -3702,7 +3702,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx, > > warn_array_subscript_with_type_char (loc, idx); > > - ret = cp_build_binary_op (input_location, PLUS_EXPR, ar, ind, complain); > + ret = cp_build_binary_op (location_t (input_location), PLUS_EXPR, ar, ind, > + complain); > if (first) > ret = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (ret), first, ret); > ret = cp_build_indirect_ref (loc, ret, RO_ARRAY_INDEXING, complain); > @@ -3793,10 +3794,10 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, > { > int flag_sanitize_save; > case ptrmemfunc_vbit_in_pfn: > - e1 = cp_build_binary_op (input_location, > + e1 = cp_build_binary_op (location_t (input_location), > BIT_AND_EXPR, idx, integer_one_node, > complain); > - idx = cp_build_binary_op (input_location, > + idx = cp_build_binary_op (location_t (input_location), > MINUS_EXPR, idx, integer_one_node, > complain); > if (idx == error_mark_node) > @@ -3804,7 +3805,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, > break; > > case ptrmemfunc_vbit_in_delta: > - e1 = cp_build_binary_op (input_location, > + e1 = cp_build_binary_op (location_t (input_location), > BIT_AND_EXPR, delta, integer_one_node, > complain); > /* Don't instrument the RSHIFT_EXPR we're about to create because > @@ -3812,7 +3813,7 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, > well with SAVE_EXPRs therein. */ > flag_sanitize_save = flag_sanitize; > flag_sanitize = 0; > - delta = cp_build_binary_op (input_location, > + delta = cp_build_binary_op (location_t (input_location), > RSHIFT_EXPR, delta, integer_one_node, > complain); > flag_sanitize = flag_sanitize_save; > @@ -3874,7 +3875,8 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function, > cp_build_addr_expr (e2, complain)); > > e2 = fold_convert (TREE_TYPE (e3), e2); > - e1 = build_conditional_expr (input_location, e1, e2, e3, complain); > + e1 = build_conditional_expr (location_t (input_location), e1, e2, e3, > + complain); > if (e1 == error_mark_node) > return error_mark_node; > > @@ -6754,7 +6756,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert, > > case TRUTH_NOT_EXPR: > if (gnu_vector_type_p (TREE_TYPE (arg))) > - return cp_build_binary_op (input_location, EQ_EXPR, arg, > + return cp_build_binary_op (location_t (input_location), EQ_EXPR, arg, > build_zero_cst (TREE_TYPE (arg)), complain); > arg = perform_implicit_conversion (boolean_type_node, arg, > complain); > @@ -7501,12 +7503,13 @@ convert_ptrmem (tree type, tree expr, bool allow_inverse_p, > if (TREE_CODE (expr) == PTRMEM_CST) > expr = cplus_expand_constant (expr); > > - tree cond = cp_build_binary_op (input_location, EQ_EXPR, expr, > + tree cond = cp_build_binary_op (location_t (input_location), EQ_EXPR, > + expr, > build_int_cst (TREE_TYPE (expr), -1), > complain); > tree op1 = build_nop (ptrdiff_type_node, expr); > - tree op2 = cp_build_binary_op (input_location, PLUS_EXPR, op1, delta, > - complain); > + tree op2 = cp_build_binary_op (location_t (input_location), > + PLUS_EXPR, op1, delta, complain); > > expr = fold_build3_loc (input_location, > COND_EXPR, ptrdiff_type_node, cond, op1, op2); > @@ -8686,7 +8689,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > tree op2 = TREE_OPERAND (lhs, 2); > if (TREE_CODE (op2) != THROW_EXPR) > op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain); > - tree cond = build_conditional_expr (input_location, > + tree cond = build_conditional_expr (location_t (input_location), > TREE_OPERAND (lhs, 0), op1, op2, > complain); > > @@ -8767,7 +8770,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode, > /* Do the default thing. */; > else > { > - result = build_new_op (input_location, MODIFY_EXPR, > + result = build_new_op (location_t (input_location), MODIFY_EXPR, > LOOKUP_NORMAL, lhs, rhs, > make_node (NOP_EXPR), /*overload=*/NULL, > complain); > @@ -9263,10 +9266,10 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p, > if (!integer_zerop (n)) > { > if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta) > - n = cp_build_binary_op (input_location, > + n = cp_build_binary_op (location_t (input_location), > LSHIFT_EXPR, n, integer_one_node, > complain); > - delta = cp_build_binary_op (input_location, > + delta = cp_build_binary_op (location_t (input_location), > PLUS_EXPR, delta, n, complain); > } > return build_ptrmemfunc1 (to_type, delta, npfn); > diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c > index d58586f2526..3f68d1d79eb 100644 > --- a/gcc/diagnostic.c > +++ b/gcc/diagnostic.c > @@ -1835,7 +1835,7 @@ internal_error (const char *gmsgid, ...) > auto_diagnostic_group d; > va_list ap; > va_start (ap, gmsgid); > - rich_location richloc (line_table, input_location); > + rich_location richloc (line_table, UNKNOWN_LOCATION); > diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE); > va_end (ap); > > diff --git a/gcc/input.c b/gcc/input.c > index 9e39e7df83c..1843c3077aa 100644 > --- a/gcc/input.c > +++ b/gcc/input.c > @@ -122,7 +122,7 @@ public: > > /* Current position in real source file. */ > > -location_t input_location = UNKNOWN_LOCATION; > +poisonable input_location (UNKNOWN_LOCATION); > > class line_maps *line_table; > > diff --git a/gcc/input.h b/gcc/input.h > index f1ef5d76cfd..2b96ce8008e 100644 > --- a/gcc/input.h > +++ b/gcc/input.h > @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see > #ifndef GCC_INPUT_H > #define GCC_INPUT_H > > +#include "poison.h" > #include "line-map.h" > > extern GTY(()) class line_maps *line_table; > @@ -95,7 +96,7 @@ expand_location_to_spelling_point (location_t, > extern location_t expansion_point_location_if_in_system_header (location_t); > extern location_t expansion_point_location (location_t); > > -extern location_t input_location; > +extern poisonable input_location; > > #define LOCATION_FILE(LOC) ((expand_location (LOC)).file) > #define LOCATION_LINE(LOC) ((expand_location (LOC)).line) > diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c > index 3cfcd0b1a57..9ecb91cc56b 100644 > --- a/gcc/objc/objc-next-runtime-abi-02.c > +++ b/gcc/objc/objc-next-runtime-abi-02.c > @@ -1690,7 +1690,7 @@ build_v2_objc_method_fixup_call (int super_flag, tree method_prototype, > fold_convert (rcv_p, integer_zero_node), 1); > > #ifdef OBJCPLUS > - ret_val = build_conditional_expr (input_location, > + ret_val = build_conditional_expr (location_t (input_location), > ifexp, ret_val, ftree, > tf_warning_or_error); > #else > -- > 2.20.1 >