aboutsummaryrefslogtreecommitdiff
path: root/gcc
AgeCommit message (Collapse)AuthorFilesLines
2022-11-13analyzer: new warning: -Wanalyzer-tainted-assertion [PR106235]David Malcolm14-21/+821
This patch adds a new -Wanalyzer-tainted-assertion warning to -fanalyzer's "taint" mode (which also requires -fanalyzer-checker=taint). It complains about attacker-controlled values being used in assertions, or in any expression affecting control flow that guards a "noreturn" function. As noted in the docs part of the patch, in such cases: - when assertion-checking is enabled: an attacker could trigger a denial of service by injecting an assertion failure - when assertion-checking is disabled, such as by defining NDEBUG, an attacker could inject data that subverts the process, since it presumably violates a precondition that is being assumed by the code. For example, given: #include <assert.h> int __attribute__((tainted_args)) test_tainted_assert (int n) { assert (n > 0); return n * n; } compiling with -fanalyzer -fanalyzer-checker=taint gives: t.c: In function 'test_tainted_assert': t.c:6:3: warning: use of attacked-controlled value in condition for assertion [CWE-617] [-Wanalyzer-tainted-assertion] 6 | assert (n > 0); | ^~~~~~ 'test_tainted_assert': event 1 | | 4 | test_tainted_assert (int n) | | ^~~~~~~~~~~~~~~~~~~ | | | | | (1) function 'test_tainted_assert' marked with '__attribute__((tainted_args))' | +--> 'test_tainted_assert': event 2 | | 4 | test_tainted_assert (int n) | | ^~~~~~~~~~~~~~~~~~~ | | | | | (2) entry to 'test_tainted_assert' | 'test_tainted_assert': events 3-6 | |/usr/include/assert.h:106:10: | 106 | if (expr) \ | | ^ | | | | | (3) use of attacker-controlled value for control flow | | (4) following 'false' branch (when 'n <= 0')... |...... | 109 | __assert_fail (#expr, __FILE__, __LINE__, __ASSERT_FUNCTION); \ | | ~~~~~~~~~~~~~ | | | | | (5) ...to here | | (6) treating '__assert_fail' as an assertion failure handler due to '__attribute__((__noreturn__))' | The testcases have various examples for BUG and BUG_ON from the Linux kernel; there, the diagnostic treats "panic" as an assertion failure handler, due to '__attribute__((__noreturn__))'. gcc/analyzer/ChangeLog: PR analyzer/106235 * analyzer.opt (Wanalyzer-tainted-assertion): New. * checker-path.cc (checker_path::fixup_locations): Pass false to pending_diagnostic::fixup_location. * diagnostic-manager.cc (get_emission_location): Pass true to pending_diagnostic::fixup_location. * pending-diagnostic.cc (pending_diagnostic::fixup_location): Add bool param. * pending-diagnostic.h (pending_diagnostic::fixup_location): Add bool param to decl. * sm-taint.cc (taint_state_machine::m_tainted_control_flow): New. (taint_diagnostic::describe_state_change): Drop "final". (class tainted_assertion): New. (taint_state_machine::taint_state_machine): Initialize m_tainted_control_flow. (taint_state_machine::alt_get_inherited_state): Support comparisons being tainted, based on their arguments. (is_assertion_failure_handler_p): New. (taint_state_machine::on_stmt): Complain about calls to assertion failure handlers guarded by an attacker-controller conditional. Detect attacker-controlled gcond conditionals and gswitch index values. (taint_state_machine::check_control_flow_arg_for_taint): New. gcc/ChangeLog: PR analyzer/106235 * doc/gcc/gcc-command-options/option-summary.rst: Add -Wno-analyzer-tainted-assertion. * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: Add -Wno-analyzer-tainted-assertion. gcc/testsuite/ChangeLog: PR analyzer/106235 * gcc.dg/analyzer/taint-assert-BUG_ON.c: New test. * gcc.dg/analyzer/taint-assert-macro-expansion.c: New test. * gcc.dg/analyzer/taint-assert.c: New test. * gcc.dg/analyzer/taint-assert-system-header.c: New test. * gcc.dg/analyzer/test-assert.h: New header. * gcc.dg/plugin/analyzer_gil_plugin.c (gil_diagnostic::fixup_location): Add bool param. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-11-13Fortran: diagnostics for actual arguments to pointer dummy arguments [PR94104]José Rui Faustino de Sousa4-18/+90
Error message improvement. In Fortran 2008 actual procedure arguments associated with a pointer, intent(in) attribute, dummy argument can also have the target attribute, not just pointer. gcc/fortran/ChangeLog: PR fortran/94104 * interface.cc (gfc_compare_actual_formal): Improve error message dependent on Fortran standard level. gcc/testsuite/ChangeLog: PR fortran/94104 * gfortran.dg/parens_2.f90: Adjust to improved error message. * gfortran.dg/PR94104a.f90: New test. * gfortran.dg/PR94104b.f90: New test.
2022-11-13Skip guality tests on hppa-hpux.John David Anglin3-0/+12
The guality check command hangs. This causes TCL errors in other tests and slows testsuite execution. 2022-11-13 John David Anglin <danglin@gcc.gnu.org> gcc/testsuite/ChangeLog: * g++.dg/guality/guality.exp: Skip on hppa*-*-hpux*. * gcc.dg/guality/guality.exp: Likewise. * gfortran.dg/guality/guality.exp: Likewise.
2022-11-13RISC-V: optimize '(a >= 0) ? b : 0' to srai + andn, if compiling for ZbbPhilipp Tomsich2-0/+28
If-conversion is turning '(a >= 0) ? b : 0' into a branchless sequence not a5,a0 srai a5,a5,63 and a0,a1,a5 missing the opportunity to combine the NOT and AND into an ANDN. This adds a define_split to help the combiner reassociate the NOT with the AND. gcc/ChangeLog: * config/riscv/bitmanip.md: New define_split. gcc/testsuite/ChangeLog: * gcc.target/riscv/zbb-srai-andn.c: New test.
2022-11-13RISC-V: costs: support shift-and-add in strength-reductionPhilipp Tomsich2-0/+50
The strength-reduction implementation in expmed.cc will assess the profitability of using shift-and-add using a RTL expression that wraps a MULT (with a power-of-2) in a PLUS. Unless the RISC-V rtx_costs function recognizes this as expressing a sh[123]add instruction, we will return an inflated cost---thus defeating the optimization. This change adds the necessary idiom recognition to provide an accurate cost for this for of expressing sh[123]add. Instead on expanding to li a5,200 mulw a0,a5,a0 with this change, the expression 'a * 200' is sythesized as: sh2add a0,a0,a0 // *5 = a + 4 * a sh2add a0,a0,a0 // *5 = a + 4 * a slli a0,a0,3 // *8 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_rtx_costs): Recognize shNadd, if expressed as a plus and multiplication with a power-of-2. Split costing for MINUS from PLUS. gcc/testsuite/ChangeLog: * gcc.target/riscv/zba-shNadd-07.c: New test.
2022-11-13configure: always set SPHINX_BUILDMartin Liska2-2/+2
During the Sphinx-migration development, I used SPHINX_BUILD='' in order to skip building info and manual pages in gcc folder. However, we've got HAS_SPHINX_BUILD which is the correct flag for that. With the patch, one will get a nicer error message when sphinx-build is missing and one builds (explicitly) a target which depends on it. PR other/107620 gcc/ChangeLog: * configure: Regenerate. * configure.ac: Always set sphinx-build. libgomp/ChangeLog: * configure: Regenerate. * configure.ac: Always set sphinx-build. libiberty/ChangeLog: * configure: Regenerate. * configure.ac: Always set sphinx-build. libitm/ChangeLog: * configure: Regenerate. * configure.ac: Always set sphinx-build. libquadmath/ChangeLog: * configure: Regenerate. * configure.ac: Always set sphinx-build.
2022-11-13ginclude: C2x header version macrosJoseph Myers18-0/+151
C2x adds __STDC_VERSION_*_H__ macros to individual headers with interface changes compared to C17. All the new header features in headers provided by GCC have now been implemented, so define those macros to the value given in the current working draft. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/ * ginclude/float.h [__STDC_VERSION__ > 201710L] (__STDC_VERSION_FLOAT_H__): New macro. * ginclude/stdarg.h [__STDC_VERSION__ > 201710L] (__STDC_VERSION_STDARG_H__): New macro. * ginclude/stdatomic.h [__STDC_VERSION__ > 201710L] (__STDC_VERSION_STDATOMIC_H__): New macro. * ginclude/stddef.h [__STDC_VERSION__ > 201710L] (__STDC_VERSION_STDDEF_H__): New macro. * ginclude/stdint-gcc.h [__STDC_VERSION__ > 201710L] (__STDC_VERSION_STDINT_H__): New macro. * glimits.h [__STDC_VERSION__ > 201710L] (__STDC_VERSION_LIMITS_H__): New macro. gcc/testsuite/ * gcc.dg/c11-float-8.c, gcc.dg/c11-limits-1.c, gcc.dg/c11-stdarg-4.c, gcc.dg/c11-stdatomic-3.c, gcc.dg/c11-stddef-1.c, gcc.dg/c11-stdint-1.c, gcc.dg/c2x-float-13.c, gcc.dg/c2x-limits-1.c, gcc.dg/c2x-stdarg-5.c, gcc.dg/c2x-stdatomic-1.c, gcc.dg/c2x-stddef-1.c, gcc.dg/c2x-stdint-1.c: New tests.
2022-11-13doc: Remove outdated reference to "core" and front-end downloadsJonathan Wakely1-3/+1
gcc/ChangeLog: * doc/install/testing.rst: Remove anachronism about separate source tarballs.
2021-11-06Fortran: Remove unused declarationBernhard Reutner-Fischer1-1/+0
This function was removed years ago, remove it's prototype. gcc/fortran/ChangeLog: * gfortran.h (gfc_check_include): Remove declaration.
2022-11-13Daily bump.GCC Administrator6-1/+208
2022-11-12Fortran: fix treatment of character, value, optional dummy arguments [PR107444]Harald Anlauf6-23/+84
Fix handling of character dummy arguments that have the optional+value attribute. Change name of internal symbols that carry the hidden presence status of optional arguments to distinguish them from the internal hidden character length. Update documentation to clarify the gfortran ABI. gcc/fortran/ChangeLog: PR fortran/107444 * trans-decl.cc (create_function_arglist): Extend presence status to all intrinsic types, and change prefix of internal symbol to '.'. * trans-expr.cc (gfc_conv_expr_present): Align to changes in create_function_arglist. (gfc_conv_procedure_call): Fix generation of procedure arguments for the case of character dummy arguments with optional+value attribute. * trans-types.cc (gfc_get_function_type): Synchronize with changes to create_function_arglist. * doc/gfortran/naming-and-argument-passing-conventions.rst: Clarify the gfortran argument passing conventions with regard to OPTIONAL dummy arguments of intrinsic type. gcc/testsuite/ChangeLog: PR fortran/107444 * gfortran.dg/optional_absent_7.f90: Adjust regex. * gfortran.dg/optional_absent_8.f90: New test.
2022-11-12c: C2x constexprJoseph Myers22-97/+1539
Implement C2x constexpr (a feature based on the C++ one but much more minimal, with only constexpr variables, not functions). I believe this implementation is fully functional for use of this feature. However, there are several things that seem unclear about the specification that I'll need to raise in NB comments. There are also areas where there may be followup bug fixes because the implementation doesn't reject some more obscure cases that ought to be rejected: cases where a constexpr initializer for floating type meets the constraints for a constant expression in initializers but not those for an arithmetic constant expression (previously we haven't had to track whether something is an arithmetic constant expression in detail, unlike with integer constant expressions), and some cases where a tag or struct or union member gets declared indirectly in the declaration specifiers or declarator of a constexpr declaration, which is not permitted (modulo lack of clarity in the specification) for underspecified declarations in general (the cases of a declaration in the initializer, or a tagged type being directly declared as a type specifier, are already detected). Cases of ambiguity in the specification include: * Many questions (previously raised in WG14 discussions) over the rule about what conversions do or do not involve a change of value that's not allowed in a constexpr initializer, that aren't properly addressed by the normative text (and where the footnote on the subject isn't very clear either, and the examples don't necessarily follow from the normative text). I've made a series of choices there, that include disallowing all conversions between real and complex types or between binary and decimal floating types in constexpr initializers, that might not necessarily agree with how things end up getting clarified. The dfp.cc change also arises here, to allow quiet NaN initializers of one DFP type to be used in a constexpr initializer for another DFP type (as is possible for signaling NaNs) by ensuring the result of such a conversion is properly marked as canonical (note that most of the DFP code doesn't actually do anything with NaN payloads at all). * Various issues with what exactly counts as part of a declaration for the purposes of the rule on underspecified declarations not declaring any identifiers other than ordinary identifiers (and not declaring more than one ordinary identifier, though the latter is undefined behavior). These include cases where the declaration of a struct / union / enum type appears inside typeof or alignas in the declaration specifiers (the latter also applies with auto), or in the declarator (e.g. an array size or in a parameter declaration). The issues are similar to those involved in C90 DR#115 and C99 DRs #277 and #341; the intent may not be the same in all the different cases involved, but it's not clear that the normative wording in the various places is sufficient to deduce the differences in intent. * The wording about producing a compound literal constant using member access is present in one place but another place only applies that to named constants. * It's not clear when a structure or union constant (a constexpr variable or compound literal with structure or union type, or a member with such type extracted by a series of member access operations) can itself be used in an initializer (constexpr or otherwise). Based on general wording for initializers not having been changed, the working draft might only strictly allow it at automatic storage duration (but elsewhere it would be undefined behavior, not a constraint violation, so no diagnostic required) - since that's the only case mentioned where a single expression of structure or union type can be used to initialize an object of such a type. But it definitely seems to be allowed in even constexpr initializers at automatic storage duration - and since generally constexpr initializers (any storage duration) are *more* constrained than ordinary static storage duration initializers, it would seem odd for it not to be allowed at static storage duration. * When you do allow such initializers, it's then not entirely clear how the constraint that constexpr pointer initializers must be null pointer constants should be applied (given that a constexpr object of pointer type is a null pointer but *not* a null pointer constant). My guess would be that a constexpr struct or union containing such a field should still be allowed as an initializer, but the wording could be read otherwise. * It also becomes important with constexpr exactly what kind of constant expression an implicit zero initializer is; the wording for default initialization only really deals with the value of the initializer and not what kind of constant it is. In particular, this affects whether {} is a valid constexpr initializer for a pointer not of type void *, since the wording only talks about a null pointer, not whether it's a null pointer *constant*. I assumed that it should be a null pointer constant in that case. * It's also not entirely clear whether constexpr can be used in the declaration part of a for loop (which "shall only declare identifiers for objects having storage class auto or register"). I interpreted it as allowed (treating such objects as implicitly auto just like those with no storage class specifiers), but it could also be argued that constexpr is another storage class specifier and so not allowed there. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/ * dfp.cc (decimal_from_binary): Convert a canonical NaN to a canonical NaN. gcc/c-family/ * c-common.cc (c_common_reswords): Use D_C2X instead of D_CXXONLY. gcc/c/ * c-decl.cc (start_underspecified_init) (finish_underspecified_init): Handle name == NULL_TREE for compound literals. (merge_decls): Merge C_DECL_DECLARED_CONSTEXPR. (shadow_tag_warned): Check for constexpr. (start_decl): Add parameter do_push. (build_compound_literal): Set C_DECL_DECLARED_CONSTEXPR. (grokdeclarator): Handle constexpr. (finish_struct): Set C_TYPE_FIELDS_NON_CONSTEXPR. (declspecs_add_scspec): Handle constexpr. * c-parser.cc (c_token_starts_compound_literal) (c_token_starts_declspecs, c_parser_declaration_or_fndef) (c_parser_declspecs, c_parser_gnu_attribute_any_word) (c_parser_compound_literal_scspecs) (c_parser_postfix_expression_after_paren_type): Handle constexpr. Update calls to start_init. (c_parser_declaration_or_fndef, c_parser_initializer) (c_parser_initval): Pass true for new argument of convert_lvalue_to_rvalue. Call convert_lvalue_to_rvalue for constexpr compound literals. (c_parser_static_assert_declaration_no_semi) (c_parser_enum_specifier, c_parser_struct_declaration) (c_parser_alignas_specifier, c_parser_initelt, c_parser_label): Call convert_lvalue_to_rvalue on expressions required to be integer constant expressions. (c_parser_omp_declare_reduction): Update call to start_init. * c-tree.h (C_TYPE_FIELDS_NON_CONSTEXPR) (C_DECL_DECLARED_CONSTEXPR): New macros. (struct c_declspecs): Add constexpr_p. (start_decl, convert_lvalue_to_rvalue, start_init): Update prototypes. * c-typeck.cc (require_constant_value, require_constant_elements): Change to bool. (require_constexpr_value, maybe_get_constexpr_init) (constexpr_init_fits_real_type, check_constexpr_init): New. (convert_lvalue_to_rvalue): Add new parameter for_init. Call maybe_get_constexpr_init. (store_init_value): Update call to digest_init. (digest_init): Add parameters int_const_expr, arith_const_expr and require_constexpr. Check constexpr initializers. (constructor_top_level): Remove. (struct initializer_stack): Remove top_level. Add require_constexpr_value. (start_init): Remove parameter top_level. Add parameters init_require_constant and init_require_constexpr. Save require_constexpr_value on stack. (pop_init_level): Use a null pointer constant for zero initializer of pointer initialized with {}. (output_init_element): Update call to digest_init. Avoid passing null pointer constants of pointer type through digest_init a second time when initializing a constexpr object. gcc/testsuite/ * gcc.dg/c11-keywords-1.c: Also test constexpr. * gcc.dg/c2x-constexpr-1.c, gcc.dg/c2x-constexpr-2a.c, gcc.dg/c2x-constexpr-2b.c, gcc.dg/c2x-constexpr-3.c, gcc.dg/c2x-constexpr-4.c, gcc.dg/c2x-constexpr-5.c, gcc.dg/c2x-constexpr-6.c, gcc.dg/c2x-constexpr-7.c, gcc.dg/c2x-constexpr-8.c, gcc.dg/c2x-constexpr-9.c, gcc.dg/dfp/c2x-constexpr-dfp-1.c, gcc.dg/dfp/c2x-constexpr-dfp-2.c, gcc.dg/gnu2x-constexpr-1.c, gcc.target/i386/excess-precision-11.c, gcc.target/i386/excess-precision-12.c: New tests.
2022-11-12[frange] Avoid testing signed zero test for -fno-signed-zeros.Aldy Hernandez1-4/+5
This patch moves a test that is meant to only work for signed zeros into range_tests_signed_zeros. I am not aware of any architectures where this is failing, but it is annoying to see selftests failing when -fno-signed-zeros is used. gcc/ChangeLog: * value-range.cc (range_tests_signbit): Move to set from here... (range_tests_signed_zeros): ...to here.
2022-11-12[range-ops] Add ability to represent open intervals in frange.Aldy Hernandez1-4/+19
Currently we represent < and > with a closed interval. So < 3.0 is represented as [-INF, +3.0]. This means 3.0 is included in the range, and though not ideal, is conservatively correct. Jakub has found a couple cases where properly representing < and > would help optimizations and tests, and this patch allows representing open intervals with real_nextafter. There are a few caveats. First, we leave MODE_COMPOSITE_P types pessimistically as a closed interval. Second, for -ffinite-math-only, real_nextafter will saturate the maximum representable number into +INF. However, this will still do the right thing, as frange::set() will crop things appropriately. Finally, and most frustratingly, representing < and > -+0.0 is problematic because we flush denormals to zero. Let me explain... real_nextafter(+0.0, +INF) gives 0x0.8p-148 as expected, but setting a range to this value yields [+0.0, 0x0.8p-148] because of the flushing. On the other hand, real_nextafter(+0.0, -INF) (surprisingly) gives -0.0.8p-148, but setting a range to that value yields [-0.0x8p-148, -0.0]. I say surprising, because according to cppreference.com, std::nextafter(+0.0, -INF) should give -0.0. But that's neither here nor there because our flushing denormals to zero prevents us from even representing ranges involving small values around 0.0. We ultimately end up with ranges looking like this: > +0.0 => [+0.0, INF] > -0.0 => [+0.0, INF] < +0.0 => [-INF, -0.0] < -0.0 => [-INF, -0.0] I suppose this is no worse off that what we had before with closed intervals. One could even argue that we're better because we at least have the right sign now ;-). gcc/ChangeLog: * range-op-float.cc (build_lt): Adjust with frange_nextafter instead of default to a closed range. (build_gt): Same.
2022-11-12range-op: Implement op[12]_range operators for {PLUS,MINUS,MULT,RDIV}_EXPRJakub Jelinek2-0/+157
On Wed, Nov 09, 2022 at 04:43:56PM +0100, Aldy Hernandez wrote: > On Wed, Nov 9, 2022 at 3:58 PM Jakub Jelinek <jakub@redhat.com> wrote: > > > > On Wed, Nov 09, 2022 at 10:02:46AM +0100, Aldy Hernandez wrote: > > > We can implement the op[12]_range entries for plus and minus in terms > > > of each other. These are adapted from the integer versions. > > > > I think for NANs the op[12]_range shouldn't act this way. > > For the forward binary operations, we have the (maybe/known) NAN handling > > of one or both NAN operands resulting in VARYING sign (maybe/known) NAN > > result, that is the somehow the case for the reverse binary operations too, > > if result is (maybe/known) NAN and the other op is not NAN, op is > > VARYING sign (maybe/known) NAN, if other op is (maybe/known) NAN, > > then op is VARYING sign maybe NAN (always maybe, never known). > > But then for + we have the -INF + INF or vice versa into NAN, and that > > is something that shouldn't be considered. If result isn't NAN, then > > neither operand can be NAN, regardless of whether result can be > > +/- INF and the other op -/+ INF. > > Heh. I just ran into this while debugging the problem reported by Xi. > > We are solving NAN = op1 - VARYING, and trying to do it with op1 = NAN > + VARYING, which returns op1 = NAN (incorrectly). > > I suppose in the above case op1 should ideally be > [-INF,-INF][+INF,+INF]+-NAN, but since we can't represent that then > [-INF,+INF] +-NAN, which is actually VARYING. Do you agree? > > I'm reverting this patch as attached, while I sort this out. Here is a patch which reinstalls your change, add the fixups I've talked about and also hooks up reverse operators for MULT_EXPR/RDIV_EXPR. 2022-11-12 Aldy Hernandez <aldyh@redhat.com> Jakub Jelinek <jakub@redhat.com> * range-op-float.cc (float_binary_op_range_finish): New function. (foperator_plus::op1_range): New. (foperator_plus::op2_range): New. (foperator_minus::op1_range): New. (foperator_minus::op2_range): New. (foperator_mult::op1_range): New. (foperator_mult::op2_range): New. (foperator_div::op1_range): New. (foperator_div::op2_range): New. * gcc.c-torture/execute/ieee/inf-4.c: New test.
2022-11-12range-op: Cleanup floating point multiplication and division fold_range ↵Jakub Jelinek1-196/+157
[PR107569] Admittedly there are many similar spots with the foperator_div case (but also with significant differences), so perhaps if foperator_{mult,div} inherit from some derived class from range_operator_float and that class would define various smaller helper static? methods, like this discussed in the PR - contains_zero_p, singleton_nan_p, zero_p, that + bool must_have_signbit_zero = false; + bool must_have_signbit_nonzero = false; + if (real_isneg (&lh_lb) == real_isneg (&lh_ub) + && real_isneg (&rh_lb) == real_isneg (&rh_ub)) + { + if (real_isneg (&lh_lb) == real_isneg (&rh_ub)) + must_have_signbit_zero = true; + else + must_have_signbit_nonzero = true; + } returned as -1/0/1 int, and those set result (based on the above value) to [+INF, +INF], [-INF, -INF] or [-INF, +INF] or [+0, +0], [-0, -0] or [-0, +0] or [+0, +INF], [-INF, -0] or [-INF, +INF] and the + for (int i = 1; i < 4; ++i) + { + if (real_less (&cp[i], &cp[0]) + || (real_iszero (&cp[0]) && real_isnegzero (&cp[i]))) + std::swap (cp[i], cp[0]); + if (real_less (&cp[4], &cp[i + 4]) + || (real_isnegzero (&cp[4]) && real_iszero (&cp[i + 4]))) + std::swap (cp[i + 4], cp[4]); + } block, it could be smaller and more readable. 2022-11-12 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/107569 * range-op-float.cc (zero_p, contains_p, singleton_inf_p, signbit_known_p, zero_range, inf_range, zero_to_inf_range): New functions. (foperator_mult_div_base): New class. (foperator_mult, foperator_div): Derive from that and use protected static method from it as well as above new functions to simplify the code.
2022-11-12range-op: Implement floating point division fold_range [PR107569]Jakub Jelinek1-0/+178
Here is the floating point division fold_range implementation, as I wrote in the last mail, we could outline some of the common parts into static methods with descriptive names and share them between foperator_div and foperator_mult. Regressions are +FAIL: gcc.dg/pr95115.c execution test +FAIL: libphobos.phobos/std/math/hardware.d execution test +FAIL: libphobos.phobos_shared/std/math/hardware.d execution test The first test is we have: # RANGE [frange] double [] +-NAN _3 = Inf / Inf; if (_3 ord _3) goto <bb 3>; [INV] else goto <bb 4>; [INV] <bb 3> : abort (); <bb 4> : before evrp, the range is correct, Inf / Inf is known NAN of unknown sign. evrp correctly folds _3 ord _3 into false and the _3 = Inf / Inf; remains in the IL, but then comes dse1 and removes it as dead statement. So, I think yet another example of the PR107608 problems where DCE? removes dead statements which raise floating point exceptions. And -fno-delete-dead-exceptions doesn't help. 2022-11-12 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/107569 * range-op-float.cc (foperator_div): New class. (floating_op_table::floating_op_table): Use foperator_div for RDIV_EXPR.
2022-11-12range-op: Implement floating point multiplication fold_range [PR107569]Jakub Jelinek2-7/+187
The following patch implements frange multiplication, including the special case of x * x. The callers don't tell us that it is x * x, just that it is either z = x * x or if (x == y) z = x * y; For irange that makes no difference, but for frange it can mean x is -0.0 and y is 0.0 if they have the same range that includes both signed and unsigned zeros, so we need to assume result could be -0.0. The patch causes one regression: +FAIL: gcc.dg/fold-overflow-1.c scan-assembler-times 2139095040 2 but that is already tracked in PR107608 and affects not just the newly added multiplication, but addition and other floating point operations (and doesn't seem like a ranger bug but dce or whatever else). 2022-11-12 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/107569 PR tree-optimization/107591 * range-op.h (range_operator_float::rv_fold): Add relation_kind argument. * range-op-float.cc (range_operator_float::fold_range): Name last argument trio and pass trio.op1_op2 () as last argument to rv_fold. (range_operator_float::rv_fold): Add relation_kind argument. (foperator_plus::rv_fold, foperator_minus::rv_fold): Likewise. (foperator_mult): New class. (floating_op_table::floating_op_table): Use foperator_mult for MULT_EXPR.
2022-11-12LoongArch: Add flogb.{s,d} instructions and expand logb{sf,df}2Xi Ruoyao2-2/+51
On LoongArch, flogb instructions extract the exponent of a non-negative floating point value, but produces NaN for negative values. So we need to add a fabs instruction when we expand logb. gcc/ChangeLog: * config/loongarch/loongarch.md (UNSPEC_FLOGB): New unspec. (type): Add flogb. (logb_non_negative<mode>2): New instruction template. (logb<mode>2): New define_expand. gcc/testsuite/ChangeLog: * gcc.target/loongarch/flogb.c: New test.
2022-11-12LoongArch: Add fscaleb.{s,d} instructions as ldexp{sf,df}3Xi Ruoyao2-2/+72
This allows optimizing __builtin_ldexp{,f} and __builtin_scalbn{,f} with -fno-math-errno. IMODE is added because we can't hard code SI for operand 2: fscaleb.d instruction always take the high half of both source registers into account. See my_ldexp_long in the test case. gcc/ChangeLog: * config/loongarch/loongarch.md (UNSPEC_FSCALEB): New unspec. (type): Add fscaleb. (IMODE): New mode attr. (ldexp<mode>3): New instruction template. gcc/testsuite/ChangeLog: * gcc.target/loongarch/fscaleb.c: New test.
2022-11-12LoongArch: Add ftint{,rm,rp}.{w,l}.{s,d} instructionsXi Ruoyao3-0/+122
This allows to optimize the following builtins if -fno-math-errno: - __builtin_lrint{,f} - __builtin_lfloor{,f} - __builtin_lceil{,f} Inspired by https://gcc.gnu.org/pipermail/gcc-patches/2022-November/605287.html. ANYFI is added so the compiler won't try ftint.l.s if -mfpu=32. If we simply used GPR here an ICE would be triggered with __builtin_lrintf and -mfpu=32. ftint{rm,rp} instructions may raise inexact exception, so they can't be used if -fno-trapping-math -fno-fp-int-builtin-inexact. Note that the .w.{s,d} variants are not tested because we don't support ILP32 for now. gcc/ChangeLog: * config/loongarch/loongarch.md (UNSPEC_FTINT): New unspec. (UNSPEC_FTINTRM): Likewise. (UNSPEC_FTINTRP): Likewise. (LRINT): New define_int_iterator. (lrint_pattern): New define_int_attr. (lrint_submenmonic): Likewise. (lrint_allow_inexact): Likewise. (ANYFI): New define_mode_iterator. (lrint<ANYF><ANYFI>): New instruction template. gcc/testsuite/ChangeLog: * gcc.target/loongarch/ftint.c: New test. * gcc.target/loongarch/ftint-no-inexact.c: New test.
2022-11-12LoongArch: Rename frint_<fmt> to rint<mode>2Xi Ruoyao2-2/+18
Use standard name so __builtin_rint{,f} can be expanded to one instruction. gcc/ChangeLog: * config/loongarch/loongarch.md (frint_<fmt>): Rename to .. (rint<mode>2): .. this. gcc/testsuite/ChangeLog: * gcc.target/loongarch/frint.c: New test.
2022-11-12Daily bump.GCC Administrator6-1/+283
2022-11-11analyzer: more state machine documentationDavid Malcolm4-2/+125
gcc/analyzer/ChangeLog: * sm-fd.dot: Fix typo in comment. * sm-file.dot: New file. * varargs.cc: Fix typo in comment. * varargs.dot: New file. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-11-11analyzer: split out checker_event classes to their own headerDavid Malcolm2-582/+612
gcc/analyzer/ChangeLog: * checker-path.h: Split out checker_event and its subclasses to... * checker-event.h: ...this new header. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-11-11analyzer: new warning: -Wanalyzer-infinite-recursion [PR106147]David Malcolm34-37/+1590
This patch adds a new -Wanalyzer-infinite-recursion warning to -fanalyzer, which complains about certain cases of infinite recursion. Specifically, when it detects recursion during its symbolic execution of the user's code, it compares the state of memory to that at the previous level of recursion, and if nothing appears to have effectively changed, it issues a warning. Unlike the middle-end warning -Winfinite-recursion (added by Martin Sebor in GCC 12; r12-5483-g30ba058f77eedf), the analyzer warning complains if there exists an interprocedural path in which recursion occurs in which memory has not changed, whereas -Winfinite-recursion complains if *every* intraprocedural path through the function leads to a self-call. Hence the warnings complement each other: there's some overlap, but each also catches issues that the other misses. For example, the new warning complains about a guarded recursion in which the guard is passed unchanged: void test_guarded (int flag) { if (flag) test_guarded (flag); } t.c: In function 'test_guarded': t.c:4:5: warning: infinite recursion [CWE-674] [-Wanalyzer-infinite-recursion] 4 | test_guarded (flag); | ^~~~~~~~~~~~~~~~~~~ 'test_guarded': events 1-4 | | 1 | void test_guarded (int flag) | | ^~~~~~~~~~~~ | | | | | (1) initial entry to 'test_guarded' | 2 | { | 3 | if (flag) | | ~ | | | | | (2) following 'true' branch (when 'flag != 0')... | 4 | test_guarded (flag); | | ~~~~~~~~~~~~~~~~~~~ | | | | | (3) ...to here | | (4) calling 'test_guarded' from 'test_guarded' | +--> 'test_guarded': events 5-6 | | 1 | void test_guarded (int flag) | | ^~~~~~~~~~~~ | | | | | (5) recursive entry to 'test_guarded'; previously entered at (1) | | (6) apparently infinite recursion | whereas the existing warning doesn't complain, since when "flag" is false the function doesn't recurse. The new warning doesn't trigger for e.g.: void test_param_variant (int depth) { if (depth > 0) test_param_variant (depth - 1); } on the grounds that "depth" is changing, and appears to be a variant that enforces termination of the recursion. gcc/ChangeLog: PR analyzer/106147 * Makefile.in (ANALYZER_OBJS): Add analyzer/infinite-recursion.o. gcc/analyzer/ChangeLog: PR analyzer/106147 * analyzer.opt (Wanalyzer-infinite-recursion): New. * call-string.cc (call_string::count_occurrences_of_function): New. * call-string.h (call_string::count_occurrences_of_function): New decl. * checker-path.cc (function_entry_event::function_entry_event): New ctor. (checker_path::add_final_event): Delete. * checker-path.h (function_entry_event::function_entry_event): New ctor. (function_entry_event::get_desc): Drop "final". (checker_path::add_final_event): Delete. * diagnostic-manager.cc (diagnostic_manager::emit_saved_diagnostic): Create the final event via a new pending_diagnostic::add_final_event vfunc, rather than checker_path::add_final_event. (diagnostic_manager::add_events_for_eedge): Create function entry events via a new pending_diagnostic::add_function_entry_event vfunc. * engine.cc (exploded_graph::process_node): When creating a new PK_BEFORE_SUPERNODE node, call exploded_graph::detect_infinite_recursion on it after adding the in-edge. * exploded-graph.h (exploded_graph::detect_infinite_recursion): New decl. (exploded_graph::find_previous_entry_to): New decl. * infinite-recursion.cc: New file. * pending-diagnostic.cc (pending_diagnostic::add_function_entry_event): New. (pending_diagnostic::add_final_event): New. * pending-diagnostic.h (pending_diagnostic::add_function_entry_event): New vfunc. (pending_diagnostic::add_final_event): New vfunc. gcc/ChangeLog: PR analyzer/106147 * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: Add -Wanalyzer-infinite-recursion. * doc/gcc/gcc-command-options/options-to-request-or-suppress-warnings.rst (-Winfinite-recursion): Mention -Wanalyzer-infinite-recursion. gcc/testsuite/ChangeLog: PR analyzer/106147 * g++.dg/analyzer/infinite-recursion-1.C: New test. * g++.dg/analyzer/infinite-recursion-2.C: New test, copied from g++.dg/warn/Winfinite-recursion-2.C. * g++.dg/analyzer/infinite-recursion-3.C: New test, adapted from g++.dg/warn/Winfinite-recursion-3.C. * gcc.dg/analyzer/infinite-recursion-2.c: New test. * gcc.dg/analyzer/infinite-recursion-3.c: New test. * gcc.dg/analyzer/infinite-recursion-4-limited-buggy.c: New test. * gcc.dg/analyzer/infinite-recursion-4-limited.c: New test. * gcc.dg/analyzer/infinite-recursion-4-unlimited-buggy.c: New test. * gcc.dg/analyzer/infinite-recursion-4-unlimited.c: New test. * gcc.dg/analyzer/infinite-recursion-5.c: New test, adapted from gcc.dg/Winfinite-recursion.c. * gcc.dg/analyzer/infinite-recursion-alloca.c: New test. * gcc.dg/analyzer/infinite-recursion-inlining.c: New test. * gcc.dg/analyzer/infinite-recursion-multiline-1.c: New test. * gcc.dg/analyzer/infinite-recursion-multiline-2.c: New test. * gcc.dg/analyzer/infinite-recursion-variadic.c: New test. * gcc.dg/analyzer/infinite-recursion.c: Add dg-warning directives where infinite recursions occur. * gcc.dg/analyzer/malloc-ipa-12.c: Likewise. * gcc.dg/analyzer/pr105365.c: Likewise. * gcc.dg/analyzer/pr105366.c: Likewise. * gcc.dg/analyzer/pr97029.c: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-11-11Don't add dependencies in update_stmt.Andrew MacLeod2-1/+33
gimple_ranger::update_stmt has no idea what the context of an update is, and should not be adding relations when it re-evaluates a stmt. PR tree-optimization/107523 gcc/ * gimple-range.cc (gimple_ranger::update_stmt): Use fur_stmt rather than fur_depend. gcc/testsuite/ * gcc.dg/pr107523.c: New.
2022-11-11process transitive inferred ranges in pre_fold_stmt.Andrew MacLeod1-9/+7
The subst_and_fold engine can perform some folding activity before calling fold_stmt, so do this work in pre_fold_stmt instead. * tree-vrp.cc (rvrp_folder::rvrp_folder): Init m_last_bb_stmt. (rvrp_folder::pre_fold_bb): Set m_last_bb_stmt. (rvrp_folder::pre_fold_stmt): Check for transitive inferred ranges. (rvrp_folder::fold_stmt): Check in pre_fold_stmt instead.
2022-11-11aarch64: Add support for Cortex-X1C CPU.Srinath Parvathaneni3-2/+3
This patch adds support for Cortex-X1C CPU. Regards, Srinath. gcc/ChangeLog: 2022-11-09 Srinath Parvathaneni <srinath.parvathaneni@arm.com> * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add Cortex-X1C CPU. * config/aarch64/aarch64-tune.md: Regenerate. * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst: Document Cortex-X1C CPU.
2022-11-11aarch64: Add support for Cortex-A715 CPU.Srinath Parvathaneni3-2/+5
This patch adds support for Cortex-A715 CPU. Regards, Srinath. gcc/ChangeLog: 2022-11-09 Srinath Parvathaneni <srinath.parvathaneni@arm.com> * config/aarch64/aarch64-cores.def (AARCH64_CORE): Add Cortex-A715 CPU. * config/aarch64/aarch64-tune.md: Regenerate. * doc/gcc/gcc-command-options/machine-dependent-options/aarch64-options.rst: Document Cortex-A715 CPU.
2022-11-11tree-optimization/107554 - fix ICE in stlen optimizationRichard Biener2-1/+13
The following fixes a wrongly typed variable causing an ICE. PR tree-optimization/107554 * tree-ssa-strlen.cc (strlen_pass::count_nonzero_bytes): Use unsigned HOST_WIDE_INT type for the strlen. * gcc.dg/pr107554.c: New testcase. Co-Authored-By: Nikita Voronov <nik_1357@mail.ru>
2022-11-11tree-optimization/105142 - improve maybe_fold_comparisons_from_match_pd fixRichard Biener1-1/+24
The following improves on the fix for PR105142 which restricted the expression lookup used for maybe_fold_comparisons_from_match_pd to avoid picking up flow-sensitive info for use in places where guarding conditions do not hold. Instead of not allowing to expand SSA definitions there the following temporarily clears flow-sensitive info on the SSA names and restores it when finished matching. PR tree-optimization/105142 * gimple-fold.cc (fosa_unwind): New global. (follow_outer_ssa_edges): When the SSA definition to follow is does not dominate fosa_bb, temporarily clear flow-sensitive info. Make sure to not expand stmts with not defined overflow. (maybe_fold_comparisons_from_match_pd): Set up unwind stack for follow_outer_ssa_edges and unwind flow-sensitive info clearing after matching.
2022-11-11[range-ops] Remove specialized fold_range methods for various operators.Aldy Hernandez1-52/+0
Remove some specialized fold_range methods that were merely setting maybe nonzero masks, as these are now subsumed by the generic version. gcc/ChangeLog: * range-op.cc (operator_mult::fold_range): Remove. (operator_div::fold_range): Remove. (operator_bitwise_and): Remove.
2022-11-11[range-ops] Avoid unnecessary intersection in update_known_bitmask.Aldy Hernandez1-4/+1
All the work for keeping the maybe nonzero masks up to date is being done by the bit-CCP code now. Any bitmask inherent in the range that range-ops may have calculated has no extra information, so the intersection is unnecessary. gcc/ChangeLog: * range-op.cc (update_known_bitmask): Avoid unnecessary intersection.
2022-11-11[range-ops] Update known bitmasks using CCP for all operators.Aldy Hernandez1-1/+4
Use bit-CCP to calculate bitmasks for all integer operators, instead of the half-assed job we were doing with just a handful of operators. This sets us up nicely for tracking known-one bitmasks in the next release, as all we'll have to do is just store them in the irange. All in all, this series of patches incur a 1.9% penalty to VRP, with no measurable difference in overall compile time. The reason is three-fold: (a) There's double dispatch going on. First, the dispatch for the range-ops virtuals, and now the switch in bit_value_binop. (b) The maybe nonzero mask is stored as a tree and there is an endless back and forth with wide-ints. This will be a non-issue next release, when we convert irange to wide-ints. (c) New functionality has a cost. We were handling 2 cases (plus casts). Now we handle 20. I can play around with moving the bit_value_binop cases into inlined methods in the different range-op entries, and see if that improves anything, but I doubt (a) buys us that much. Certainly something that can be done in stage3 if it's measurable in any significant way. p.s It would be nice in the future to teach the op[12]_range methods about the masks. gcc/ChangeLog: * range-op.cc (range_operator::fold_range): Call update_known_bitmask. (operator_bitwise_and::fold_range): Avoid setting nonzero bits when range is undefined.
2022-11-11[range-ops] Use existing tree code for *DIV_EXPR entries.Aldy Hernandez1-15/+6
There is no need for a special tree code in the *DIV_EXPR entries, as the parent class has one. gcc/ChangeLog: * range-op.cc (class operator_div): Remove tree code. (operator_div::wi_op_overflows): Handle EXACT_DIV_EXPR as TRUNC_DIV_EXPR.
2022-11-11[range-ops] Add tree code to range_operator.Aldy Hernandez2-14/+28
This patch adds a tree code to range_operator in order to known which tree code to pass into bit-CCP. Up to now range-ops has been free of tree details, with the exception of the div entries which use a tree code to differentiate between them. This is still the goal going forward, but this is a stop-gap until we can merge the CCP and range-op bit handling in the next release. No change in performance. gcc/ChangeLog: * range-op.cc: (range_op_table::set): Set m_code. (integral_table::integral_table): Handle shared entries. (pointer_table::pointer_table): Same. * range-op.h (class range_operator): Add m_code.
2022-11-11tree-optimization/107618 - enhance copy propagation of constantsRichard Biener2-24/+35
The following enhances copy propagation of constants to also see through simple operations like conversions but also operations with otherwise constant operands. That's required to fulfill the promise /* Copy propagation also copy-propagates constants, this is necessary to forward object-size and builtin folding results properly. */ NEXT_PASS (pass_copy_prop); and avoid false diagnostics as shown in the testcase. We're using gimple_fold_stmt_to_constant_1 with not following SSA edges and accordingly adjust what stmts we simulate during SSA propagation. PR tree-optimization/107618 * tree-ssa-copy.cc (stmt_may_generate_copy): Simulate all assignments with a single SSA use. (copy_prop_visit_assignment): Use gimple_fold_stmt_to_constant_1 to perform simple constant folding. (copy_prop::visit_stmt): Visit all assignments. * gcc.dg/pr107618.c: New testcase.
2022-11-11Make last DCE remove empty loopsRichard Biener4-11/+22
The following makes the last DCE pass CD-DCE and in turn the last CD-DCE pass a DCE one. That ensues we remove empty loops that become empty between the two. I've also moved the tail-call pass after DCE since DCE can only improve things here. The two testcases were the only ones scanning cddce3 so I've changed them to scan the dce7 pass that's now in this place. The testcases scanning dce7 also work when that's in the earlier position. PR tree-optimization/84646 * tree-ssa-dce.cc (pass_dce::set_pass_param): Add param wheter to run update-address-taken. (pass_dce::execute): Honor it. * passes.def: Exchange last DCE and CD-DCE invocations. Swap pass_tail_calls and the last DCE. * g++.dg/tree-ssa/pr106922.C: Continue to scan earlier DCE dump. * gcc.dg/tree-ssa/20030808-1.c: Likewise.
2022-11-11jit: doc: Use shared Indices and tablesMartin Liska7-40/+36
Apart from that, do not use leading .rst names in toctree. ChangeLog: * doc/indices-and-tables.rst: Rename Indexes to Indices. gcc/jit/ChangeLog: * doc/cp/index.rst: Remove trailing .rst in toctree. * doc/cp/intro/index.rst: Likewise. * doc/cp/topics/index.rst: Likewise. * doc/index.rst: Likewise. * doc/intro/index.rst: Likewise. * doc/topics/index.rst: Likewise. * doc/indices-and-tables.rst: New file.
2022-11-11RISC-V: Add RVV registers register spillingJu-Zhe Zhong18-86/+2017
This patch support RVV scalable register spilling. prologue && epilogue handling pick up prototype from Monk Chiang <monk.chiang@sifive.com>. Co-authored-by: Monk Chiang <monk.chiang@sifive.com> gcc/ChangeLog: * config/riscv/riscv-v.cc (emit_pred_move): Adjust for scalable register spilling. (legitimize_move): Ditto. * config/riscv/riscv.cc (riscv_v_adjust_scalable_frame): New function. (riscv_first_stack_step): Adjust for scalable register spilling. (riscv_expand_prologue): Ditto. (riscv_expand_epilogue): Ditto. (riscv_dwarf_poly_indeterminate_value): New function. (TARGET_DWARF_POLY_INDETERMINATE_VALUE): New target hook support for register spilling. * config/riscv/riscv.h (RISCV_DWARF_VLENB): New macro. (RISCV_PROLOGUE_TEMP2_REGNUM): Ditto. (RISCV_PROLOGUE_TEMP2): Ditto. * config/riscv/vector-iterators.md: New iterators. * config/riscv/vector.md (*mov<mode>): Fix it for register spilling. (*mov<mode>_whole): New pattern. (*mov<mode>_fract): New pattern. (@pred_mov<mode>): Fix it for register spilling. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/macro.h: New test. * gcc.target/riscv/rvv/base/spill-1.c: New test. * gcc.target/riscv/rvv/base/spill-10.c: New test. * gcc.target/riscv/rvv/base/spill-11.c: New test. * gcc.target/riscv/rvv/base/spill-12.c: New test. * gcc.target/riscv/rvv/base/spill-2.c: New test. * gcc.target/riscv/rvv/base/spill-3.c: New test. * gcc.target/riscv/rvv/base/spill-4.c: New test. * gcc.target/riscv/rvv/base/spill-5.c: New test. * gcc.target/riscv/rvv/base/spill-6.c: New test. * gcc.target/riscv/rvv/base/spill-7.c: New test. * gcc.target/riscv/rvv/base/spill-8.c: New test. * gcc.target/riscv/rvv/base/spill-9.c: New test.
2022-11-11c-family: Support #pragma region/endregion [PR85487]Jonathan Wakely3-0/+23
These pragmas are used by some editors to mark regions of code for grouping and folding. GCC should silently ignore them, rather than giving -Wunknown-pragmas warnings. PR c/85487 gcc/ChangeLog: * doc/cpp/pragmas.rst (Pragmas): Document region pragmas. gcc/c-family/ChangeLog: * c-pragma.cc (handle_pragma_ignore): New function. (init_pragma): Register region and endregion pragmas. gcc/testsuite/ChangeLog: * c-c++-common/pragma-region.c: New test.
2022-11-11i386: Add ISA check for newly introduced prefetch builtins.Haochen Jiang4-4/+27
Hi all, As Hongtao said, the fail on pentiumpro is caused by missing ISA check since we are using emit_insn () through new builtins and it won't check if the TARGET matches. Previously, the builtin in middle-end will check that. On pentiumpro, we won't have anything that supports any prefetch so that it dropped into the pattern and then failed. I have added the restrictions just like what middle-end builtin_prefetch does. Also I added missing checks for PREFETCHI. Ok for trunk? BRs, Haochen gcc/ChangeLog: * config/i386/i386-builtin.def (BDESC): Add OPTION_MASK_ISA2_PREFETCHI for prefetchi builtin. * config/i386/i386-expand.cc (ix86_expand_builtin): Add ISA check before emit_insn. * config/i386/prfchiintrin.h: Add target for intrin. gcc/testsuite/ChangeLog: * gcc.target/i386/prefetchi-5.c: New test.
2022-11-11Daily bump.GCC Administrator8-1/+246
2022-11-10analyzer: new warning: -Wanalyzer-deref-before-check [PR99671]David Malcolm17-16/+860
This patch implements a new -Wanalyzer-deref-before-check within -fanalyzer. It complains about code paths in which a pointer is checked for NULL after it has already been dereferenced. For example, for the testcase in PR 77432 the diagnostic emits: deref-before-check-1.c: In function 'test_from_pr77432': deref-before-check-1.c:6:8: warning: check of 'a' for NULL after already dereferencing it [-Wanalyzer-deref-before-check] 6 | if (a) | ^ 'test_from_pr77432': events 1-2 | | 5 | int b = *a; | | ^ | | | | | (1) pointer 'a' is dereferenced here | 6 | if (a) | | ~ | | | | | (2) pointer 'a' is checked for NULL here but it was already dereferenced at (1) | and in PR 77425 we had an instance of this hidden behind a macro, which the diagnostic complains about as follows: deref-before-check-pr77425.c: In function 'get_odr_type': deref-before-check-pr77425.c:35:10: warning: check of 'odr_types_ptr' for NULL after already dereferencing it [-Wanalyzer-deref-before-check] 35 | if (odr_types_ptr) | ^ 'get_odr_type': events 1-3 | | 27 | if (cond) | | ^ | | | | | (1) following 'false' branch... |...... | 31 | else if (other_cond) | | ~~~~~~~~~~~ | | || | | |(2) ...to here | | (3) following 'true' branch... | 'get_odr_type': event 4 | | 11 | #define odr_types (*odr_types_ptr) | | ~^~~~~~~~~~~~~~~ | | | | | (4) ...to here deref-before-check-pr77425.c:33:7: note: in expansion of macro 'odr_types' | 33 | odr_types[val->id] = 0; | | ^~~~~~~~~ | 'get_odr_type': event 5 | | 11 | #define odr_types (*odr_types_ptr) | | ~^~~~~~~~~~~~~~~ | | | | | (5) pointer 'odr_types_ptr' is dereferenced here deref-before-check-pr77425.c:33:7: note: in expansion of macro 'odr_types' | 33 | odr_types[val->id] = 0; | | ^~~~~~~~~ | 'get_odr_type': event 6 | | 35 | if (odr_types_ptr) | | ^ | | | | | (6) pointer 'odr_types_ptr' is checked for NULL here but it was already dereferenced at (5) | gcc/analyzer/ChangeLog: PR analyzer/99671 * analyzer.opt (Wanalyzer-deref-before-check): New warning. * diagnostic-manager.cc (null_assignment_sm_context::set_next_state): Only add state change events for transition to "null" state. (null_assignment_sm_context::is_transition_to_null): New. * engine.cc (impl_region_model_context::on_pop_frame): New. * exploded-graph.h (impl_region_model_context::on_pop_frame): New decl. * program-state.cc (sm_state_map::clear_any_state): New. (sm_state_map::can_merge_with_p): New. (program_state::can_merge_with_p): Replace requirement that sm-states be equal in favor of an attempt to merge them. * program-state.h (sm_state_map::clear_any_state): New decl. (sm_state_map::can_merge_with_p): New decl. * region-model.cc (region_model::eval_condition): Make const. (region_model::pop_frame): Call ctxt->on_pop_frame. * region-model.h (region_model::eval_condition): Make const. (region_model_context::on_pop_frame): New vfunc. (noop_region_model_context::on_pop_frame): New. (region_model_context_decorator::on_pop_frame): New. * sm-malloc.cc (enum resource_state): Add RS_ASSUMED_NON_NULL. (allocation_state::dump_to_pp): Drop "final". (struct assumed_non_null_state): New subclass. (malloc_state_machine::m_assumed_non_null): New. (assumed_non_null_p): New. (class deref_before_check): New. (assumed_non_null_state::dump_to_pp): New. (malloc_state_machine::get_or_create_assumed_non_null_state_for_frame): New. (malloc_state_machine::maybe_assume_non_null): New. (malloc_state_machine::on_stmt): Transition from start state to "assumed-non-null" state for pointers passed to __attribute__((nonnull)) arguments, and for pointers explicitly dereferenced. Call maybe_complain_about_deref_before_check for pointers explicitly compared against NULL. (malloc_state_machine::maybe_complain_about_deref_before_check): New. (malloc_state_machine::on_deallocator_call): Also transition "assumed-non-null" states to "freed". (malloc_state_machine::on_pop_frame): New. (malloc_state_machine::maybe_get_merged_states_nonequal): New. * sm-malloc.dot: Update for changes to sm-malloc.cc. * sm.h (state_machine::on_pop_frame): New. (state_machine::maybe_get_merged_state): New. (state_machine::maybe_get_merged_states_nonequal): New. gcc/ChangeLog: * doc/gcc/gcc-command-options/options-that-control-static-analysis.rst: Add -Wanalyzer-deref-before-check. gcc/testsuite/ChangeLog: * gcc.dg/analyzer/deref-before-check-1.c: New test. * gcc.dg/analyzer/deref-before-check-2.c: New test. * gcc.dg/analyzer/deref-before-check-pr77425.c: New test. * gcc.dg/analyzer/malloc-1.c (test_51): New test. gcc/ChangeLog: PR analyzer/99671 * tristate.h (tristate::is_unknown): New. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-11-10c++: Extend -Wdangling-reference for std::minmaxMarek Polacek3-6/+94
This patch extends -Wdangling-reference to also warn for auto v = std::minmax(1, 2); which dangles because this overload of std::minmax returns a std::pair<const int&, const int&> where the two references are bound to the temporaries created for the arguments of std::minmax. This is a common footgun, also described at <https://en.cppreference.com/w/cpp/algorithm/minmax> in Notes. It works by extending do_warn_dangling_reference to also warn when the function returns a std::pair<const T&, const T&>. std_pair_ref_ref_p is a new helper to check that. gcc/cp/ChangeLog: * call.cc (std_pair_ref_ref_p): New. (do_warn_dangling_reference): Also warn when the function returns std::pair<const T&, const T&>. Recurse into TARGET_EXPR_INITIAL. (maybe_warn_dangling_reference): Don't return early if we're initializing a std_pair_ref_ref_p. gcc/ChangeLog: * doc/gcc/gcc-command-options/options-controlling-c++-dialect.rst: Extend the description of -Wdangling-reference. gcc/testsuite/ChangeLog: * g++.dg/warn/Wdangling-reference6.C: New test.
2022-11-10docs: move label directly before titleMartin Liska69-138/+138
Otherwise Sphinx can compare if Intersphinx is unavailable: gcc/fortran/doc/gfortran/intrinsic-procedures/atand.rst:50: WARNING: Failed to create a cross reference. A title or caption not found: 'atan' gcc/fortran/doc/gfortran/intrinsic-procedures/atan2.rst:55: WARNING: Failed to create a cross reference. A title or caption not found: 'atan' ... gcc/fortran/ChangeLog: * doc/gfortran/intrinsic-procedures/abs.rst: Move label directly before title. * doc/gfortran/intrinsic-procedures/acos.rst: Likewise. * doc/gfortran/intrinsic-procedures/acosd.rst: Likewise. * doc/gfortran/intrinsic-procedures/acosh.rst: Likewise. * doc/gfortran/intrinsic-procedures/aimag.rst: Likewise. * doc/gfortran/intrinsic-procedures/aint.rst: Likewise. * doc/gfortran/intrinsic-procedures/anint.rst: Likewise. * doc/gfortran/intrinsic-procedures/asin.rst: Likewise. * doc/gfortran/intrinsic-procedures/asind.rst: Likewise. * doc/gfortran/intrinsic-procedures/asinh.rst: Likewise. * doc/gfortran/intrinsic-procedures/atan.rst: Likewise. * doc/gfortran/intrinsic-procedures/atan2.rst: Likewise. * doc/gfortran/intrinsic-procedures/atan2d.rst: Likewise. * doc/gfortran/intrinsic-procedures/atand.rst: Likewise. * doc/gfortran/intrinsic-procedures/atanh.rst: Likewise. * doc/gfortran/intrinsic-procedures/besselj0.rst: Likewise. * doc/gfortran/intrinsic-procedures/besselj1.rst: Likewise. * doc/gfortran/intrinsic-procedures/besseljn.rst: Likewise. * doc/gfortran/intrinsic-procedures/bessely0.rst: Likewise. * doc/gfortran/intrinsic-procedures/bessely1.rst: Likewise. * doc/gfortran/intrinsic-procedures/besselyn.rst: Likewise. * doc/gfortran/intrinsic-procedures/btest.rst: Likewise. * doc/gfortran/intrinsic-procedures/char.rst: Likewise. * doc/gfortran/intrinsic-procedures/conjg.rst: Likewise. * doc/gfortran/intrinsic-procedures/cos.rst: Likewise. * doc/gfortran/intrinsic-procedures/cosd.rst: Likewise. * doc/gfortran/intrinsic-procedures/cosh.rst: Likewise. * doc/gfortran/intrinsic-procedures/cotan.rst: Likewise. * doc/gfortran/intrinsic-procedures/cotand.rst: Likewise. * doc/gfortran/intrinsic-procedures/dim.rst: Likewise. * doc/gfortran/intrinsic-procedures/dprod.rst: Likewise. * doc/gfortran/intrinsic-procedures/erf.rst: Likewise. * doc/gfortran/intrinsic-procedures/erfc.rst: Likewise. * doc/gfortran/intrinsic-procedures/exp.rst: Likewise. * doc/gfortran/intrinsic-procedures/gamma.rst: Likewise. * doc/gfortran/intrinsic-procedures/iand.rst: Likewise. * doc/gfortran/intrinsic-procedures/ibclr.rst: Likewise. * doc/gfortran/intrinsic-procedures/ibits.rst: Likewise. * doc/gfortran/intrinsic-procedures/ibset.rst: Likewise. * doc/gfortran/intrinsic-procedures/ichar.rst: Likewise. * doc/gfortran/intrinsic-procedures/ieor.rst: Likewise. * doc/gfortran/intrinsic-procedures/index.rst: Likewise. * doc/gfortran/intrinsic-procedures/int.rst: Likewise. * doc/gfortran/intrinsic-procedures/ior.rst: Likewise. * doc/gfortran/intrinsic-procedures/ishft.rst: Likewise. * doc/gfortran/intrinsic-procedures/ishftc.rst: Likewise. * doc/gfortran/intrinsic-procedures/len.rst: Likewise. * doc/gfortran/intrinsic-procedures/lge.rst: Likewise. * doc/gfortran/intrinsic-procedures/lgt.rst: Likewise. * doc/gfortran/intrinsic-procedures/lle.rst: Likewise. * doc/gfortran/intrinsic-procedures/llt.rst: Likewise. * doc/gfortran/intrinsic-procedures/log.rst: Likewise. * doc/gfortran/intrinsic-procedures/log10.rst: Likewise. * doc/gfortran/intrinsic-procedures/loggamma.rst: Likewise. * doc/gfortran/intrinsic-procedures/max.rst: Likewise. * doc/gfortran/intrinsic-procedures/min.rst: Likewise. * doc/gfortran/intrinsic-procedures/mod.rst: Likewise. * doc/gfortran/intrinsic-procedures/mvbits.rst: Likewise. * doc/gfortran/intrinsic-procedures/nint.rst: Likewise. * doc/gfortran/intrinsic-procedures/not.rst: Likewise. * doc/gfortran/intrinsic-procedures/real.rst: Likewise. * doc/gfortran/intrinsic-procedures/sign.rst: Likewise. * doc/gfortran/intrinsic-procedures/sin.rst: Likewise. * doc/gfortran/intrinsic-procedures/sind.rst: Likewise. * doc/gfortran/intrinsic-procedures/sinh.rst: Likewise. * doc/gfortran/intrinsic-procedures/sqrt.rst: Likewise. * doc/gfortran/intrinsic-procedures/tan.rst: Likewise. * doc/gfortran/intrinsic-procedures/tand.rst: Likewise. * doc/gfortran/intrinsic-procedures/tanh.rst: Likewise.
2022-11-10Remove SLOW_SHORT_ACCESS from target headersAndrew Pinski3-5/+1
SLOW_SHORT_ACCESS is defined in bfin and i386 target headers but the target macro is not used elsewhere. So let's remove it from those two headers and poison it. OK? Built x86_64-linux-gnu and bfin-elf. gcc/ChangeLog: * config/bfin/bfin.h (SLOW_SHORT_ACCESS): Delete. * config/i386/i386.h (SLOW_SHORT_ACCESS): Delete. * system.h: Poison SLOW_SHORT_ACCESS
2022-11-10Do not specify NAN sign in frange::set_nonnegative.Aldy Hernandez1-5/+7
After further reading of the IEEE 754 standard, it has become clear that there are no guarantees with regards to the sign of a NAN when it comes to any operation other than copy, copysign, abs, and negate. Currently, set_nonnegative() is only used in one place in ranger applicable to floating point values, when expanding unknown calls. Since we already specially handle copy, copysign, abs, and negate, all the calls to set_nonnegative() must be NAN-sign agnostic. The cleanest solution is to leave the sign unspecificied in frange::set_nonnegative(). Any special case, must be handled by the caller. gcc/ChangeLog: * value-range.cc (frange::set_nonnegative): Remove NAN sign handling. (range_tests_signed_zeros): Adjust test.
2022-11-10better PHI copy propagation for forwpropRichard Biener1-1/+6
We can handle _1 = PHI <_1, _2> as a copy. PR tree-optimization/84646 * tree-ssa-forwprop.cc (pass_forwprop::execute): Improve copy propagation across PHIs.