I am a new in using clang/Xcode. I have a question now that I build a code analyzer through clang-rewriter and I must get a log from return statement of every function , so I do this.
#define return if(fun1(),1) return
But when I come across this situation , the clang cannot make me compile success
As I have to build the prj automatically , I want to find a way to ignore this error, like g++ ,I can through '-Wno-return-type' to ignore this warning, but I configure this in Xcode,it is not used. :(sad
IMO the problem is not the warning but the way you return from the block. Instead of adding an explicit else branch you can just write the following (which is semantically the same):
if(cmp != NSOrderedSame) {
return cmp;
}
return [lhs.tagName compare:rhs.tagName];
Related
My Usecase:
I have two c language files: ApplicationCode.c and UserCode.c . Application code is something generated by my app and UserCode is available to my application user where he can write his own code.
ApplicationCode.c internally uses UserCode.c and calls out its methods/function.
One thing you can assume here that ApplicationCode.c will never have any errors but could have warnings generated by gcc compiler. And UserCode.c can have both errors and warnings.
So, While compiling code I wanted to show user his code's errors as first priority. If needed to show warning also then show warning generated by his code only not from ApplicationCode.c (As i don't want to expose my ApplicationCode.c's code).
One more constraint is here that I wanted to show return-type warning as error here and for this I am using -Werror=return-type argument.
So, I am thinking of following three approaches to do this:
If I could able to disable all the warnings and enable only -Wreturn-type
Raised a saparate question for this here
If I could able to instruct gcc (or redirect) only error messages to stderr and rest on stdout.
Raised a saparate question for this also here
If I could able to disable all the warnings (which are enabled by default) from ApplicationCode.c file and enable all with -Werror=return-type for UserCode.c
I tried searching everywhere but did not get any solution for all the above 3. Let me know how could I achieve above problems or if there any other better way to do solve my use case ?
Update 1:
Here is my both the code file look like
ApplicationCode.c
#include <stdio.h>
// some headers
// some application specific code
int testUserFunction(); // user function declaration
int main(int argc, char *a[]) {
int result = testUserFunction(); // calling user function
// some logic to use and evaluate result
}
UserCode.c
#include<stdio.h>
int testUserFunction(int input1)
{
// user will write his code below this
// user code
}
Base command to compile code:
gcc -o code.out ApplicationCode.c UserCode.c
or if there any other better way to do solve my use case ?
If you don't want to "expose ApplicationCode.c", then why are you showing its compilation output in the first place? Solution: Compile it in somewhere secret and let the user link their UserCode.c with it.
I want to define a custom set of rules to be checked at compile time. But it seems not to work.
Example:
I choose one rule directly and I'll get the expected warning.
But when I instead create a custom ruleset containing the exact same rule then I won't get the expected warning.
What could be wrong?
Edit:
void f(std::string& i) {
std::string s = i;
cout << s;
}
int main()
{
std::string s ("abc");
f(s);
}
This gives me the expected warning Warnung C26460 The reference argument 'i' for function 'f' can be marked as const (con.3). in the first case.
Even if I create a custom ruleset including all available rules, I won't get any warnings.
Here you see me selecting the custom ruleset:
Edit: The ruleset action must change one time to enable it.
When I create a new ruleset containing only the const-checks then I will get a .ruleset that does not work and look like this:
In the ruleset editor it looks like this:
When I then change its action from Warning to Error:
Then the .ruleset gets additional lines for each test case:
When I change the action back to warning it looks like this:
Now it is working as expected.
I've been able to reproduce your error with Visual Studio 2017. I don't know exactly what I changed (or if I changed anything at all), but I am able to see the code analysis warning you expect with a custom rule set.
Things I would try:
Double check the Error List window is visible and not hiding somewhere.
Open the rule set file, change the Action to Error and then back to Warning and save it. I wouldn't expect this to be the problem but it's one of the things I did and after which I started seeing the Error List window.
I want my clang plugin to not actually do anything if there was an error compiling the code for the AST my plugin is going to run on.
However, I can't figure out what object contains the list of errors generated during compilation.
Is there either a boolean query for whether there was an error or a list API for getting all the errors (or all diagnostics) generated during the TU compilation?
Thank you.
I eventually figured out a way to get the error count from a CompilerInstance object:
auto & ast_context = compiler_instance.getASTContext();
auto & diagnostics_engine = ast_context.getDiagnostics();
auto diagnostic_consumer = diagnostics_engine.getClient();
auto error_count = diagnostic_consumer->getNumErrors();
if (error_count > 0) {
llvm::report_fatal_error("Errors during compilation, plugin aborting");
}
I don't know if this is the best way, but it is working for me when I put the above code in the onStartOfTranslationUnit of my class I derive from ast_matchers::MatchFinder::MatchCallback.
While porting my lexer file from Quex 0.64.8 to 0.67.4 I ran
into some problems with the string accumulator. The issues
I get look like this:
Severity Code Description Project File Line Suppression State
Error C3861 'ecmascript_lexer_Accumulator__clear': identifier not found (compiling source file C:\Users\Patrikj\Work\git\ecmascript_build_vc14_x64\generated\ecmascript_lexer.cpp) ktes C:\Users\Patrikj\Work\git\ecmascript\ecmascript.qx 107
I suppose it's the double underline Accumulator__clear that is the cause of the issue. Maybe I need to supply a new switch to Quex or maybe the API
has changed in the newer version. Either way I am at a loss on how to
fix the issue.
And example from my lexer (.qx) that generates the issue:
mode StringHelper : EOF
<inheritable: only>
{
on_exit {
/// All 3 rows using the accumulator generates an error similiar to the one mentioned above
if(self.accumulator.text.begin != self.accumulator.text.end)
self_send(TOK_STRLITPART);
self_accumulator_flush(TOK_QUOTE);
self_accumulator_clear();
}
}
Any help fixing this issue would be much appreciated.
Best regards,
Patrik J
Version 0.67.3 and later excluded the string accumulator from
the main generator. The reason was that for some situations
there is no general solution in the construct, include-push,
and reset scenarios. Users must specify them as they go along.
For using the accumulator, no command line option is required.
However, in the .qx files the following sections need to be defined
(this is an example):
header {
#include <quex/code_base/extra/accumulator/Accumulator>
}
footer {
#include <quex/code_base/extra/accumulator/Accumulator.i>
}
body {
QUEX_NAME(Accumulator) accumulator;
}
constructor {
if( ! QUEX_NAME(Accumulator_construct)(&me->accumulator, me) ) {
return false;
}
}
destructor {
QUEX_NAME(Accumulator_destruct)(&me->accumulator);
}
print {
QUEX_NAME(Accumulator_print_this)(&me->accumulator);
}
The case with the PostCategorizer is the same. You find the setup
shown below in 'common.qx' files in the demo subdirectories.
Also, after 'flush()' you do not need to 'clear()'.
I'm new to LLVM. I am using the clang c++ API to compile multiple stub files (in c) to IR, and then stick them together using IR builder (after linking them) to eventually run via JIT.
All this works great, unless I add a functionInlining pass to my optimizations, at which point one of these function calls made in IR builder will trigger the following exception when the pass manager is run:
Assertion failed: (New->getType() == getType() && "replaceAllUses of value with new value of different type!"), function replaceAllUsesWith, file /Users/mike/Development/llvm/llvm/lib/IR/Value.cpp, line 356.
This is how I make the call instruction (pretty straight forward):
Function *kernelFunc = mModule->getFunction( (kernel->Name() + StringRef("_") + StringRef(funcName)).str());
if (kernelFunc){
CallInst* newInst = builder.CreateCall(kernelFunc, args);
}
Later the module is optimized:
legacy::PassManager passMan;
PassManagerBuilder Builder;
Builder.OptLevel = 3;
//Builder.Inliner = llvm::createFunctionInliningPass(); //commenting this back in trigger the exception
Builder.populateModulePassManager(passMan);
passMan.run( *mModule ); //exception occurs before this call returns
Any ideas what to look for?
Try running llvm::verifyModule on your module to see if it's correct. You might have an error and have been getting lucky beforehand but it tripped something up in the inliner.
In general assertions check a subset of things that can be wrong with your module but verify checks a lot more.
It could be a bug in LLVM but more than likely it's a bad module, it's easy to happen.
So I finally setup my dev environment so I could inspect the assertion call in the debugger. I turns out the basic block being replaced had a different context set than the one it was being replaced with. going back and making sure IRBuilder was using the same context as the IR parsers solved the problem.