Skip to content

LLVM sanitizer issues #220

@yzazik

Description

@yzazik

Hi Eyal,
Thank you for the great library and even better support.
I have a couple of UBSan (Undefined Behaviour Sanitizer) issues with LLVM (v20.1.0) building on x64.

First screams at this line when calling printf("%g", 0.0014663999499999749):

dwba.U = ((printf_fp_uint_t)(exp2) + FP_TYPE_BASE_EXPONENT) << FP_TYPE_STORED_MANTISSA_BITS;

saying:

runtime error: unsigned integer overflow: 18446744073709551606 + 1023 cannot be represented in type 'printf_fp_uint_t' (aka 'unsigned long long')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior printf.c:989:38

exp2 is -10 in this case, and 18446744073709551606 is FFFF FFFF FFFF FFF6 which is -10 casted to unsigned type.

From the looks of it, LLVM just doesn't like things being wrapped around at math operations.
Can you please see if you can still add first and then cast second so this issue would go away?
Checked this locally, seems fine, unless of course you have some other way to fix it:

dwba.U = (printf_fp_uint_t)(exp2 + FP_TYPE_BASE_EXPONENT) << FP_TYPE_STORED_MANTISSA_BITS;

Second screams here at decrement when calling print("%s", "{");:

          while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision)) {
            putchar_via_gadget(output, *(p++));
            --precision;
          }

saying:

runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'printf_size_t' (aka 'unsigned int')
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior printf.c:1518:13

flags and precision are both zero in this case.
Not sure what to recommend here.
Checking static flags in a loop is already a potential performance issue.
So if performance is not that critical, checking for zero would be the simplest:

            if (precision)
              --precision;

If performance is critical, then I would rather split it to two loops,
one for the case when FLAGS_PRECISION is set and another when it's not.
This would obviously increase the code size more than just a zero check.

One other option is to declare precision to be signed, then it's more work and code impact.
Thank you.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions