Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,828
    • Issues 4,828
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 446
    • Merge requests 446
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #11395

Closed
Open
Created Jan 09, 2016 by mkarcher@trac-mkarcher

The via-C code generation backend is incompatible with gcc 5.3.1 on m68k (ELF)

ghc is generating C code like in the following simplified example:

demo1.c:

#include <assert.h>

extern void* int_returning_function();

typedef int (*int_f_ptr)();

int main(void)
{
	int result;
	{
		int_f_ptr correctly_typed_pointer;
		correctly_typed_pointer = (int_f_ptr)int_returning_function;
		result = correctly_typed_pointer();
	}
	assert(result == 42);
	return 0;
}

demo2.c:

int int_returning_function()
{
	return 42;
}

This code fails to work on m68k with gcc-5.3.1 if optimization is turned on. The real-life example from ghc is rts/Schedule.c:raiseExceptionHelper as int_returning_function and rts/Exception.cmm:stg_raisezh as main. The reason it fails is that on m68k, a function returning a pointer returns the result in %a0, while a function returning an integer returns it in %d0. If optimization is enabled, gcc elides the function pointer and calls the function as-if it were called directly. Without optimization, gcc expects the result to be in %d0, where it actually is.

In my oppinion, gcc is allowed to do that, because according to N843 (C99 draft), 6.2.7 #2 (closed) "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined." is violated in this example. Compatibility of return types is defined in 6.7.5.3 #11 (closed) "For two function types to be compatible, both shall specify compatible return types. Moreover, [...]" which is clearly violated.

If you just look at demo1.c and assume that 6.2.7 #2 (closed) is *not* violated, int_returning_function would in fact be a function returning a pointer. In that case, compiling demo1.c would violate 6.3.2.3 #8 (closed) "If a converted pointer is used to call a function whose type is not compatible with the pointed-to type, the behavior is undefined." and/or 6.5.2.2 "If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined."

You might want to discuss this issue with the gcc developers, but I don't see a standard claus justifying the approach of declaring all functions returning StgFunPtr and casting them to the right type.

If you cross-compile the source tarball Debian claims to be 7.10.3-rc1 to m68k using gcc 5.3.1, ghc crashes on startup because stg_raisezh gets a wrong value as frame_type and tries to cancel an STM transaction that does not exist at all.

Trac metadata
Trac field Value
Version 7.10.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking