clang - error: non-ASM statement in naked function is not supported - clang

$ clang --version
clang version 5.0.0 (tags/RELEASE_500/final)
.
CC ../../py/nlrthumb.c
../../py/nlrthumb.c:79:5: error: non-ASM statement in naked function is not supported
return 0; // needed to silence compiler warning
Why doesn't Clang support non-ASM statement in naked function?
This works fine on gcc.
The mailing list explains it as
Naked functions don't have prologues or epilogues, so doing
codegen for anything other than inline assembly would be completely
hit or miss.
so then how can gcc do it?

I should have written this as an answer instead of a comment. The question was:
Why doesn't Clang support non-ASM statement in naked function? This works fine on gcc.
The answer is that this doesn't work fine in gcc. Quoting from the gcc docs for the naked attribute:
Only basic asm statements can safely be included in naked functions. While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.
If there is a less ambiguous way to phrase this, I couldn't come up with it.
Note that while the specific link above is for ARM (which is what I'm guessing the OP is using), I believe the same text applies to all platforms that support naked.

Related

Using g_autoptr() together with G_DEFINE_AUTOPTR_CLEANUP_FUNC() when using older and newer GLib versions

There is something about using g_autoptr() together with G_DEFINE_AUTOPTR_CLEANUP_FUNC() when using different GLib versions which I don't understand (this affects also the other g_auto... variants and its G_DEFINEs).
The documentation says
"The way to clean up the type must have been defined using the macro
G_DEFINE_AUTOPTR_CLEANUP_FUNC()"
When using for example GLib 2.62 and using the G_DEFINE macro this results in errors like
/usr/include/glib-2.0/glib/gmacros.h:1032:49: error: redefinition of ‘glib_slistautoptr_cleanup_GtkTreePath’
1032 | #define _GLIB_AUTOPTR_SLIST_FUNC_NAME(TypeName) glib_slistautoptr_cleanup_##TypeName
Leaving out the G_DEFINE macro will solve the problem and the program works just fine.
However, on older GLib versions like 2.50 (which is for example still used by Debian 9), using the G_DEFINE macro will not result in an error message. But I can't see any changes reflected by the GLib documentation. I cannot determine when exactly the aforementioned change of behaviour has been introduced. How am I supposed to cope with this when I want to support all GLib versions from 2.50 on?
The issue is probably in Gtk, not GLib. g_autoptr() was supported for most things in Gtk+ 3.22 (the one in Debian 9) already: so you shouldn't have to call G_DEFINE_AUTOPTR_CLEANUP_FUNC() on Gtk types yourself. GtkTreePath however was still missing a call: this was added in 3.24, see https://gitlab.gnome.org/GNOME/gtk/-/commit/86dd1e37a70e9bae057a9a11332f7254cda242e8.
You'll probably have to do the macro call behind a version check if you want to use g_autoptr() with TreePath on Gtk < 3.24.

Prevent ArmClang to add calls to Standard C library

I am evaluating Keil Microvision IDE on STM32H753.
I am doing compiler comparison between ARMCC5 and AC6 in the different optimisation levels. AC6 is based on Clang.
My code is not using memcpy and I have unchecked "Use MicroLIB" in the project settings , However a basic byte per byte copy loop in my code is replaced by a memcpy with AC6 (only in "high" optimisation levels). It doesn't happen with ARMCC5.
I tried using compilation options to avoid that, as described here: -ffreestanding and -disable-simplify-libcalls, at both compiler and linker levels but it didn't change (for the second option, I get an error message saying that the option is not supported).
In the ARMCLANG reference guide i've found the options -nostdlib -nostdlibinc that prevent (??) the compiler to use any function of a standard lib.
However I still need the math.h function.
Do you know how to prevent clang to use functions from the Standard C Lib that are not explicitely called in the code ?
EDIT: here is a quick and dirty reproduceable example:
https://godbolt.org/z/AX8_WV
Please do not discuss the quality of this example, I know it is dumb !!, I know about memset, etc... It is just to understand the issue
gcc know a lot about the memcpy, memset and similar functions and even they are called "the builtin functions". If you do not want those functions to be used by default just use the command line option -fno-builtin
https://godbolt.org/z/a42m4j

Add #include's to the headers of a program using llvm clang

I need to add headers to an already existing program by transforming it with LLVM and Clang.
I have used clang's rewriter to accomplish a similar thing in the changing function names and arguments, etc.
But the header files aren't present in clang's AST. I already know we need to use PPCallbacks (https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html) but I am in dire need of some examples on how to make it work with the rewriter if at all possible.
Alternatively, adding a #include statement just before the first
using namespace <namespace>;
Also works. I would like to know an example of this as well.
Any help would be appreciated.
There is a bit of confusion in your question. You need to understand in details how the preprocessor works. Be aware that most of C++ compilation happens after the preprocessing phase (so most C++ static analyzers work after that phase).
In other words, the C++ specification (and also the C specification) defines first what is preprocessing, and then what is the syntax and the semantics of the preprocessed form.
In other words, when compiling foo.cc your compiler see the preprocessed form foo.ii that you could obtain with clang++ -C -E foo.cc > foo.ii
In the 1980s the preprocessor /lib/cpp was a separate program forked by the compiler (and some temporary foo.ii was sitting on the disk and removed at end of compilation). Today, it is -for performance reasons- some initial processing done inside the compiler. But you could reason as if it was still separate.
Either you want to alter the Clang compiler, and it deals (like every other C++ compiler or C++ static analyzer) mostly with the preprocessed form. Then you don't want to add new #include-s, but you want to alter the flow of AST given to the compiler (after preprocessing), and that is a different question: you then want to add some AST between existing AST elements (independently of any preprocessor directives).
Or you want to automatically change the C++ source code. The hard part is determining what you want to change and at what place. I suppose that you have used complex stuff to determine that a #include <vector> has to be inserted after line 34 of file foo.cc. Once you've got that information (and getting it is the hard thing), doing the insertion is pretty trivial. For example, you could read every C++ source line, and insert your line when you have read enough lines.

Are Hack named functions fully first-class citizens?

HHVM 3.9 is not such a fan of ternary statements with named functions, even when passed through fun(), but ≥3.10 is totally fine with them. It seems as though this is one of few cases, however, because 3.9 does accept named functions returned from concrete functions, as well as accepting named functions passed into other functions (3v4l):
<?hh
echo ((() ==> fun('strlen'))())('Hello'); // 5
echo (($f, $v) ==> $f($v))(strlen, 'Hello'); // 5 + Notice: Use of undefined constant strlen - assumed 'strlen'
echo (true ? strlen : intval)('100'); // Fatal error: syntax error, unexpected '(', expecting ',' or ';' on line 3
What changed between 3.9 and 3.10? Are there any cases in HHVM ≥3.10 where named functions cannot be referenced and used this way?
First, when writing Hack, don't write your code at toplevel; the hh_client typechecker can't check anything at toplevel. And 3v4l doesn't run the typechecker at all, you need to run it locally.
That said, no, Hack doesn't really have first-class functions. Most of its behaviour here it inherited from PHP, which also doesn't have them. Back when I was working on the Hack team, we tossed around a lot of ideas for adding them to the language; it's an obvious addition and need. But the need was never quite strong enough such that we sat down and actually worked out the details for both the type system and runtime implications; in particular, how to work out some of the scoping issues that the current callables have. Anonymous functions fill out enough of the need, especially with Hack's short lambda syntax, that there was always something more pressing to deal with.
So Hack just has PHP's normal callable forms; fun is one of a few special functions which give information to the typechecker that the string you specified actually represents a function so the typechecker can do proper type analysis. But at the end of the day, fun just boils down to the usual PHP callable forms with a bit of extra magic in the typechecker.
As to the behaviour you indicate in your 3v4l link. Using strlen and intval like that would cause a type error in Hack, since those are syntactically constants but constants with those names don't exist since Hack doesn't have first-class functions -- or it would if the code weren't at toplevel and you were running the typechecker. As to why it causes a parse error in HHVM 3.9 (which masks the "invalid constant" errors you see in 3.10), I'm not 100% sure. Judging from this example which works in PHP7 and HHVM 3.10, but not PHP5 and HHVM 3.9, my guess it is a PHP7 feature that is backwards compatible and so is always enabled in HHVM.

What does -fheinous-gnu-extensions option do?

When Homebrew compiles libgcrypt on OS X, it patches it to use clang and add -std=gnu89 and -fheinous-gnu-extensions to the CFLAG Makefile var. What does the latter do?
https://clang.llvm.org/doxygen/SemaStmtAsm_8cpp.html says:
GNU C has an extremely ugly extension whereby they silently ignore "noop" casts in places where an lvalue is required by an inline asm. We emulate this behavior when -fheinous-gnu-extensions is specified, but provide a strong guidance to not use it.
No, I haven’t used it; I don’t know why Homebrew needed it.

Resources