POC: --- --- Run command: --- gcc -o poc poc.c --- Gcc version: --- gcc (GCC) 10.0.1 20200208 (experimental) Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. --- Stack dump: --- internal compiler error: in gimple_ca ll_arg, at gimple.h:3258 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return c - b ; | ^~ 0x696d12 gimple_call_arg ../../gcc/gimple.h:3258 0x69ae3a gimple_call_arg ../../gcc/tree.h:3799 0x69ae3a gimple_call_arg ../../gcc/gimple.h:3266 0x69ae3a gimple_fold_builtin_string_compare ../../gcc/gimple-fold.c:2382 0xafbc7d gimple_fold_builtin ../../gcc/gimple-fold.c:3966 0xafbc7d gimple_fold_call ../../gcc/gimple-fold.c:4481 0xafd2f3 fold_stmt_1 ../../gcc/gimple-fold.c:5152 0x169fc97 lower_stmt ../../gcc/gimple-low.c:388 0x169f7f2 lower_sequence ../../gcc/gimple-low.c:217 0x169f7f2 lower_gimple_bind ../../gcc/gimple-low.c:474 0x16a08f9 lower_function_body ../../gcc/gimple-low.c:110 0x16a08f9 execute ../../gcc/gimple-low.c:195 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. ---
POC: --- int f2 ( int x [ strcmp ( ) ] , int b ) { return c - b ; } int ( * f1 ( int a , enum E2 { E = -2 , F , G , H } b ) ) ( int c , int b ) { if ( a != b ) return f2 ; return 0 ; } int main ( ) { int ( * ( * p ) ( int a , int b ) ) ( int c , int d ) = f1 ; return ( * ( * p ) ( 0 , 2 ) ) ( 2 , 2 ) ; } ---
Confirmed. As said elsewhere the real issue lies in the C FE having this kind of prototypes marked with BUILT-IN.
smaller "invalid" testcase (why don't we diagnose it?): int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } it's interesting that if I declare strcmp to avoid an implicit declaration warning with the following it stops to ICE... int strcmp(); so somehow the FEs decl merging for an implicit declaration coming from the argument list is "broken" and doesn't avoid pre-empting the built-in declaration? While I have a patch to paper over the issue in the middle-end it would be nice to avoid the issue in the frontend. The middle-end patch would do the following, using the canonical built-in declaration for argument verification. Similar issues exist for target builtins since we also have a target specific folder. Not sure how the FE deals with user-provided "bogus" implementations of those (and whether they ever exist in non __builtin_ obfuscated variants). diff --git a/gcc/gimple.c b/gcc/gimple.c index 324e706d508..d64c2a77ea3 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2698,6 +2698,11 @@ gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl) { gcc_checking_assert (DECL_BUILT_IN_CLASS (fndecl) != NOT_BUILT_IN); + /* Use the decl we are actually expecting for comparison, not a possibly + bogus one from the user the C frontend is happily marking as builtin. */ + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + fndecl = builtin_decl_explicit (DECL_FUNCTION_CODE (fndecl)); + tree ret = gimple_call_lhs (stmt); if (ret && !useless_type_conversion_p (TREE_TYPE (ret), CCing C FE folks.
Both test cases are diagnosed with two instances of -Wimplicit-function-declaration, the smaller of the two with: $ gcc -S pr93631.c pr93631.c:1:18: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration] 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } | ^~~~~~ pr93631.c:1:18: warning: too few arguments to built-in function ‘strcmp’ expecting 2 [-Wbuiltin-declaration-mismatch] during GIMPLE pass: lower pr93631.c: In function ‘f2’: pr93631.c:1:5: internal compiler error: in gimple_call_arg, at gimple.h:3258 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } | ^~ The second warning has started to be issued with r266194 but it doesn't prevent the call from being treated as a built-in (the function only prevents that for errors, not for warning). There are a couple more checks later on for incompatible built-in calls that look like should catch this but don't. Changing the convert_arguments() function in the C front-end that issues the second warning to treat this case as an error (while still only issuing a warning) avoids the GIMPLE ICE but then causes another ICE later on: $ gcc -S -Wall -Wextra -Wpedantic t.c t.c:1:18: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration] 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } | ^~~~~~ t.c:1:18: warning: too few arguments to built-in function ‘strcmp’ expecting 2 [-Wbuiltin-declaration-mismatch] t.c: In function ‘f2’: t.c:1:14: warning: unused parameter ‘x’ [-Wunused-parameter] 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } | ~~~~^~~~~~~~~~~~~~~~ t.c:1:1: warning: control reaches end of non-void function [-Wreturn-type] 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } | ^~~ during RTL pass: expand t.c:1:5: internal compiler error: in adjust_one_expanded_partition_var, at cfgexpand.c:1463 1 | int f2 ( int x [ strcmp ( ) ] , int b ) { return x[0] - b ; } | ^~ 0xb06387 adjust_one_expanded_partition_var /src/gcc/trunk/gcc/cfgexpand.c:1463 0xb184b4 execute /src/gcc/trunk/gcc/cfgexpand.c:6457 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. For reference, bisection of the reported ICE points to r243832: commit d17680f342ef5407303d8c76f8faa0762f83c3f7 Author: Jakub Jelinek <jakub@redhat.com> Date: Wed Dec 21 01:07:49 2016 +0100 re PR c/77767 (Side-effect from VLA array parameters lost) PR c/77767 * c-decl.c (grokdeclarator): If *expr is non-NULL, append expression to *expr instead of overwriting it. * gcc.c-torture/execute/pr77767.c: New test. From-SVN: r243832
Just to add as a data point, gimple_builtin_call_types_compatible_p was originally added to catch indirect calls turned into direct calls of builtins but with wrongly typed args like from void (*fn)(int) = (void (*)(int))&memcpy; fn (1); it was _not_ designed to cope with a function decl that claims to be BUILT_IN_MEMCPY but whose TYPE_ARG_TYPES are not compatible with what we'd expect from a memcpy declaration. It is the frontends business to make sure the middle-end is not seeing a DECL_FUNCTION_CODE when the types do not match the canonical function declaration. The patch from comment#3 is a hack trying to work around FEs brokeness. But it's the frontends that need fixing. Finally. Please. Iff then as hackish as comment#3 but please within the FE like in merge_decls at the end do if (DECL_FUNCTION_CODE (...) && !decls_compatible_p (builtin_decl_explicit (...), ...))) DECL_BUILT_IN_CLASS (..) = BUILT_IN_NONE; and possibly clear the decl from builtin_decl_implicit iff we ever populated that with user decls.
GCC 8.4.0 has been released, adjusting target milestone.
GCC 8 branch is being closed.
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
GCC 9 branch is being closed
I can't reproduce with GCC 10+
GCC 10.4 is being released, retargeting bugs to GCC 10.5.
GCC 10 branch is being closed.
Per c#10.
Seems r12-8017-g71770a0ea920641c53912f725f5abd4413b38fd5 fixed this.