NO

Author Topic: strnlen_s bug with /Ot option  (Read 1464 times)

Offline ntprc

  • Member
  • *
  • Posts: 2
strnlen_s bug with /Ot option
« on: December 23, 2020, 06:19:06 AM »
Code: [Select]
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>

//#pragma function(strnlen_s) // disable [strnlen_s] intrinsic form, bug fixed

int main(void)
{
char str2[110] = "1234";

printf("len[%s] = %zd\n", str2, strnlen_s(str2, 110)); // intrinsic form bug

printf("len[%s] = %zd\n", str2, strlen(str2));

return 0;
}


 "Pelles C for Windows, version 10.00" win7
CCFLAGS = -Tx64-coff -Ot -W1 -std:C17 -Zi#

Output:
len[1234] = 220
len[1234] = 4

When compile with 64bit and /Ot
size_t strnlen_s(const char *string, size_t max);
if length of string < max, strnlen_s return 2*max.

strnlen_s generated as inline code:
   printf("len[%s] = %zd\n", str2, strnlen_s(str2, 110));      // intrinsic form bug
  [000000014000101E] 488D7C2422                   lea               rdi,[rsp+22]
  [0000000140001023] B96E000000                   mov               ecx,6E
  [0000000140001028] 31C0                         xor               eax,eax
  [000000014000102A] 4885FF                       test              rdi,rdi
  [000000014000102D] 7410                         je                000000014000103F
  [000000014000102F] 4989CA                       mov               r10,rcx
  [0000000140001032] F2AE                         repne scasb       
  [0000000140001034] 4C89D0                       mov               rax,r10
  [0000000140001037] 7506                         jne               000000014000103F
  [0000000140001039] 48F7D1                       not               rcx
  [000000014000103C] 4801C0                       add               rax,rax   #wrong here? may be add rax,rcx?
  [000000014000103F] 4989C0                       mov               r8,rax
  [0000000140001042] 488D0DC7940000               lea               rcx,[000000014000A510]
  [0000000140001049] 488D542422                   lea               rdx,[rsp+22]
  [000000014000104E] E87D000000                   call              00000001400010D0

From Help file:
Intrinsic functions are generated as inline code. The C runtime functions in the first table are all enabled when optimizing for speed (/Ot option), and some when optimizing for size (/Os option). Individual functions can always be enabled through #pragma intrinsic and disabled through #pragma function.

The following C runtime functions have an intrinsic form:
Name       X86    X64
......
strnlen_s  no      yes
......



Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: strnlen_s bug with /Ot option
« Reply #1 on: December 23, 2020, 05:03:47 PM »
Yes, you are absolutely correct. Thanks for the detailed analysis.
This will be fixed in the next version.
/Pelle

Offline ntprc

  • Member
  • *
  • Posts: 2
Re: strnlen_s bug with /Ot option
« Reply #2 on: December 25, 2020, 04:01:21 PM »
Same problem with wcsnlen_s.
You may already know that.  :)

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Re: strnlen_s bug with /Ot option
« Reply #3 on: December 25, 2020, 06:53:00 PM »
Yes, thanks. The templates for strnlen_s() and wcsnlen_s() were conveniently located next to each other...  ;D
/Pelle