-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
clang generates endless loop #9986
Comments
Testcase boils down to something like the following: typedef __typeof(+L'a') wint_t; clang resolves the call to __btowc_alias into a call to btowc, so clang essentially sees through the trick to try and make the inline version call the out-of-line version. The function then ends up looking like it's tail-recursive, i.e. an infinite loop. |
I've found another test case with realpath. extern char *__realpath_alias (__const char *__restrict __name, char extern char * char *f(const char *path, char *buf) |
*** Bug llvm/llvm-bugzilla-archive#10179 has been marked as a duplicate of this bug. *** |
*** Bug llvm/llvm-bugzilla-archive#10207 has been marked as a duplicate of this bug. *** |
I get an infinite loop for btowc() with -O2 but not -O1 as described in bug #10207. This bug appears to have quite far reaching consequences. Not only does it make the configure scripts of such software as gnu tar, coreutils, diffutils, findutils, gettext, and grep hang. It might be the reason gnu sed, and awk hang during their tests as well (at least they hang when compiled with -O2 but not with -O1). |
*** Bug llvm/llvm-bugzilla-archive#10981 has been marked as a duplicate of this bug. *** |
*** Bug llvm/llvm-bugzilla-archive#10160 has been marked as a duplicate of this bug. *** |
Another testcase with getcwd, boils down to (after preprocessing, removing impossible code paths, etc) typedef typeof(sizeof(int)) size_t; This bug clang build a hanging vim on Linux unless optimizations are explicitly disabled. |
s/clang/causes clang to/ |
Dragonegg turns this into define i32 @btowc(i32 %__c) nounwind uwtable inlinehint { declare i32 @"\01btowc"(i32) define i32 @f(i32 %x) nounwind uwtable { which results in f being codegened as
|
Is this still a problem for clang? This is what I'm getting now: $ cat test.c $ clang test.c -o - -S -emit-llvm -O define i32 @main() nounwind uwtable ssp { declare i32 @btowc(i32) $ cat > test.c $ clang test.c -o - -S -emit-llvm -O define i32 @f(i32 %x) nounwind uwtable ssp { declare i32 @"\01btowc"(i32) $ cat > test.c extern char * char *f(const char *path, char *buf) { $ clang test.c -o - -S -emit-llvm -O define i8* @realpath(i8* noalias %__name, i8* noalias %__resolved) nounwind uwtable ssp { declare i8* @"\01realpath"(i8*, i8*) define i8* @f(i8* %path, i8* %buf) nounwind uwtable ssp { $ cat > test.c $ clang test.c -o - -S -O -emit-llvm define i8* @getcwd(i8* %__buf, i64 %__size) nounwind uwtable ssp { declare i8* @"\01getcwd"(i8*, i64) define i8* @test(i8* %buf, i32 %len) nounwind uwtable ssp { |
Still reproducable on Linux with [/kutu/stuff]> clang -v And AFAIK it only affects Linux. |
Interesting. When I took your IR example from the fist comment and ran it through 'opt' it generated IR which looked just fine. And the result was a 'jmp btowc' command, like Duncan's. Can you investigate further? I don't have easy access to a Linux box.. |
I can only reproduce the problem with my original testcase from bug 10160 , http://llvm.org/bugs/attachment.cgi?id=6754 |
I just remembered that I do have access to a Linux box. All of the tests I ran give the result as "ret i8* undef" (or some variation on that) with `-O'. Almost certainly not what you're looking for. |
Yes, please try with http://llvm.org/bugs/attachment.cgi?id=6754 and you need to do clang -O2 -D_FORTIFY_SOURCE=2 mmap.c since the definition of _FORTIFY_SOURCE=2 along with -O2 triggers the problem. bug 10160 had a nicer discussion of this bug but its marked as a duplicate :( |
Another reduced testcase for which clang, when passed -D_FORTIFY_SOURCE=2, turns into an infinite loop, on current 64-bit Debian testing, in both 64-bit and 32-bit mode: $ cat bug.c int fread_n_bytes(FILE * f, int n, uint8_t *s) if (s == NULL) return 0; int main(int argc, char * argv[]) { clang invocations that produce bad programs: Invocations that produce good programs: $ gdb bad1 |
Looking like the source fortification is necessary? Maybe it's interfering with an optimization that the code expects to happen? |
Potential fix here: http://comments.gmane.org/gmane.comp.compilers.clang.scm/40901 |
Fixed in r143049. |
Well, the testcase I posted in comment #18 still fails (infinite loops) for me after r143049, when -D_FORTIFY_SOURCE=2 is used: $ clang --version $ cat build.sh The base invocation, reduced from my original testcase.clang -D_FORTIFY_SOURCE=2 -Os -g3 -Wall -W -Wno-unused-parameter -Wshadow -Wwrite-strings -Wredundant-decls -Wdeclaration-after-statement -fstack-protector-all -Wstack-protector -o bad1 bug.c It ain't better in 32-bit mode.clang -m32 -D_FORTIFY_SOURCE=2 -Os -g3 -Wall -W -Wno-unused-parameter -Wshadow -Wwrite-strings -Wredundant-decls -Wdeclaration-after-statement -fstack-protector-all -Wstack-protector -o bad2 bug.c Disabling stack protector switches doesn't help.clang -D_FORTIFY_SOURCE=2 -Os -g3 -Wall -W -Wno-unused-parameter -Wshadow -Wwrite-strings -Wredundant-decls -Wdeclaration-after-statement -o bad3 bug.c Disabling FORTIFY_SOURCE helps.clang -Os -g3 -Wall -W -Wno-unused-parameter -Wshadow -Wwrite-strings -Wredundant-decls -Wdeclaration-after-statement -o good1 bug.c No problem if stack protector switches are activated but FORTIFY_SOURCE is not set.clang -Os -g3 -Wall -W -Wno-unused-parameter -Wshadow -Wwrite-strings -Wredundant-decls -Wdeclaration-after-statement -fstack-protector-all -Wstack-protector -o good2 bug.c $ cat bug.c int fread_n_bytes(FILE * f, int n, uint8_t *s) if (s == NULL) return 0; int main(int argc, char * argv[]) { |
Problem is still producable with the testcase from bug 10160 , |
Reduced testcase that still fails: extern int foo_alias (void) asm ("foo"); |
Dragonegg produces this for the testcase in comment 24: define i32 @foo() nounwind uwtable inlinehint alwaysinline { declare i32 @"\01foo"() define i32 @bar(...) nounwind uwtable { |
fixed in r143222. |
This doesn't apply cleanly to the 3.0 release branch: |
With clang r143304, the reduced testcase I posted in comments #18 and #22 now segfaults (which is the expected behaviour) even when compiled with -D_FORTIFY_SOURCE=2, and the original application from which I extracted it doesn't contain an infinite loop anymore, either. |
This fix doesn’t work in C++ mode, where the fortify wrappers use attribute ((always_inline)) but not attribute ((gnu_inline)): |
…tests Reland "[lldb][test] Re-enable bounds safety tests"
Extended Description
Clang generates llvm intermediate code with an endless loop, when -O is used.
Here is source .c code:
$ cat test.c
#include <wchar.h>
int main ()
{
return btowc ('\0');
}
And after compilation we have:
(gdb) disas main
Dump of assembler code for function main:
0x00000000004004f0 <+0>: jmp 0x4004f0
End of assembler dump.
Here is LLVM IR:
$ clang -S -emit-llvm test.c; cat test.s
; ModuleID = 'test.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"
define i32 @main() nounwind {
%1 = alloca i32, align 4
store i32 0, i32* %1
%2 = call i32 @btowc(i32 0) nounwind
ret i32 %2
}
declare i32 @btowc(i32) nounwind
$ clang -O -S -emit-llvm test.c; cat test.s
; ModuleID = 'test.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"
define i32 @main() nounwind readnone {
br label %tailrecurse.i
tailrecurse.i: ; preds = %tailrecurse.i, %0
br label %tailrecurse.i
}
I've attached wchar.h just in case.
The text was updated successfully, but these errors were encountered: