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 1486 - ExitValue of intepreter left in broken state at interpreter construction
Summary: ExitValue of intepreter left in broken state at interpreter construction
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Interpreter (show other bugs)
Version: trunk
Hardware: Macintosh MacOS X
: P normal
Assignee: Reid Spencer
URL:
Keywords: miscompilation, regression
Depends on:
Blocks:
 
Reported: 2007-06-01 14:00 PDT by Chuck Rose
Modified: 2010-02-22 12:50 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 Chuck Rose 2007-06-01 14:00:37 PDT
Interpreter::Interpreter(Module *M) : ExecutionEngine(M), TD(M) {
	  memset(&ExitValue, 0, sizeof(ExitValue));   <-----
	...
	}

The problem with this line is that it leaves the APInt value within 
ExitValue in a broken state (bit width cannot be zero).  If you run a 
function with no return value through the interpreter it will crash as 
the ExitValue is passed out of the interpreter's run function as it 
gets to the APInt copy constructor.

This problem is easily reproducable with by running a void function through 
the interpeter.  I've seen this repro both on Mac OSX and Vista.
Comment 1 Reid Spencer 2007-06-01 14:19:51 PDT
Hi Chuck,

Thanks for the report. The code you highlighed does look to be in error and I
have a patch for it, but I can't reproduce the original problem. I've got a test
case like this:

; PR1486
; RUN: llvm-as %s -f -o %t.bc
; RUN: lli -force-interpreter=true %t.bc
; Test that void function results don't cause an assert

define void @doNothing() {
  ret void
}

define i32 @main() {
  call void @doNothing()
  ret i32 0
}

I'm trying this on Linux, but I doubt platform makes a difference for this
problem. Is this the kind of test case you were using? 
Comment 2 Reid Spencer 2007-06-01 15:08:20 PDT
Comments from Chuck, via email:

Here'e the function that's running, though I have seen it with something
like your doNothing function alone.  The thing we don't have is the main
function.

  define void @evaluateDependents(float* %colorValue) {
  FnTemporariesBlock:
        br label %FunctionBlock

  FunctionBlock:                ; preds = %FnTemporariesBlock
        call float @fabsf( float -5.000000e-001 )               ;
<float>:0 [#us
es=1]
        store float %0, float* %colorValue
        br label %DestructorBlock

  DestructorBlock:              ; preds = %FunctionBlock
        ret void
  }

  declare float @fabsf(float)

Here's how we call in:

   llvm::Function* pExecutableFunction =
pEE->FindFunctionNamed("evaluateDependents");

   llvm::GenericValue GV = pEE->runFunction( pExecutableFunction,
parameters );
Comment 3 Reid Spencer 2007-06-01 15:10:22 PDT
Chuck,

I can't easily reproduce that (limited time here), but perhaps you could try
this patch:

Index: Interpreter.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp,v
retrieving revision 1.39
diff -t -d -u -p -5 -r1.39 Interpreter.cpp
--- Interpreter.cpp     6 Mar 2007 03:05:57 -0000       1.39
+++ Interpreter.cpp     1 Jun 2007 20:08:49 -0000
@@ -52,11 +52,11 @@ ExecutionEngine *Interpreter::create(Mod
 //===----------------------------------------------------------------------===//
 // Interpreter ctor - Initialize stuff
 //
 Interpreter::Interpreter(Module *M) : ExecutionEngine(M), TD(M) {

-  memset(&ExitValue, 0, sizeof(ExitValue));
+  memset(&ExitValue.Untyped, 0, sizeof(ExitValue.Untyped));
   setTargetData(&TD);
   // Initialize the "backend"
   initializeExecutionEngine();
   initializeExternalFunctions();
   emitGlobals();

Instead of memset'ing the whole thing, it just does the "union" part. That
should avoid setting 0 bit width in the APInt portion and relieve the problem.

If this works for you, please let me know and I'll commit it and close this PR.

Thanks,

Reid.
Comment 4 Chuck Rose 2007-06-01 15:25:29 PDT
If your fix is applied to the intreter constructor and also to the void return 
path in popStackAndReturnToCaller function in execution.cpp, it works on my 
system.

Thank you for the quick turnaround.