GithubHelp home page GithubHelp logo

Conversion problem with C backend about cm3 HOT 10 CLOSED

modula3 avatar modula3 commented on August 10, 2024
Conversion problem with C backend

from cm3.

Comments (10)

 avatar commented on August 10, 2024

I can't speak to the old C backend, but I'm not entirely sure we can lay this at the feet of the new C backend. Digging into the generated code more, the declared type for the SHA state variables is UINT32 exactly as expected. The INT32 is coming from the static initializer for the module. That is, the generated code is trying to pack those constants into the data segment so that it can initialize the SHA via memcpy.

The static data is constructed via calls to cg.init_int (from the frontend?) and those initialization calls are telling it to allocate an INT32. All the calls that I can find to cg.init_int get their type from CG.FindInitType and that function only looks at signed integer types.

https://github.com/modula3/cm3/blob/master/m3-sys/m3front/src/misc/CG.m3#L1161

So yeah, I'm new here, I don't know my way around the code generation, and maybe I've found my way into dead code that's not actually used...

But it looks like the front end is telling the back end to allocate static storage using only signed integer types. This is probably fine for backends that, literally, only allocate static storage, but the C backend has some typechecking so it goes boom.

Here's a simpler test to replicate the problem:

MODULE Main;
IMPORT Ctypes, IO;
VAR
        x: Ctypes.unsigned_int := 16_80000000;
BEGIN
        IO.PutInt (x)
END Main.

It's easy to see that the generated code is trying to use a UINT32

IO__PutInt(
  ( INTEGER )( ((INT64)(*((UINT32*)(INT64_(104)+((ADDRESS)(&Main_m_M_Main_L_10)))))) ),
  ( Wr__T )(((ADDRESS)(0)) ));

But the static initializer (where the compile error happens) is all about the INT32.

struct Main_m_M_Main_L_10_t{ADDRESS L_18[1];
// snip
INT32 L_26[1];
// snip
};

tl;dr I think the bug is actually in the frontend calling the codegen, the other backends just happen to be impervious to this particular problem

from cm3.

RodneyBates avatar RodneyBates commented on August 10, 2024

from cm3.

demoitem avatar demoitem commented on August 10, 2024

It's gcc or clang complaining about the generated C code.
( those files have a cpp suffix. Are they meant to be compiled with g++ ??)

So it's the C backend. It only seems to be global initialisers.

Changing the INT32 L_26[1]; declaration to UINT32 to agree with the source fixes the problem.

I had a brief look at M3C.m3 but it's daunting. Best left in the hands of an expert.

from cm3.

RodneyBates avatar RodneyBates commented on August 10, 2024

from cm3.

 avatar commented on August 10, 2024

I still don't understand what's going on here. Variable x is a scalar. Unless I am very mixed up, the front end does not put scalar constants in the global static constant area, only array, record, and set constructors. Scalars that are components of constructors do, of course go there, but that is not the case here. When it is, these are inserted as just bit patterns in the constructed value. But here, there should be no M3CG_Ops.init_int and no static initial value. The initial value should come from a load_integer, in executable code where it is stored into x.

This could be an artifact of a bad example. I was only interested in recreating the overflow / compile error. In the example I wrote above, x is getting baked into the data segment because it is a global. Rewriting the code to make x a procedure local makes the call to M3CG_Ops.init_int go away.

from cm3.

RodneyBates avatar RodneyBates commented on August 10, 2024

from cm3.

 avatar commented on August 10, 2024

I have merged my fix for this, but I'll leave the issue open in the hopes that somebody else will try to verify it. (Works for me!) Remember, the C backend is already broken wrt to the SHA256 changes of a few days ago, so to build it is necessary to roll-back pre-Sept 8 and cherry-pick this commit. After patching the compiler, SHA256 will build on the C backend.

Since HEAD is now broken wrt the most recent releases, I figure that means there will need to be a new release, but I'll make a separate issue for that.

from cm3.

jaykrell avatar jaykrell commented on August 10, 2024

The frontend is sloppy on the types it passes to the backend, indeed.
Thank you for looking into this!
I have seen similar warnings for a while, but didn't realize anything had gotten into an error state.
Yes the C vs. C++'ness is murky, sorry about that.
For the longest time, it has been both valid C and C++.
For a while, maybe a long time ago, it compiled as C.
For a very time I have been throwing various compiler-specific switches to compile as C++.
Things like cl /TP and gcc -xc++ or invoking g++.
I finally only very recently changed the extensions.
This can get us away from maintaining the /TP and -xc++.
This should make it easier to generate Makefile.am. I couldn't find a way to tell Automake the language of a file, only to ask Automake to find a C++ compiler. (Yes, I know, generate a thing, that generates another thing, that probably generates another thing; I prototyped and it is looking good.)

The code is still valid C.

But I want to use C++98 exception handling.
That should provide major performance gains on most platforms, over any of the other compilation strategies (it is a different "level", really, just that it is most easily achieved, perhaps, via C++ backend).
maybe C++11 [thread].

This could enable, if people really want, going back to having .c compile as C, and maybe sprinkling cxx_source around the m3core m3makefiles. I am on the fence there. I'd kinda just as soon compile .c as C++ still.

Anyway, again thank you for taking a look.
Most people seem to want to completely ignore the C backend (it is all we have though for ARM64, Riscv, NT/AMD64, etc...)

from cm3.

 avatar commented on August 10, 2024

But I want to use C++98 exception handling.

I don't have a strong opinion on the C/C++ issue, but I do know GNU Modula-2 went the same way, using the C++ exception handling instead of implementing their own. I can certainly see the logic to it.

In general I like having a C/C++ backend for bootstrapping and portability. It's a little worrying to me that the primary production backend is a 10-year old fork of GCC, but I guess that's a topic for another day. :)

from cm3.

jaykrell avatar jaykrell commented on August 10, 2024

Exactly! Including the license.
The LLVM backend is pretty good I hear.
I ran the C/C++ backend on Alpha/OSF this year even. :)

Fyi, the C++ code is sort of platform-independent.
That is, there are approximately 6 actual targets:
Unix 64bit little endian (almost everything)
Unix 64bit big endian (Solaris/Linux/SPARC64)
Unix 32bit little endian (x86, arm32)
Unix 32bit big endian (Solaris/Linux/SPARC32)
Windows 64bit little endian
Windows 32bit little endian
Windows big endian is hypothetical -- CE and 360.

I have unfinished work where the 32bit/64bit difference is then erased.
Where we pass and store pointers as UINT64, and cast to dereference.
The Windows/Linux thing is harder to deal with.
I have a vague theory, that conditionals in m3makefile's can be "remembered", considered as true, and then passed to the C backend to put #if around the files. Something like that. Or pass through to a hypothetical Automake generator.

But if you ignore 32bit and big endian (for redist), the havint just Unix and Windows isn't bad.
Later..

from cm3.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.