Skip to content

GCC and attribute non_null #50

@th-otto

Description

@th-otto

Since quite some time, some functions like strlen() are declared as only allowing non-null arguments (either explicitly, or if their prototype matches the _builtin version).

The library function should imho nevertheless check the argument, since it might be referenced by code compiled by older gcc versions. Since newer gcc complain about such checks,i've disabled the warning about this some time ago.

However, it seems that the check is nevertheless removed from the code.An example for strlen:

size_t
strlen(const char *scan)
{
	register const char *start = scan+1;

	if (!scan) return 0;
	while (*scan++ != '\0')
		continue;
	return (size_t)((long)scan - (long)start);
}

produces:

[00000000] 206f 0004                 movea.l    4(a7),a0
[00000004] 5288                      addq.l     #1,a0
[00000006] 2008                      move.l     a0,d0
.L2:
[00000008] 4a28 ffff                 tst.b      -1(a0)
[0000000c] 6606                      bne.s      .L7
[0000000e] 91c0                      suba.l     d0,a0
[00000010] 2008                      move.l     a0,d0
[00000012] 4e75                      rts
.L7:
[00000014] 5288                      addq.l     #1,a0
[00000016] 60f0                      bra.s      .L2

I can't see any check for NULL there. Any idea how to solve that?
BTW, gcc-4 also seems to remove the check, just does not emit any warning.

BTW2, that code above (produced by gcc 7 and above) doesn't look very optimal. The version produced by gcc4 looks like this:

strlen:
[00000000] 206f 0004                 movea.l    4(a7),a0
[00000004] 2008                      move.l     a0,d0
[00000006] 5280                      addq.l     #1,d0
.L2:
[00000008] 4a18                      tst.b      (a0)+
[0000000a] 66fc                      bne.s      .L2
[0000000c] 91c0                      suba.l     d0,a0
[0000000e] 2008                      move.l     a0,d0
[00000010] 4e75                      rts

That is actually quite close to how you would IMHO code it directly in assembler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions