-
Notifications
You must be signed in to change notification settings - Fork 61
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
Polish CodeQL and do some chores #2255
Polish CodeQL and do some chores #2255
Conversation
I was wondering about some of these Are these there to avoid a potential For the changes in |
Hi @halfflat, they're here to silence CodeQL static analysis. I agree, that was a unnecessarily lazy approach to the affair. |
I don't recall why it was signed; I'd have to go look at the git blame :) It might have been because we use them to store differences. It's possible but less likely they get SIMDed somewhere and we don't yet have unsigned SIMD in the library. |
But on the CodeQL front, what is its complaint? Potential signed overflow, or is it complaining about implicit conversion of signed to size_t in the Is there some way of decorating
it would all be fine? |
pbuf->prefix = std::string(tabs*tabwidth, ' '); | ||
if (auto ptr = static_cast<indent_stack*>(s.pword(index)); | ||
ptr && !ptr->empty()) { | ||
unsigned n_tab = ptr->top(); |
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.
Argh! This is terribly misleading formatting.
Edit: what was so bad with unsigned tabs = (!stack_ptr || stack_ptr->empty())? 0: stack_ptr->top();
?
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.
I knew you were going to love it. Isn't it beautiful how the second line of the condition and the first line of the body line up?
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.
It has a certain horrible charm to it.
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.
Fixed it.
Possibly, but I do not think it's worth it even. CodeQL is technically correct in pointing out that possibility, but The urge to 'fix' this was merely my completionist attitude. |
test/unit/test_sde.cpp
Outdated
@@ -377,8 +377,8 @@ class sde_recipe: public simple_recipe_base { | |||
// generic advance method used for all pertinent mechanisms | |||
// first argument indicates the number of random variables | |||
void advance_common(unsigned int n_rv, arb_mechanism_ppack* pp) { | |||
const auto width = pp->width; | |||
arb_value_type* ptr = archive_ptr->claim(std::size_t{width} * n_rv); | |||
auto width = static_cast<size_t>(pp->width); |
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.
Why not just size_t width = pp->width
?
Regarding the CodeQL flagging the size_t conversion, I'd say we should either ignore it or address it in a robust way (with actual range checks). My inclination is to ignore it. |
modcc/io/prefixbuf.cpp
Dismissed
ptr && !ptr->empty()) { | ||
unsigned n_tab = ptr->top(); | ||
unsigned width = s.iword(index); | ||
pbuf->prefix = std::string(n_tab*width, ' '); |
Check failure
Code scanning / CodeQL
Multiplication result converted to larger type High
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.
Dismissed.
using count_type = typename gathered_vector<cell_gid_type>::count_type; | ||
|
||
count_type local_size = local_gids.size(); | ||
size_t local_size = local_gids.size(); |
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.
std::size_t
?
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.
Yes and all other instance in that file.
test/unit/test_sde.cpp
Outdated
@@ -377,8 +377,8 @@ class sde_recipe: public simple_recipe_base { | |||
// generic advance method used for all pertinent mechanisms | |||
// first argument indicates the number of random variables | |||
void advance_common(unsigned int n_rv, arb_mechanism_ppack* pp) { | |||
const auto width = pp->width; | |||
arb_value_type* ptr = archive_ptr->claim(width * n_rv); | |||
std::size_t width = static_cast<size_t>(pp->width); |
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.
std::size_t width = static_cast<size_t>(pp->width); | |
auto width = static_cast<std::size_t>(pp->width); |
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.
Yes, that's fine, too.
@@ -138,8 +138,8 @@ using time_type = double; | |||
constexpr time_type terminal_time = std::numeric_limits<time_type>::max(); | |||
|
|||
// For holding counts and indexes into generated sample data. | |||
|
|||
using sample_size_type = std::int32_t; | |||
using sample_index_type = std::int32_t; |
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.
where is this type actually used?
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.
It -- currently -- isn't, but it's useful when we are considering things like:
sample_size_type a = ..., b = ..., c = a - b;
due to the potential overflow.
for (size_t i = 0; i < num_ranks_; i++) { | ||
util::append(gathered_gids, local_gids); | ||
} | ||
|
||
for (count_type i = 0; i < num_ranks_; i++) { | ||
for (count_type j = i*local_size; j < (i+1)*local_size; j++){ | ||
for (size_t i = 0; i < num_ranks_; i++) { |
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.
2 more std::size_t
s
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.
One query and some requests for changing how we deal with the wrapping product warning. Generally, I suspect the cost of a range-checking assert is cheap and provides the guarantees we need while casting up and down the unsigned integer sizes keeps the potential bug while changing its clothes.
Currently arb_assert
is a build-time option, and I'm wondering if we could perhaps split its functionality into asserts which should always be checked and those which are really there to be enabled when we're tracking down bugs in our code logic.
arb_assert((unsigned)n_raw_per_sample==p.weight.size()); | ||
sample_size_type n_sample = (sc.end_offset - sc.begin_offset)/n_raw_per_sample; | ||
arb_assert((sc.end_offset - sc.begin_offset)==n_sample*n_raw_per_sample); | ||
arb_assert((unsigned)n_raw_per_sample == p.weight.size()); |
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.
Are these changes to make CodeQL happy, or just for readability?
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.
Readability. I can get behind a*b + c
for similarities with mathematical notation, but =
, ==
, and especially -
tend to merge visually into one token. Or: Too similar to snake_case
for my liking.
As much of the code, especially newer parts is in this style, I tend to adjust these expression in passing when editing files. Same for removing redundant headers, which my IDE picks up on these days.
@@ -26,7 +24,7 @@ struct dry_run_context_impl { | |||
count_type local_size = local_spikes.size(); | |||
|
|||
std::vector<spike> gathered_spikes; | |||
gathered_spikes.reserve(local_size*num_ranks_); | |||
gathered_spikes.reserve(std::size_t{local_size}*num_ranks_); |
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.
We shouldn't change the (effective) maximum size of the gathered_spikes vector without also changing the range of the indices in the loop 35-37.
We ultimately make a partition of the indices into the variable partition
which has count_type
as its value type, and this vector is used to construct the gathered_vector
return type, which also expects things in terms of count_type
. I believe the correct fix is not to cast local_size
or use std::size_t
here but instead
- Add an assertion which confirms that the
local_size*num_ranks_
doesn't wrap incount_type
, and - Uses
std::size_t{local_size*num_ranks_}
to keep CodeQL happy or else we tell CodeQL that this is not a bug (my preference).
std::vector<count_type> partition; | ||
for (count_type i = 0; i <= num_ranks_; i++) { | ||
for (std::size_t i = 0; i <= num_ranks_; i++) { | ||
partition.push_back(static_cast<count_type>(i*local_size)); |
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.
There's no point doing everything in size_t
only to cast back down to count_type
here; the alterations just make the potential bug more obscure. IMO the only correct resolution is to have an assert that checks that the product doesn't wrap and then to keep using count_type
.
Polish CodeQL integration:
tsplot
is not processing htmljson/.../serve.py
is not ours