Skip to content
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

Small steps towards enabling -Wsign-conversion for some submodules #3413

Merged
merged 5 commits into from Dec 17, 2019

Conversation

felipecrv
Copy link
Contributor

Enabling -Wsign-conversion, makes the compiler report many sign conversions in libponyrt (not a suprise). Most of them are inoffensive, but some conversions of negative integer to unsigned integers could potentially lead to infinite loops or attempts to allocate
an (unsigned)-1 amount of memory.

Enabling -Wsign-conversion can prevent these things from becoming bigger issues and hint at possible refactorings of the code (e.g. use a signed integer as the return type when a function can return negative integers).

Doing `return std::move(value)` is, in general, not a good idea, and GCC
warns about it.

```
src/libponyc/codegen/genjit.cc: In lambda function:
src/libponyc/codegen/genjit.cc:46:34: error: redundant move in return
statement [-Werror=redundant-move]
      46 |         if (err) return std::move(err);
	 |                         ~~~~~~~~~^~~~~
src/libponyc/codegen/genjit.cc:46:34: note: remove ‘std::move’ call
```

But in this case, this warning is a false-positive.  What's happening is
an implicit conversion from `Error &&` to `JITSymbol`. Changing the code
to be explicit rather than implicit fixes the warning and makes the code
more clear.
@felipecrv felipecrv changed the title Enable -Wsign-conversion for libponyrt WIP: Enable -Wsign-conversion for libponyrt Nov 30, 2019
@felipecrv felipecrv changed the title WIP: Enable -Wsign-conversion for libponyrt Small steps towards enabling -Wsign-conversion for some submodules Nov 30, 2019
@felipecrv
Copy link
Contributor Author

@SeanTAllen my initial plans were more ambitious, but I decided to reduce the scope of this PR to contain only these initial steps. Please review whenever you can.

@cquinn
Copy link
Contributor

cquinn commented Dec 3, 2019

One approach that might work here is to encapsulate these casts in macros so that they could be switch on or off based on platform or compiler flags. They could also be easier to locate and change as needed.
Maybe something like TO_INT64(), TO_SIZET(), TO_INT(), etc.

@felipecrv
Copy link
Contributor Author

@cquinn making those dependent on compilation macros might hide some bugs. And the point of explicit casts is to reduce the risk of bugs due to implicit conversions.

Most of the explicit casts wouldn't be needed if the code was re-structured in a way that is more portable. The explicit casts work as a reminder of that.

@cquinn
Copy link
Contributor

cquinn commented Dec 3, 2019

True, but I think the macros would be at least as visible as the casts. The discussion on the dev sync brought up that this change actually makes these conversions harder to find than just leaving them implicit and letting the compiler give us a warning/error. The macro idea was to make these casts stand out for later fixing, and also allow their internals to be easily modified.

@felipecrv
Copy link
Contributor Author

felipecrv commented Dec 3, 2019 via email

@felipecrv
Copy link
Contributor Author

@cquinn I looked at the commits left in this PR again and I think they are all portable and necessary (i.e. they don't hint at a problematic choice of integer types in the program).

@SeanTAllen
Copy link
Member

Does any @ponylang/committer have time to review this to verify @philix's belief? It would be good to get one more set of eyes. @jemc has said he will try.

@SeanTAllen SeanTAllen requested a review from jemc December 10, 2019 19:22
test/libponyrt/ds/list.cc Outdated Show resolved Hide resolved
Nothing in the generated code will change duo this (see
https://godbolt.org/z/n6Dkdp), but it makes it more clear what's
happening and doesn't violate -Wsign-conversion (which I plan to
enable). Without this change, clang reports:

    src/libponyrt/ds/list.c:52:39: error: implicit conversion changes signedness:
    'unsigned long' to 'ssize_t' (aka 'long') [-Werror,-Wsign-conversion]
        index = ponyint_list_length(list) + index;
              ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
    src/libponyrt/ds/list.c:52:41: error: implicit conversion changes signedness:
    'ssize_t' (aka 'long') to 'unsigned long' [-Werror,-Wsign-conversion]
        index = ponyint_list_length(list) + index;
                                          ~ ^~~~~
The GCC/clang builtins listed here return int even though they never
return a negative number.

The __pony_* wrappers of these builtins all return unsigned and most
of the use-cases of the builtins make sense with the unsigned result,
so I think it makes sense to have unsigned return as the default for
all platforms.

This change means we don't have to add many explicit casts in the calls
to __pony_* to fix -Wsign-conversion violations.
@SeanTAllen SeanTAllen merged commit bfc9b86 into ponylang:master Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants