Comments (10)
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.
from cm3.
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.
from cm3.
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.
from cm3.
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.
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.
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.
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)
- I386_MINGW HOT 2
- Any attempts so resurrect the GCC backend? HOT 1
- Is the LLVM backend working yet?
- The wiki: does mingw-w64-x86_64-gcc is already enough?
- The wiki: add the later steps after the users have bootstrapped cm3
- Is it possible to introduce your own extensions? HOT 18
- Update Trestle GUI toolkit to meet modern real life requirements HOT 5
- An IDE dedicated to Modula-3
- We need a language server for Modula-3 HOT 1
- Update Windows API headers HOT 1
- A modern GUI stack for Modula-3
- Apple Silicon / ARM64_DARWIN support HOT 5
- Modern cmake unable to find COMCTL32 HOT 2
- -g0 option has no effect HOT 2
- BITSIZE of "SET OF SomeEnumeration" has been made flexible? (C backend, ARM64_DARWIN) HOT 2
- [Minor Issue] Bad Cube and Calculator in case cm3 -DM3_BACKEND_MODE=C -DBUILD_DIR=AMD64_LINUX HOT 9
- Packaging for NixOS HOT 11
- MxConfigC.c seems to set a wrong host name for Darwin PPC HOT 1
- it's just non-sense HOT 1
- macOS 14.2.1 on M2 ARM: cannot redefine readonly global symbol: M3_BACKEND_MODE HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cm3.