Hey again) Now I have next code: ; ModuleID = 'sample.lz' @.str1 = internal global [8 x i8] c" world!\00" ; <[8 x i8]*> [#uses=1] @.str2 = internal global [8 x i8] c"hello, \00" ; <[8 x i8]*> [#uses=1] @.str7 = internal global [21 x i8] c"welcome to out hall!\00" ; <[21 x i8]*> [#uses=1] declare i32 @puts(i8*) declare i8* @strcat(i8*, i8*) declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) define i32 @main() { mainBlock: %.str3 = getelementptr [8 x i8]* @.str2, i64 0, i64 0 ; <i8*> [#uses=1] %.str4 = getelementptr [8 x i8]* @.str1, i64 0, i64 0 ; <i8*> [#uses=1] %tmp5 = call i8* @strcat( i8* %.str3, i8* %.str4 ) ; <i8*> [#uses=1] %tmp6 = call i32 @puts( i8* %tmp5 ) ; <i32> [#uses=0] %.str8 = getelementptr [21 x i8]* @.str7, i64 0, i64 0 ; <i8*> [#uses=1] %tmp9 = call i32 @puts( i8* %.str8 ) ; <i32> [#uses=0] ret i32 0 } After compilation I see next(without %): % hello, world! world! what is the trouble now? but next code runs ok: ; ModuleID = 'sample.lz' @.str1 = internal global [7 x i8] c"father\00" ; <[7 x i8]*> [#uses=1] @.str2 = internal global [8 x i8] c"mother \00" ; <[8 x i8]*> [#uses=1] declare i32 @puts(i8*) declare i8* @strcat(i8*, i8*) declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) define i32 @main() { mainBlock: %.str3 = getelementptr [8 x i8]* @.str2, i64 0, i64 0 ; <i8*> [#uses=1] %.str4 = getelementptr [7 x i8]* @.str1, i64 0, i64 0 ; <i8*> [#uses=1] %tmp5 = call i8* @strcat( i8* %.str3, i8* %.str4 ) ; <i8*> [#uses=1] %tmp6 = call i32 @puts( i8* %tmp5 ) ; <i32> [#uses=0] ret i32 0 } After running: % mother father It's ok, but in prev. example (when I call strcat more than one times) program works incorrectly help me please... Best regards, Zalunin Pavel -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080106/99ddb9f4/attachment.html>
It's invalid for the same reason that char *foobar = strcat("foo", "bar"); is invalid in C. Please make sure you understand what you're asking LLVM to do before going any further down this path. A good approach is to write out the correct code in C and then use llvm-gcc (or the demo page at http://llvm.org/demo ) to see what it looks like in LLVM assembly. Nick Zalunin Pavel wrote:> Hey again) > > Now I have next code: > > ; ModuleID = 'sample.lz' > @.str1 = internal global [8 x i8] c" world!\00" ; <[8 x i8]*> > [#uses=1] > @.str2 = internal global [8 x i8] c"hello, \00" ; <[8 x i8]*> > [#uses=1] > @.str7 = internal global [21 x i8] c"welcome to out hall!\00" > ; <[21 x i8]*> [#uses=1] > > declare i32 @puts(i8*) > > declare i8* @strcat(i8*, i8*) > > declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) > > define i32 @main() { > mainBlock: > %.str3 = getelementptr [8 x i8]* @.str2, i64 0, i64 0 > ; <i8*> [#uses=1] > %.str4 = getelementptr [8 x i8]* @.str1, i64 0, i64 0 > ; <i8*> [#uses=1] > %tmp5 = call i8* @strcat( i8* %.str3, i8* %.str4 ) > ; <i8*> [#uses=1] > %tmp6 = call i32 @puts( i8* %tmp5 ) ; <i32> [#uses=0] > %.str8 = getelementptr [21 x i8]* @.str7, i64 0, i64 0 > ; <i8*> [#uses=1] > %tmp9 = call i32 @puts( i8* %.str8 ) ; <i32> [#uses=0] > ret i32 0 > } > > After compilation I see next(without %): > > % > hello, world! > world! > > what is the trouble now? > but next code runs ok: > ; ModuleID = 'sample.lz' > @.str1 = internal global [7 x i8] c"father\00" ; <[7 x i8]*> > [#uses=1] > @.str2 = internal global [8 x i8] c"mother \00" ; <[8 x i8]*> > [#uses=1] > > declare i32 @puts(i8*) > > declare i8* @strcat(i8*, i8*) > > declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) > > define i32 @main() { > mainBlock: > %.str3 = getelementptr [8 x i8]* @.str2, i64 0, i64 0 > ; <i8*> [#uses=1] > %.str4 = getelementptr [7 x i8]* @.str1, i64 0, i64 0 > ; <i8*> [#uses=1] > %tmp5 = call i8* @strcat( i8* %.str3, i8* %.str4 ) > ; <i8*> [#uses=1] > %tmp6 = call i32 @puts( i8* %tmp5 ) ; <i32> [#uses=0] > ret i32 0 > } > > After running: > % > mother father > > It's ok, but in prev. example (when I call strcat more than one times) > program works incorrectly > help me please... > > Best regards, > Zalunin Pavel > > > ------------------------------------------------------------------------ > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
On Jan 6, 2008, at 12:29 PM, Zalunin Pavel wrote:> Hey again) > > Now I have next code: > > ; ModuleID = 'sample.lz' > @.str1 = internal global [8 x i8] c" world!\00" ; <[8 x > i8]*> [#uses=1] > @.str2 = internal global [8 x i8] c"hello, \00" ; <[8 x > i8]*> [#uses=1] > @.str7 = internal global [21 x i8] c"welcome to out hall! > \00" ; <[21 x i8]*> [#uses=1] > > declare i32 @puts(i8*) > > declare i8* @strcat(i8*, i8*) > > declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) > > define i32 @main() { > mainBlock: > %.str3 = getelementptr [8 x i8]* @.str2, i64 0, i64 > 0 ; <i8*> [#uses=1] > %.str4 = getelementptr [8 x i8]* @.str1, i64 0, i64 > 0 ; <i8*> [#uses=1] > %tmp5 = call i8* @strcat( i8* %.str3, i8* > %.str4 ) ; <i8*> [#uses=1] > %tmp6 = call i32 @puts( i8* %tmp5 ) ; <i32> > [#uses=0] > %.str8 = getelementptr [21 x i8]* @.str7, i64 0, i64 > 0 ; <i8*> [#uses=1] > %tmp9 = call i32 @puts( i8* %.str8 ) ; <i32> > [#uses=0] > ret i32 0 > }You should look more closely at the man page for strcat(). You have to have sufficient space in the buffer for the first argument. Otherwise you're trashing memory. Brendan Younger
hm.... I think, that is valid in c but next code too doesn't works right: ; ModuleID = 'sample.lz' @.str1 = internal global [6 x i8] c"world\00" ; <[6 x i8]*> [#uses=1] @.str2 = internal global [7 x i8] c"hello \00" ; <[7 x i8]*> [#uses=1] @.str7 = internal global [7 x i8] c"father\00" ; <[7 x i8]*> [#uses=1] @.str8 = internal global [8 x i8] c"mother \00" ; <[8 x i8]*> [#uses=1] declare i32 @puts(i8*) declare i8* @strcat(i8*, i8*) declare i32 @strlen(i8*) declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) define i32 @main() { mainBlock: %str3 = getelementptr [7 x i8]* @.str2, i64 0, i64 0 ; <i8*> [#uses=2] %str4 = getelementptr [6 x i8]* @.str1, i64 0, i64 0 ; <i8*> [#uses=1] call i8* @strcat( i8* %str3, i8* %str4 ) ; <i8*>:0 [#uses=0] %tmp6 = call i32 @puts( i8* %str3 ) ; <i32> [#uses=0] %str9 = getelementptr [8 x i8]* @.str8, i64 0, i64 0 ; <i8*> [#uses=2] %str10 = getelementptr [7 x i8]* @.str7, i64 0, i64 0 ; <i8*> [#uses=1] call i8* @strcat( i8* %str9, i8* %str10 ) ; <i8*>:1 [#uses=0] %tmp12 = call i32 @puts( i8* %str9 ) ; <i32> [#uses=0] ret i32 0 } writes: % hello world mother orld I tried decompile code: main(int argc, char **argv) { char str1[] = "mother "; strcat(str1, "father"); return 0; } decompiler gives to me code, in this code string " mother\0" presents as: %str1 = alloca [8 x i8], align 16 ; <[8 x i8]*> [#uses=9] %tmp1 = getelementptr [8 x i8]* %str1, i32 0, i32 0 ; <i8*> [#uses=2] store i8 109, i8* %tmp1, align 16 %tmp4 = getelementptr [8 x i8]* %str1, i32 0, i32 1 ; <i8*> [#uses=1] store i8 111, i8* %tmp4, align 1 %tmp7 = getelementptr [8 x i8]* %str1, i32 0, i32 2 ; <i8*> [#uses=1] store i8 116, i8* %tmp7, align 1 %tmp10 = getelementptr [8 x i8]* %str1, i32 0, i32 3 ; <i8*> [#uses=1] store i8 104, i8* %tmp10, align 1 %tmp13 = getelementptr [8 x i8]* %str1, i32 0, i32 4 ; <i8*> [#uses=1] store i8 101, i8* %tmp13, align 1 %tmp16 = getelementptr [8 x i8]* %str1, i32 0, i32 5 ; <i8*> [#uses=1] store i8 114, i8* %tmp16, align 1 %tmp19 = getelementptr [8 x i8]* %str1, i32 0, i32 6 ; <i8*> [#uses=1] store i8 32, i8* %tmp19, align 1 %tmp22 = getelementptr [8 x i8]* %str1, i32 0, i32 7 ; <i8*> [#uses=1] store i8 0, i8* %tmp22, align 1 it's looks funny, can you say another less complex way to do this operation? Thanks Best regards, Zalunin Pavel -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080106/7f9b54f1/attachment.html>