https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93549

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:c7c09af8ef0fe6671c7733d4d67bb73ecf10fc1b

commit r10-6523-gc7c09af8ef0fe6671c7733d4d67bb73ecf10fc1b
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Feb 8 15:11:28 2020 +0100

    c++: Handle CONSTRUCTORs without indexes in find_array_ctor_elt [PR93549]

    My change
    * typeck2.c (store_init_value): Don't call cp_fully_fold_init on
    initializers of automatic non-constexpr variables in constexpr
    functions.
    -  value = cp_fully_fold_init (value);
    +  /* Don't fold initializers of automatic variables in constexpr
functions,
    +     that might fold away something that needs to be diagnosed at
constexpr
    +     evaluation time.  */
    +  if (!current_function_decl
    +      || !DECL_DECLARED_CONSTEXPR_P (current_function_decl)
    +      || TREE_STATIC (decl))
    +    value = cp_fully_fold_init (value);
    from the constexpr new change apparently broke the following testcase.
    When handling COND_EXPR, we build_vector_from_val, however as the argument
we
    pass to it is not an INTEGER_CST/REAL_CST, but that wrapped in a
    NON_LVALUE_EXPR location wrapper, we end up with a CONSTRUCTOR and as it is
    middle-end that builds it, it doesn't bother with indexes.  The
    cp_fully_fold_init call used to fold it into VECTOR_CST in the past, but as
    we intentionally don't invoke it anymore as it might fold away something
    that needs to be diagnosed during constexpr evaluation, we end up
evaluating
    ARRAY_REF into the index-less CONSTRUCTOR.  The following patch fixes the
    ICE by teaching find_array_ctor_elt to handle CONSTRUCTORs without indexes
    (that itself could be still very efficient) and CONSTRUCTORs with some
    indexes present and others missing (the rules are that if the index on the
    first element is missing, then it is the array's lowest index (in C/C++ 0)
    and if other indexes are missing, they are the index of the previous
element
    + 1).

    Here is a new version, which assumes CONSTRUCTORs with all or none indexes
    and for CONSTRUCTORs without indexes performs the verification for
    flag_checking directly in find_array_ctor_elt.  For CONSTRUCTORs with
    indexes, it doesn't do the verification of all elts, because some
CONSTRUCTORs
    can be large, and it "verifies" only what it really needs - if all elts
    touched during the binary search have indexes, that is actually all we care
    about because we are sure we found the right elt.  It is just if we see a
    missing index we need assurance that all are missing to be able to directly
    access it.

    The assumption then simplifies the patch, for no index CONSTRUCTORs we can
    use direct access like for CONSTRUCTORs where last elt index is equal to
the
    elt position.  If we append right after the last elt, we just should clear
    the index so that we don't violate the assumption, and if we need a gap
    between the elts and the elt to be added, we need to add indexes.

    2020-02-08  Jakub Jelinek  <ja...@redhat.com>

        PR c++/93549
        * constexpr.c (find_array_ctor_elt): If last element has no index,
        for flag_checking verify all elts have no index.  If i is within the
        elts, return it directly, if it is right after the last elt, append
        if NULL index, otherwise force indexes on all elts.
        (cxx_eval_store_expression): Allow cep->index to be NULL.

        * g++.dg/ext/constexpr-pr93549.C: New test.

Reply via email to