Bug 84724 - [7 Regression] internal compiler error: in single_succ_edge, at basic-block.h:339 with a declaration of __builtin_trap
Summary: [7 Regression] internal compiler error: in single_succ_edge, at basic-block.h...
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0.1
: P2 normal
Target Milestone: 7.4
Assignee: Jakub Jelinek
URL:
Keywords: ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2018-03-05 18:50 UTC by Vegard Nossum
Modified: 2018-03-09 18:03 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.4.0
Known to fail: 7.3.0, 8.0
Last reconfirmed: 2018-03-06 00:00:00


Attachments
gcc8-pr84724.patch (831 bytes, patch)
2018-03-08 09:42 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Vegard Nossum 2018-03-05 18:50:47 UTC
Input:

int __builtin_trap();

int a() {
  int b;
  int c(&b);
  return b %= b ? c : 0;
}

Output:

$ xgcc -x c++ -O3 -fpermissive -fno-toplevel-reorder -S -
<stdin>:1:5: warning: new declaration 'int __builtin_trap()' ambiguates built-in declaration 'void __builtin_trap()' [-Wbuiltin-declaration-mismatch]
<stdin>: In function 'int a()':
<stdin>:5:9: warning: invalid conversion from 'int*' to 'int' [-fpermissive]
<stdin>:3:5: error: wrong outgoing edge flags at end of bb 4
during GIMPLE pass: isolate-paths
<stdin>:3:5: internal compiler error: in single_succ_edge, at basic-block.h:339
0x32700db single_succ_edge
        /home/vegard/git/gcc/gcc/basic-block.h:339
0x328b157 single_succ
        /home/vegard/git/gcc/gcc/basic-block.h:359
0x328b157 gimple_verify_flow_info
        /home/vegard/git/gcc/gcc/tree-cfg.c:5792
0x185db91 verify_flow_info()
        /home/vegard/git/gcc/gcc/cfghooks.c:263
0x33140ac checking_verify_flow_info
        /home/vegard/git/gcc/gcc/cfghooks.h:198
0x33140ac cleanup_tree_cfg_noloop
        /home/vegard/git/gcc/gcc/tree-cfgcleanup.c:920
0x33140ac cleanup_tree_cfg()
        /home/vegard/git/gcc/gcc/tree-cfgcleanup.c:971
0x2b6aaa4 execute_function_todo
        /home/vegard/git/gcc/gcc/passes.c:1947
0x2b73d16 do_per_function
        /home/vegard/git/gcc/gcc/passes.c:1659
0x2b73d16 execute_todo
        /home/vegard/git/gcc/gcc/passes.c:2048

$ xgcc --version
xgcc (GCC) 8.0.1 20180303 (experimental)

Built from git 0d86c284d085d29782d862600a79aa1ff0ee0c47 (r258221).

7.3.0 fails differently:

<source>:3:5: internal compiler error: in expand_gimple_basic_block, at cfgexpand.c:5457

6.3.0 apparently succeeds in compiling it.

Test case was minimised by C-Reduce.
Comment 1 Martin Sebor 2018-03-06 01:33:52 UTC
Confirmed with r244114 (gcc 7.0.0) as the first revision to ICE:

r244114 | jakub | 2017-01-05 16:14:19 -0500 (Thu, 05 Jan 2017) | 12 lines

	PR tree-optimization/71016

Prior to that GCC accepted the test case (with -fpermissive):

t.C:2:5: warning: new declaration ‘int __builtin_trap()’ ambiguates built-in declaration ‘void __builtin_trap()’ [-Wbuiltin-declaration-mismatch]
 int __builtin_trap();
     ^~~~~~~~~~~~~~
t.C: In function ‘int a()’:
t.C:6:9: warning: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
   int c(&b);
         ^~

A simpler test case is

  int __builtin_trap ();

  int a (int i)
  {
    const char *p = i < 0 ? 0 : "";

    return *p;
  }

The trouble seems to be that __builtin_trap is expected not to return but the extern C++ declaration in the program says otherwise and overrides the built-in.  I'd say re-declarations of built-ins that GCC itself depends on/makes assumptions about should be rejected with a hard error.
Comment 2 Richard Biener 2018-03-06 08:36:21 UTC
Yeah.  Or rather the FEs shouldn't clobber the builtin decls (_not_ merge into them) so that when the ME looks up decls for them they never pick up user decls.

Similar issues for builtin folding if the folded-to builtin is misdeclared.
Comment 3 Jakub Jelinek 2018-03-06 11:55:09 UTC
The C FE has quite a lot of code in this case, e.g.
match_builtin_function_types, which the C++ FE doesn't seem to have, and indeed the C FE leaves the __builtin_trap decl untouched after warning, while the C++ FE changes it.

The ICE in this case isn't caused by a mismatch between __builtin_trap () return type, but rather the lack of noreturn attribute on the new decl.
Though I'm sure that redefining similar way many other builtins that GCC emits on its own or expects a particular arguments or return types will cause many other ICEs.
Comment 4 Jakub Jelinek 2018-03-08 09:42:08 UTC
Created attachment 43595 [details]
gcc8-pr84724.patch

Untested fix.
Comment 5 Jakub Jelinek 2018-03-09 18:01:54 UTC
Author: jakub
Date: Fri Mar  9 18:01:22 2018
New Revision: 258391

URL: https://gcc.gnu.org/viewcvs?rev=258391&root=gcc&view=rev
Log:
	PR c++/84724
	* decl.c (duplicate_decls): Don't override __* prefixed builtins
	except for __[^b]*_chk, instead issue permerror and for -fpermissive
	also a note and return olddecl.

	* g++.dg/ext/pr84724.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/ext/pr84724-1.C
    trunk/gcc/testsuite/g++.dg/ext/pr84724-2.C
    trunk/gcc/testsuite/g++.dg/ext/pr84724-3.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 Jakub Jelinek 2018-03-09 18:03:07 UTC
Fixed on the trunk so far.