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

Fix several compiler warnings #336

Merged
merged 1 commit into from
Oct 27, 2023

Conversation

nirosys
Copy link
Contributor

@nirosys nirosys commented Oct 25, 2023

Issue #, if available: N/A

Description of changes:
This PR addresses the issues identified by GitHub's Code Scanning alerts, as well as a few others that are just a drop in the ocean of warnings ion-c currently spits out. I'm hoping to spend some time over the next few weeks cleaning up more, so hopefully this will be just the first PR in a series.

Pre-PR:

$ fgrep 'warning:' output.txt | wc -l
     301

Post-PR:

$ fgrep 'warning:' output.txt | wc -l
     280

Some Explainations

Int & FILE * conversions

I added a couple of macros to ion_stream.c called FD_TO_FILEP and FILEP_TO_FD. The ION_STREAM struct contains a field _fp that is of type FILE *, but is also used to store an integer file descriptor. When converting a pointer to an integer, C99 6.3.2.3.6 comes into play:

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

On x86_64 systems, a pointer is 64-bit, and an int is 32-bit, so the operation generates a warning. When converting from the integer to the pointer, the compiler also emits a warning, my guess is because of the same rule. The macros add a size_t which is not a pointer, and is a 64-bit value so it allows conversion to/from an int without warning, and to/from a pointer since the sizes match.

Redundant looking char *'s

There are a few added type casts to strings that look redundant, such as (char *)"str_col1". In C a string literal is considered a char *, at least up to C99. In C++11 (I think) C++ diverged from this idea and (rightfully) changed the string literal (which is usually kept read-only memory) to a const char *, a pointer to constant characters. Historically, most functions that take a string as an argument, consider the string to be const char *, but sometimes that is not the case, like with ion_string_assign_cstr, which takes a char * argument, even though no modification to the characters occur. So these type casts were used to stop the C++ compiler from complaining about dropping const, which rightfully could indicate a bug.

Integer Overflow in Computation

In argtable3.c, there is a calculation that involves multiple integers. The end result of the computation is used as a size_t argument to xmalloc. Implicit conversion from an int to size_t occurs in order to use the result as the argument, but that conversion occurs after the computation is complete. During the computation, it is possible that the integers involved, will overflow the integer storage, before the implicit conversion occurs. So I've added type casts to the values themselves so that each operation in the computation is considered a size_t. (This is all from the compiler's perspective, I don't think, in this situation, there's any chance that the argument parser could calculate memory requirements that exceed 32bit values)


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

ION_ASSERT_OK(ion_writer_write_string(writer, &value_string));

ion_string_assign_cstr(&fieldNameString, "str_col2", strlen("str_col2"));
ion_string_assign_cstr(&fieldNameString, (char *)"str_col2", strlen("str_col2"));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason not to change ion_string_assign_cstr take a const char *? Wouldn't that be preferable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be preferred, but I didn't want to make a potentially API breaking change. I need to dig deeper into what, if any, impact changing a const would have on a C API.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Maybe just put a comment on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, looking more into it, the API change wouldn't be too problematic. The ABI would remain the same, and since the const would determine our usage of the argument, it shouldn't cause an issue with users. However, I misremembered what ion_string_assign_cstr did, and it does not copy the string. So, it would have to drop the const anyway inside the function in order to pass it to the ION_STRING.

So now my question is: what is the intended use of ION_STRING? Looking at the API, most of the functions look like the string is expected to be immutable. If that is the case then ION_STRING's value field could be changed to a const BYTE *value (pointer to constant BYTE) so that the immutable nature of the string is communicated, and then the const-correctness could bubble up to the other functions.

That will probably require a lot more investigation into how the API is used.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea. I briefly pondered why ION_STRING couldn't be const. Honestly I don't know.

@nirosys nirosys marked this pull request as ready for review October 25, 2023 23:26
@nirosys nirosys merged commit 6d4de41 into amazon-ion:master Oct 27, 2023
14 checks passed
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.

2 participants