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

            Bug ID: 92231
           Summary: [9/10 Regression] ICE in
                    gimple_fold_stmt_to_constant_1
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: malakhov at mcst dot ru
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

Hi.

 The compilation of the following test with 'master' version of gcc has failed
since commit a0e9bfbb865dcaf307a4a06a29a7e1e7be24ee15 replacing the usage of
`DECL_BUILT_IN ()' macro  with `fndecl_built_in_p ()' function and removing
checks for FUNCTION_DECL if possible:

$ cat ./t.c
extern int bar (void);

int
foo (void)
{
  return (&bar + 4096) ();
}


$ i386-linux-gcc -S ./t.c -O1
. . .
./t.c: In function 'foo':
./t.c:7:1: internal compiler error: tree check: expected function_decl, have
mem_ref in fndecl_built_in_p, at tree.h:6133
    7 | }
      | ^
0x15b7c8e tree_check_failed(tree_node const*, char const*, int, char const*,
...)
        gcc/gcc/tree.c:9924
0x829ce8 tree_check(tree_node const*, char const*, int, char const*, tree_code)
        gcc/gcc/tree.h:3523
0x829e39 fndecl_built_in_p(tree_node const*)
        gcc/gcc/tree.h:6133
0xcda1e5 gimple_fold_stmt_to_constant_1(gimple*, tree_node* (*)(tree_node*),
tree_node* (*)(tree_node*))
        gcc/gimple-fold.c:6434
. . .


 The reason is that TREE_OPERAND (fn, 0) turns out to be MEM_REF rather than a
FUNCTION_DECL in the following context:

$ cat gcc/gimple-fold.c
. . .
tree
gimple_fold_stmt_to_constant_1 (...)
{
. . .
        fn = (*valueize) (gimple_call_fn (stmt));
        if (TREE_CODE (fn) == ADDR_EXPR
            && fndecl_built_in_p (TREE_OPERAND (fn, 0))
. . .

 Because the check for `TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL' was
removed by the aforementioned commit, the invocation of `fndecl_built_in_p ()'
results in an ICE (if gcc is configured with `--enable-checking=tree', of
course):

$ cat gcc/tree.h
. . .
/* For a builtin function, identify which part of the compiler defined it.  */
#define DECL_BUILT_IN_CLASS(NODE) \
   ((built_in_class) FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
. . .
inline bool
fndecl_built_in_p (const_tree node)
{
  return (DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
}
. . .


 P.S. The initial comment before fndecl_built_in_p () added by the same
commit said: "When a NULL argument is pass or tree code of the NODE is not
FUNCTION_DECL false is returned" which was not the case in fact. The next day
commit dfe2435feb0dc195652346a5e780380932763bdc removed this statement instead
of making fndecl_built_in_p () match it.

 P.P.S. The comment is still confusing as it refers to the no longer existent
DECL_BUILT_IN() macro instead of fndecl_built_in_p (): "For instance, user
declared prototypes of C library functions are not DECL_IS_BUILTIN but may be
DECL_BUILT_IN".

Reply via email to