Bugzilla – Bug 202
[llvm-gcc] asserts when an extern inline function is redefined
Last modified: 2004-01-08 11:16:51
You need to log in before you can comment on or make changes to this bug.
The llvm-gcc program hits the following assertion when compiling the preprocessed C code: cc1: ../../src/gcc/llvm-expand.c:6251: llvm_expand_function_start: Assertion `(Fn->BasicBlocksFirst == Fn->BasicBlocksLast) && "Function already has a body!"' failed. In file included from ../sysdeps/generic/strtol_l.c:28: ../sysdeps/generic/strtol.c: In function `__strtol_l': ../sysdeps/generic/strtol.c:568: internal compiler error: Aborted Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://llvm.cs.uiuc.edu> for instructions.
Created an attachment (id=59) [details] Pre-processed C code that triggers the bug
If you can, please reduce the testcase :) -Chris
Created an attachment (id=60) [details] Reduced test case for the bug This is the reduced test case for the bug. I have verified that normal GCC accepts it as valid input.
(From update of attachment 59 [details]) This has been replaced with a newer attachment.
Fixed, testcase here: test/Regression/CFrontend/2004-01-08-ExternInlineRedefine.c Patch here: $ diff -u llvm-expand.c~ llvm-expand.c --- llvm-expand.c~ 2004-01-08 10:53:45.000000000 -0600 +++ llvm-expand.c 2004-01-08 11:08:13.000000000 -0600 @@ -6161,6 +6161,17 @@ /* No more processing for external functions. */ if (isExternal) return Fn; + /* If there is already a body for this function, it's a wierd error. The only + * case we allow is if the old function was linkonce. + */ + if (!llvm_ilist_empty(llvm_basicblock, Fn->BasicBlocks)) { + assert(Fn->Linkage == L_LinkOnce && + "Cannot redefine non-linkonce functions!"); + llvm_ilist_clear(llvm_basicblock, Fn->BasicBlocks); + llvm_ilist_clear(llvm_argument, Fn->Arguments); + Fn->Linkage = L_External; + } + if (!TREE_PUBLIC(subr) || lang_hooks.llvm_is_in_anon(subr)) Fn->Linkage = L_Internal; else if (DECL_COMDAT(subr) || Also requires this bugfix: $ diff -u llvm-ilist.h~ llvm-ilist.h --- llvm-ilist.h~ 2003-08-28 00:50:59.000000000 -0500 +++ llvm-ilist.h 2004-01-08 11:14:06.000000000 -0600 @@ -80,6 +80,7 @@ #define llvm_ilist_clear(TYPE, LIST) do { \ llvm_ilist_foreach(TYPE, LIST, TYPE##_delete); \ LIST##First = LIST##Last; \ + LIST##First->Prev = 0; \ } while (0) /* llvm_ilist_destruct - Destroy the entire list */ Note that this depends on the bugfix for Bug 182. -Chris