How to provide fix for all parameters of the method (Roslyn - FixProvider) - roslyn

I wrote code analyzer & fix provider for adding validations to ensure argument is not null. It works good for multiple methods, but I cannot check all the parameters at once. The analyzer will mark all the parameters that are not checked already, but fix can be done only for one parameter at once.
Details:
It is not immutable nodes issue, the code adds using statement if needed.
In the analyzer i register diagnostic for every parameter.
Diagnostic diagnostic = Diagnostic.Create(
Rule,
parameter.GetLocation(),
null,
prop.ToImmutableDictionary(),
parameter.Identifier.Text);
In the fix provider I am taking first diagnostic from the context and register code fix for that.
Maybe I am doing something wrong and thus do not get multiple diagnostics in the fix provider.
What is the correct way to make multiple fixes? Should be the key/id of the diagnostic the same? Or should the diagnostic be registered directly to complain about all the parameters.

I have found hopefully good solution:
The analyzer report diagnostics for every invalid parameter so you can generate validation for specific parameter. After that the analyzer reports one more diagnostic for all the invalid parameters and sets the method identifier as the location.
The same code fix provider is used to solve both types of diagnostics. The specific parameter one (which sends the single parameter data) and all the parameters one (which sends collection of the parameters data).

Related

C++ link time resource "allocation" without defines

