LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1525 - llvm CVS: llvm2cpp generates incorrect code when string are used
Summary: llvm CVS: llvm2cpp generates incorrect code when string are used
Status: RESOLVED FIXED
Alias: None
Product: tools
Classification: Unclassified
Component: llvm2cpp (show other bugs)
Version: 1.5
Hardware: All All
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-06-21 03:34 PDT by Stephane Letz
Modified: 2010-03-06 14:00 PST (History)
1 user (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stephane Letz 2007-06-21 03:34:03 PDT
llvm2cpp generates incorrect code, that does not run correctly when compiled and run, when string are 
used:

Starting from the following code:

#include <stdio.h>

int main()
{
	printf("foo");
	return 0;
}

the generated code is: 

// Generated by llvm2cpp - DO NOT MODIFY!

#include <llvm/Module.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Constants.h>
#include <llvm/GlobalVariable.h>
#include <llvm/Function.h>
#include <llvm/CallingConv.h>
#include <llvm/BasicBlock.h>
#include <llvm/Instructions.h>
#include <llvm/InlineAsm.h>
#include <llvm/ParameterAttributes.h>
#include <llvm/Support/MathExtras.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <algorithm>
#include <iostream>

using namespace llvm;

Module* makeLLVMModule();

int main(int argc, char**argv) {
  Module* Mod = makeLLVMModule();
  verifyModule(*Mod, PrintMessageAction);
  std::cerr.flush();
  std::cout.flush();
  PassManager PM;
  PM.add(new PrintModulePass(&llvm::cout));
  PM.run(*Mod);
  return 0;
}


Module* makeLLVMModule() {
  // Module Construction
  Module* mod = new Module("function.bc");
  mod->setDataLayout("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-
f64:32:64-v64:64:64-v128:128:128-a0:0:64");
  mod->setTargetTriple("i686-apple-darwin8.9.1");
  
  // Type Definitions
  ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 4);
  
  PointerType* PointerTy_1 = PointerType::get(ArrayTy_0);
  
  std::vector<const Type*>FuncTy_2_args;
  ParamAttrsList *FuncTy_2_PAL = 0;
  FunctionType* FuncTy_2 = FunctionType::get(
    /*Result=*/IntegerType::get(32),
    /*Params=*/FuncTy_2_args,
    /*isVarArg=*/false,
    /*ParamAttrs=*/FuncTy_2_PAL);
  
  std::vector<const Type*>FuncTy_4_args;
  PointerType* PointerTy_5 = PointerType::get(IntegerType::get(8));
  
  FuncTy_4_args.push_back(PointerTy_5);
  ParamAttrsList *FuncTy_4_PAL = 0;
  FunctionType* FuncTy_4 = FunctionType::get(
    /*Result=*/IntegerType::get(32),
    /*Params=*/FuncTy_4_args,
    /*isVarArg=*/true,
    /*ParamAttrs=*/FuncTy_4_PAL);
  
  PointerType* PointerTy_3 = PointerType::get(FuncTy_4);
  
  
  // Function Declarations
  
  Function* func_main = new Function(
    /*Type=*/FuncTy_2,
    /*Linkage=*/GlobalValue::ExternalLinkage,
    /*Name=*/"main", mod); 
  func_main->setCallingConv(CallingConv::C);
  
  Function* func_printf = new Function(
    /*Type=*/FuncTy_4,
    /*Linkage=*/GlobalValue::ExternalLinkage,
    /*Name=*/"printf", mod); // (external, no body)
  func_printf->setCallingConv(CallingConv::C);
  
  // Global Variable Declarations

  
  GlobalVariable* gvar_array__str = new GlobalVariable(
  /*Type=*/ArrayTy_0,
  /*isConstant=*/true,
  /*Linkage=*/GlobalValue::InternalLinkage,
  /*Initializer=*/0, // has initializer, specified below
  /*Name=*/".str",
  mod);
  
  // Constant Definitions
  Constant* const_array_6 = ConstantArray::get("foo\x00", false);
  std::vector<Constant*> const_ptr_7_indices;
  Constant* const_int32_8 = Constant::getNullValue(IntegerType::get(32));
  const_ptr_7_indices.push_back(const_int32_8);
  const_ptr_7_indices.push_back(const_int32_8);
  Constant* const_ptr_7 = ConstantExpr::getGetElementPtr(gvar_array__str, &const_ptr_7_indices[0], 2 );
  
  // Global Variable Definitions
  gvar_array__str->setInitializer(const_array_6);
  
  // Function Definitions
  
  // Function: main (func_main)
  {
    
    BasicBlock* label_entry = new BasicBlock("entry",func_main,0);
    
    // Block entry (label_entry)
    CallInst* int32_tmp2 = new CallInst(func_printf, const_ptr_7, "tmp2", label_entry);
    int32_tmp2->setCallingConv(CallingConv::C);
    int32_tmp2->setTailCall(true);
    new ReturnInst(const_int32_8, label_entry);
    
  }
  
  return mod;
}

then when compiled and run give the error:

Global variable initializer type does not match global variable type!
[4 x i8]* @.str
Broken module found, verification continues.
; ModuleID = 'function.bc'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-
v64:64:64-v128:128:128-a0:0:64"
target triple = "i686-apple-darwin8.9.1"
@.str = internal constant [4 x i8] c"foo"               ; <[4 x i8]*> [#uses=1]

define i32 @main() {
entry:
        %tmp2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0) )          ; 
<i32> [#uses=0]
        ret i32 0
}

declare i32 @printf(i8*, ...)

If I *manually* edit the gnerated code to be : Constant* const_array_6 = ConstantArray::get("foo ", 
false); then it works.

So the issue seems a string termination problem.
Comment 1 Reid Spencer 2007-06-25 11:46:47 PDT
Fixed with this patch:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070625/050728.html