-
-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: check that we receive a scalar when expecting a scalar in C code #1051
Conversation
Current Aviator status
This PR was merged using Aviator. See the real-time status of this PR on the Aviator webapp. Use the Aviator Chrome Extension to see the status of your PR within GitHub.
|
5f62d79
to
cac459d
Compare
This already revealed an incorrect usage in an example, which I just fixed. See e44efad |
959bda8
to
3aa8a68
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, thanks!
The coverage checks take a hit here. I wonder if we should extract this conversion into a function, I suspect we won't add invalid argument checks for each and every function. |
I don't think so because memory is then not freed. Error handling in R/igraph is still a bit of a mess. We don't have clear guidelines, and I don't have a full understanding of how this work or should work. This should really be figured out before 2.0. Otherwise making changes like this one is stressful and risky. I wrote down my current understanding in a wiki page. Can you take a look? https://github.com/igraph/rigraph/wiki/Error-handling-in-C If what I wrote is correct then igraph functions cannot be called from a callback. If they are called anyway, things will go wrong. Is this accurate? Let's figure out how this should work, and continue afterwards. CC @ntamas |
What memory is there to free during argument checks? Do we need to separate argument checking from conversion? |
Some arguments may be vector-valued. These may get converted to igraph vectors, which will need to be freed if there is a failure. |
Is this still a problem if we first check arguments and then convert them? |
No, that is not possible. Suppose there are two vector arguments. First construct one, then the other. If the second construction fails, the first needs to be freed. This will always be a problem in some form. The error handling will need to be clarified either way, and it is completely doable. Trying to avoid error handling just for argument checks won't gain us anything. Am I missing something? |
We already agreed to use C++ and RAII for resource handling. Things will be much better once we have that. Right now, I'm focusing on releasing an update for the R package that will allow more frequent updates of the C core. I'd like to postpone anything that's not moving us closer to that milestone. The checks in this PR are great, but I'd rather not open another can of worms here. |
OK, just let me know if you plan to merge this before 2.0. If yes, I'll address your comments. |
I'll run revdepchecks and push the results here. It's certainly good to have this in the code, an error (even with a memory leak) is better than undefined behavior. |
bf5a6b9
to
bc573e8
Compare
Stylistic changes committed and squashed, handing this off to you now. |
Thanks. I still think length and integerness checks should live in their own functions, for more realistic coverage results. We can run revdepchecks on the current state, but now that #1055 is merged, we might as well extract the functions as part of this PR. @Antonov548: can you please extract functions for checking length one and integerness, and use them for the generated code? |
Yes, sure. I will take a look. |
bc573e8
to
b23f316
Compare
Only two failures, good to merge after extracting functions for the checks. |
Does it make sense to make it in the same pr? |
b23f316
to
1fe583b
Compare
I think so, yes. This PR drops coverage, I'd like to get back to baseline before merging. |
It doesn't truly reduce coverage. It only reduces the imperfect number that simple tools report. There are a lot of useful refactorings that drop that number, for example removing dead code often does. |
It's green now |
IGRAPH_R_CHECK_INT(%I%); | ||
%C% = (igraph_integer_t) REAL(%I%)[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the future: we could do something like
IGRAPH_R_CHECK_INT(%I%); | |
%C% = (igraph_integer_t) REAL(%I%)[0]; | |
%C% = IGRAPH_R_CHECK_INT(%I%); |
with a suitable implementation of IGRAPH_R_CHECK_INT()
. It's good as is for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for the other check functions.
This pull request can't be queued because it's currently a draft. |
and for integer-valued scalars, also check that they are representable
2190641
to
3b545ad
Compare
@krlmlr What do you think about refactoring these functions to macros? The main advantage is that the line number in the error message would actually be useful for debugging. It would pinpoint where exactly the error came from. Doing this should not have an effect on coverage (assuming that coverage is measured in the same way as for the C core). |
This is experimental. It is not completely clear to me if calling the error function directly at this point is fine ... there needs to be clarity about
IGRAPH_CHECK
vsIGRAPH_R_CHECK
and where each is allowed to be used.This fixes a potential crash in code such as
sample_pref(c(), 3)
. Herec()
is a zero-length vector which means that the C code would do an out-of-bounds access. This may or may not crash depending on your luck.The behaviour is now like this:
This is likely to cause revdepcheck failures. @krlmlr It would actually be worth doing a revdepcheck with this soon, as it may reveal graph bugs as well.
EDIT: Now it also checks for non-integer values (including NaN and infinities) when an integer is expected.