I'm currently working on a C++ class for an ESP32. I want to implement resource allocation of the resources like: IO-Pins, available RMT channels and so on.
My idea is to do this with some kind of resource handler which checks this at compile time, but I have no good idea nor did I find anything about something like this yet.
To clarify my problem lets have an example of what I mean.
Microcontroller X has IO pins 1-5, each of these can be used by exactly one component.
Components don't know anything from each other an take the pin they should use as a ctor argument.
Now I want to have a class/method/... that checks if the pin, a component needs, is already allocated at compile time.
CompA a(5); //works well: 5 is not in use
CompB b(3); //same as before, without the next line it should compile
CompC c(5); //Pin 5 is already in use: does not compile!
Im not sure yet how to do so. My best guess (as I can't use defines here: users should be able to use it only by giving a parameter or template argument) is, that it might work with a template function, but I did not find any way of checking which other parameters have been passed to a template method/class yet.
Edit1: Parts of the program may be either autogenerated or user defined in a manner, they do not know about other pin usages. The allocation thus is a "security" feature which should disallow erroneous code. This should also forbid it, if the register functions are in different code pathes (even if they might exclude each other)
Edit2: I got a response, that compile time is wrong here as components might be compiled separated from another. So the only way to do so seems like a linker error.
A silly C-style method: you could desperately use __COUNTER__ as the constructor's argument. This dynamic macro increases itself after each appearance, starting with 0.
I hope there's a better solution.

Why does gdb show a different parameter order for a function

Looking through a core file(generated by C code) with gdb, I am unable to understand one particular thing between these 2 frames
#2 increment_counter (nsteps=2, steps=0x7f3fbad26790) at gconv_db.c:393
#3 find_derivation (...) at gconv_db.c:426
This code is from open source glibc where find_derivation calls increment_counter as:
result = increment_counter (*handle, *nsteps);
The *handle and steps are of the same type and increment_counter function is defined as static
Why does gdb show that the 2 parameters have different order ?
I am pretty sure that glibc was taken as is without modification
Why does gdb show that the 2 parameters have different order ?
GDB doesn't know anything about the source (except possibly where on disk it was located at build time).
It is able to display parameters (and their values) because the compiler told it (by embedding debug info into the object file) what parameters are, in what order they appear, their types, and how to compute their value.
So why would a compiler re-order function arguments?
The function is static, so it can't be called from outside of the current translation unit. Thus the compiler is free to re-order the parameters, so long as it also re-orders the arguments at every call site.
Still, why would it do that? General answer: optimization (compiler found it more convenient to pass them in this order). Detailed answer would require digging into GCC (or whatever compiler was used to build this code) source.

(ValidationError) when calling the CreateStack operation: Template format error: Every Description member must be a string

The following image is my question. SO would not allow me to post because of some error about formatting code incorrectly that I couldn't figure out how to resolve after an hour of trying.
Image of my question
I've been bitten by this too. It boils down to limitations on CloudFormation's intrinsic functions (source):
Note
You can use intrinsic functions only in specific parts of a template. Currently, you can use intrinsic functions in resource properties, metadata attributes, and update policy attributes.
In this case, "resource properties" only applies to the contents of the Properties field. I would expect this to change, since I suspect Amazon has gotten many complaints about this! I'll happily update the answer when that happens.
The Description must be a literal string value. Even if it is an expression that returns a string, such as the one you have, it is invalid. Here is a related question.

How to populate the va_list for system error messages using the FormatMessage function?

I am unsure if I have made a fundamental issue in my implementation or there is a bug in the Windows API with regards to formatting system error messages.
I have a Windows API wrapper method for the FormatMessage function. My implementation allows the caller to pass in additional parameters to allow for the formatting of system error messages.
The method signature is as follows:
bool setFormattedMessage(int arguments, ...)
Within this method I have the following block of code that doesn't appear to work for all my unit tests:
if (arguments)
{
va_list argumentsList;
va_start(argumentsList, arguments);
size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, language, (LPWSTR)&buffer, 0,
&argumentsList);
va_end(argumentsList);
}
Note:
code and language are members of the class set in the instantiation list (using GetLastError and LANGIDFROMLCID(GetThreadLocale()).
Here are some unit tests that pass without any problems:
If I create an instance of the class for an error code of 34 I will get the following if I call the method as test.setFormattedMessage(0) (note that this doesn't go into the block of code I posted due to the if (arguments) line):
The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.`
If I call the method as test.setFormattedMessage(3, L"C:", L"disk 2", L"ABC123") I get the following:
The wrong diskette is in the drive. Insert disk 2 (Volume Serial Number: ABC123) into drive C:.;
However, for error messages that include such examples as %hs or %08lx I run into problems attempting to format the text.
Take the example of error code 573. When passing an argument of 0 into the method I get the following text (as expected):
{Missing System File} The required system file %hs is bad or missing.
But, if I pass in (1, "test") I end up with:
{Missing System File} The required system file hs is bad or missing.
In fact, I have found that regardless of whether I pass in "test", L"test", a copy of char, wchar_t etc I always end up with the error message above. The message created is the same as passing (0) with the exception of having the % dropped from the string.
I am finding the same problem for all other parameters unless they are numbered (such as %1). I am completely stuck at this point as to whether I have made a fundamental error or there really is a shortcoming in the FormatMessage function.
I was under the impression that I could pass in a replacement for the %hs placeholder in the same way I would do it for swprintf:
char * t = "file 123";
wchar_t a[2000];
int v = swprintf(a, 2000, L"Blah blah %hs", t);
std::wstring someText(a, v);
Blah blah file 123
If you read the FormatMessage() documentation, it specifically states:
Security Remarks
If this function is called without FORMAT_MESSAGE_IGNORE_INSERTS, the Arguments parameter must contain enough parameters to satisfy all insertion sequences in the message string, and they must be of the correct type. Therefore, do not use untrusted or unknown message strings with inserts enabled because they can contain more insertion sequences than Arguments provides, or those that may be of the wrong type. In particular, it is unsafe to take an arbitrary system error code returned from an API and use FORMAT_MESSAGE_FROM_SYSTEM without FORMAT_MESSAGE_IGNORE_INSERTS.
Your code is using FORMAT_MESSAGE_FROM_SYSTEM without using FORMAT_MESSAGE_IGNORE_INSERTS, which is not safe.
So, unless you are absolutely sure that you know the EXACT formatting of any given system error code, and your code has checked for that error code before deciding which formatting parameters to pass in, and you are absolutely sure that Microsoft will never change that format of that error message between OS versions, then you simply cannot safely use formatting arguments with system errors, so don't even try. Formatting arguments are only safe to use when you use your own error messages via FORMAT_MESSAGE_FROM_HMODULE to access your own EXE/DLL module resources, or FORMAT_MESSAGE_FROM_STRING to provide your own error message string in memory.
Following clarification from David Heffernan (see comments in the original question) it can be confirmed that the FormatMessage function doesn't support the ability to replace system error message placeholders unless they are numbered (%1). Therefore, a placeholder such as %hs will become hs.
Note that the above is only true when you are not using the FORMAT_MESSAGE_IGNORE_INSERTS flag.
I have checked through the system error messages using this link:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
The error messages listed here do not appear to mix the placeholder styles (an error message will either use numbered placeholders or uses the alternative format).
For numbered placeholders it is possible to continue using the functionality as described in the original question. For error messages that use the alternative style it is possible to use vswprintf, but only after calling the FormatMessage function with the FORMAT_MESSAGE_IGNORE_INSERTS flag (call vswprintf on the populated buffer, and remember to re-initialise the va_list).
There is perhaps a weakness in the overall approach when also supporting internationalisation. It is possible that the order of placeholders could differ across different languages.
The effort drastically increases if you really need to call FormatMessage to retrieve system error messages without using the FORMAT_MESSAGE_IGNORE_INSERTS flag. In addition to what has been described above, you can also get a C0000005 exception if your va_list doesn't match the number (and possibly types) of placeholders.

Failing compilation if return value is unused for a certain type

I would like to make compilation fail for some function call but not others. The function call that I want to fail are those that do not handle return values when the value is of a certain type. In the example below, not handling a function returning Error is a compilation error but not handling a function that returns anything else should succeed just fine.
Note: our runtime environment (embedded) does not allow us to use the following constructs: RTTI, exceptions.
This code only needs to compiler with Clang, I would prefer not having to annotate each function.
We prefer a solution that fails at compile time instead of at runtime.
enum class Error {
INVAL,
NOERR,
};
// do something that can fail.
Error DoThing();
// may return different return codes, we never care (we can't change prototype)
int DoIgnoredThing();
int main() {
DoThing(); // compilation failure here, unused "Error" result
DoIgnoredThing(); // compilation succeeds, OK to ignore unused "int" result
return 0;
}
I don't know of a way to do it with straight C++, but if you're using g++ you can use the warn_unused_result attribute along with the -Werror=unused-result command-line flag. See the documentation for warn_unused result for how to specify it (you'll have to specify it on every function unfortunately; I don't believe you can specify it for a type). Then the compiler flag will turn that warning into an error.
If you're not using g++, your compiler may have similar functionality.
You might find it easier to use a code analysis tool to scan the source code.
This might let you use the return type, as you requested, or a different marker for the functions to test like a comment to indicate which functions should be checked.
You might run the analysis tool as part of the compilation process or as part of a build server.
I've tried a few ways to make a class that would do what you want, but I haven't been successful. Have you considered making your "return value" an argument passed by reference? That's the most common way that I've seen APIs force you to pay attention to the return value. So instead of
Error DoThing();
you have
void DoThing(Error& e);
Anything that calls DoThing() has to pass in an Error object or they will get a compiler error. Again, not exactly what you asked for, but maybe good enough?