#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct stat {
  int /*<<< orphan*/ st_mode;
};
typedef size_t ssize_t;
typedef int /*<<< orphan*/ readlink_buffer;

/* Variables and functions */
scalar_t__ ENOENT;
scalar_t__ ENOTDIR;
int /*<<< orphan*/ PATH_MAX;
int /*<<< orphan*/ S_ISDIR(int /*<<< orphan*/);
scalar_t__ S_ISLNK(int /*<<< orphan*/);
int /*<<< orphan*/ append_path_component(char *, char const *, size_t);
scalar_t__ errno;
scalar_t__ lstat(char *, struct stat *);
size_t readlink(char *, char *, int);
int /*<<< orphan*/ realpath_recurse(char *, char *, int);
char *remove_last_path_component(char *);
char *process_path_component(const char *component, size_t component_length,
                             char *resolved_name, int last_part,
                             int max_depth) {
  char readlink_buffer[PATH_MAX + 1];
  ssize_t readlink_buffer_length;
  struct stat stat_buffer;
  if (!component_length) {
    if (last_part)
      return resolved_name;
    else {
      errno = ENOENT;
      return NULL;
    }
  }
  if (component_length == 1 && component[0] == '.')
    return resolved_name;
  if (component_length == 2 && component[0] == '.' && component[1] == '.')
    return remove_last_path_component(resolved_name);
  if (!append_path_component(resolved_name, component, component_length))
    return NULL;
  if (lstat(resolved_name, &stat_buffer) < 0) {
    if (last_part && errno == ENOENT)
      return resolved_name;
    else
      return NULL;
  }
  if (S_ISLNK(stat_buffer.st_mode)) {
    readlink_buffer_length =
        readlink(resolved_name, readlink_buffer, sizeof(readlink_buffer) - 1);
    if (readlink_buffer_length < 0)
      return NULL;
    readlink_buffer[readlink_buffer_length] = 0;
    remove_last_path_component(resolved_name);
    if (!realpath_recurse(readlink_buffer, resolved_name, max_depth - 1))
      return NULL;
    if (lstat(resolved_name, &stat_buffer) < 0) {
      if (last_part && errno == ENOENT)
        return resolved_name;
      else
        return NULL;
    }
  }
  if (!last_part && !S_ISDIR(stat_buffer.st_mode)) {
    errno = ENOTDIR;
    return NULL;
  }
  return resolved_name;
}


x86 assembly (clang, -O0):
<process_path_component>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    %r8d,-0x28(%rbp)
mov    0x2e56(%rip),%rax
mov    (%rax),%eax
add    $0x1,%eax
mov    %rax,-0x60(%rbp)
mov    %rsp,%rcx
mov    %rcx,-0x30(%rbp)
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x58(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    120f <process_path_component+0x9f>
cmpl   $0x0,-0x24(%rbp)
je     11e7 <process_path_component+0x77>
mov    -0x20(%rbp),%rax
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    0x2dd2(%rip),%rax
mov    (%rax),%rcx
mov    0x2dd8(%rip),%rax
mov    %rcx,(%rax)
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
cmpq   $0x1,-0x18(%rbp)
jne    123e <process_path_component+0xce>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    123e <process_path_component+0xce>
mov    -0x20(%rbp),%rax
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
cmpq   $0x2,-0x18(%rbp)
jne    1283 <process_path_component+0x113>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    1283 <process_path_component+0x113>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x2e,%eax
jne    1283 <process_path_component+0x113>
mov    -0x20(%rbp),%rdi
call   1070 <remove_last_path_component@plt>
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    -0x20(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1080 <append_path_component@plt>
cmp    $0x0,%eax
jne    12b1 <process_path_component+0x141>
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    -0x20(%rbp),%rdi
lea    -0x48(%rbp),%rsi
call   1090 <lstat@plt>
cmp    $0x0,%rax
jge    1314 <process_path_component+0x1a4>
cmpl   $0x0,-0x24(%rbp)
je     1300 <process_path_component+0x190>
mov    0x2cf7(%rip),%rax
mov    (%rax),%rax
mov    0x2cdd(%rip),%rcx
cmp    (%rcx),%rax
jne    1300 <process_path_component+0x190>
mov    -0x20(%rbp),%rax
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    -0x48(%rbp),%edi
call   1030 <S_ISLNK@plt>
cmp    $0x0,%rax
je     140d <process_path_component+0x29d>
mov    -0x58(%rbp),%rsi
mov    -0x60(%rbp),%rax
mov    -0x20(%rbp),%rdi
sub    $0x1,%rax
mov    %eax,%edx
call   1040 <readlink@plt>
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x40(%rbp)
jae    1360 <process_path_component+0x1f0>
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    -0x58(%rbp),%rax
mov    -0x40(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x20(%rbp),%rdi
call   1070 <remove_last_path_component@plt>
mov    -0x58(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%edx
sub    $0x1,%edx
call   1050 <realpath_recurse@plt>
cmp    $0x0,%eax
jne    13a5 <process_path_component+0x235>
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    -0x20(%rbp),%rdi
lea    -0x48(%rbp),%rsi
call   1090 <lstat@plt>
cmp    $0x0,%rax
jge    1408 <process_path_component+0x298>
cmpl   $0x0,-0x24(%rbp)
je     13f4 <process_path_component+0x284>
mov    0x2c03(%rip),%rax
mov    (%rax),%rax
mov    0x2be9(%rip),%rcx
cmp    (%rcx),%rax
jne    13f4 <process_path_component+0x284>
mov    -0x20(%rbp),%rax
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
jmp    140d <process_path_component+0x29d>
cmpl   $0x0,-0x24(%rbp)
jne    1450 <process_path_component+0x2e0>
mov    -0x48(%rbp),%edi
call   1060 <S_ISDIR@plt>
cmp    $0x0,%eax
jne    1450 <process_path_component+0x2e0>
mov    0x2bc9(%rip),%rax
mov    (%rax),%rcx
mov    0x2b97(%rip),%rax
mov    %rcx,(%rax)
movq   $0x0,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
jmp    145f <process_path_component+0x2ef>
mov    -0x20(%rbp),%rax
mov    %rax,-0x8(%rbp)
movl   $0x1,-0x4c(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,%rsp
mov    -0x8(%rbp),%rax
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<process_path_component>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %r8d,%r15d
mov    %ecx,%r14d
mov    %rdx,%r12
mov    %rsi,%rdx
mov    %rdi,%rsi
mov    0x2e54(%rip),%rax
mov    (%rax),%r13d
lea    0x1(%r13),%eax
mov    %rsp,%rbx
add    $0xf,%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%rbx
mov    %rbx,%rsp
cmp    $0x2,%rdx
je     11df <process_path_component+0x6f>
cmp    $0x1,%rdx
je     1200 <process_path_component+0x90>
test   %rdx,%rdx
jne    1209 <process_path_component+0x99>
test   %r14d,%r14d
jne    12b3 <process_path_component+0x143>
mov    0x2df3(%rip),%rax
mov    (%rax),%rax
mov    0x2df9(%rip),%rcx
mov    %rax,(%rcx)
jmp    12b0 <process_path_component+0x140>
cmpb   $0x2e,(%rsi)
jne    1209 <process_path_component+0x99>
cmpb   $0x2e,0x1(%rsi)
jne    1209 <process_path_component+0x99>
mov    %r12,%rdi
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1070 <remove_last_path_component@plt>
cmpb   $0x2e,(%rsi)
je     12b3 <process_path_component+0x143>
mov    %r12,%rdi
call   1080 <append_path_component@plt>
test   %eax,%eax
je     12b0 <process_path_component+0x140>
lea    -0x30(%rbp),%rsi
mov    %r12,%rdi
call   1090 <lstat@plt>
test   %rax,%rax
js     1295 <process_path_component+0x125>
mov    -0x30(%rbp),%edi
call   1030 <S_ISLNK@plt>
test   %rax,%rax
je     1278 <process_path_component+0x108>
mov    %r12,%rdi
mov    %rbx,%rsi
mov    %r13d,%edx
call   1040 <readlink@plt>
movb   $0x0,(%rbx,%rax,1)
mov    %r12,%rdi
call   1070 <remove_last_path_component@plt>
add    $0xffffffff,%r15d
mov    %rbx,%rdi
mov    %r12,%rsi
mov    %r15d,%edx
call   1050 <realpath_recurse@plt>
test   %eax,%eax
je     12b0 <process_path_component+0x140>
lea    -0x30(%rbp),%rsi
mov    %r12,%rdi
call   1090 <lstat@plt>
test   %rax,%rax
js     1295 <process_path_component+0x125>
test   %r14d,%r14d
jne    12b3 <process_path_component+0x143>
mov    -0x30(%rbp),%edi
call   1060 <S_ISDIR@plt>
test   %eax,%eax
jne    12b3 <process_path_component+0x143>
mov    0x2d68(%rip),%rax
jmp    11cd <process_path_component+0x5d>
test   %r14d,%r14d
je     12b0 <process_path_component+0x140>
mov    0x2d2f(%rip),%rax
mov    (%rax),%rax
mov    0x2d15(%rip),%rcx
cmp    (%rcx),%rax
je     12b3 <process_path_component+0x143>
xor    %r12d,%r12d
mov    %r12,%rax
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
%struct.stat = type { i32 }
@PATH_MAX = global i32 0
@ENOENT = global i64 0
@errno = global i64 0
@ENOTDIR = global i64 0
define i8* @process_path_component(i8* %0, i64 %1, i8* %2, i32 %3, i32 %4) {
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i64
%9 = alloca i8*
%10 = alloca i32
%11 = alloca i32
%12 = alloca i8*
%13 = alloca i64
%14 = alloca i64
%15 = alloca %struct.stat
%16 = alloca i32
store i8* %0, i8** %7
store i64 %1, i64* %8
store i8* %2, i8** %9
store i32 %3, i32* %10
store i32 %4, i32* %11
%17 = load i32, i32* @PATH_MAX
%18 = add nsw i32 %17, 1
%19 = zext i32 %18 to i64
%20 = call i8* @llvm.stacksave()
store i8* %20, i8** %12
%21 = alloca i8, i64 %19
store i64 %19, i64* %13
%22 = load i64, i64* %8
%23 = icmp ne i64 %22, 0
br i1 %23, label %31, label %24
24: ; preds = %5
%25 = load i32, i32* %10
%26 = icmp ne i32 %25, 0
br i1 %26, label %27, label %29
27: ; preds = %24
%28 = load i8*, i8** %9
store i8* %28, i8** %6
store i32 1, i32* %16
br label %132
29: ; preds = %24
%30 = load i64, i64* @ENOENT
store i64 %30, i64* @errno
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
31: ; preds = %5
%32 = load i64, i64* %8
%33 = icmp eq i64 %32, 1
br i1 %33, label %34, label %42
34: ; preds = %31
%35 = load i8*, i8** %7
%36 = getelementptr inbounds i8, i8* %35, i64 0
%37 = load i8, i8* %36
%38 = sext i8 %37 to i32
%39 = icmp eq i32 %38, 46
br i1 %39, label %40, label %42
40: ; preds = %34
%41 = load i8*, i8** %9
store i8* %41, i8** %6
store i32 1, i32* %16
br label %132
42: ; preds = %34, %31
%43 = load i64, i64* %8
%44 = icmp eq i64 %43, 2
br i1 %44, label %45, label %60
45: ; preds = %42
%46 = load i8*, i8** %7
%47 = getelementptr inbounds i8, i8* %46, i64 0
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = icmp eq i32 %49, 46
br i1 %50, label %51, label %60
51: ; preds = %45
%52 = load i8*, i8** %7
%53 = getelementptr inbounds i8, i8* %52, i64 1
%54 = load i8, i8* %53
%55 = sext i8 %54 to i32
%56 = icmp eq i32 %55, 46
br i1 %56, label %57, label %60
57: ; preds = %51
%58 = load i8*, i8** %9
%59 = call i8* @remove_last_path_component(i8* %58)
store i8* %59, i8** %6
store i32 1, i32* %16
br label %132
60: ; preds = %51, %45, %42
%61 = load i8*, i8** %9
%62 = load i8*, i8** %7
%63 = load i64, i64* %8
%64 = call i32 @append_path_component(i8* %61, i8* %62, i64 %63)
%65 = icmp ne i32 %64, 0
br i1 %65, label %67, label %66
66: ; preds = %60
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
67: ; preds = %60
%68 = load i8*, i8** %9
%69 = call i64 @lstat(i8* %68, %struct.stat* %15)
%70 = icmp slt i64 %69, 0
br i1 %70, label %71, label %81
71: ; preds = %67
%72 = load i32, i32* %10
%73 = icmp ne i32 %72, 0
br i1 %73, label %74, label %80
74: ; preds = %71
%75 = load i64, i64* @errno
%76 = load i64, i64* @ENOENT
%77 = icmp eq i64 %75, %76
br i1 %77, label %78, label %80
78: ; preds = %74
%79 = load i8*, i8** %9
store i8* %79, i8** %6
store i32 1, i32* %16
br label %132
80: ; preds = %74, %71
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
81: ; preds = %67
%82 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%83 = load i32, i32* %82
%84 = call i64 @S_ISLNK(i32 %83)
%85 = icmp ne i64 %84, 0
br i1 %85, label %86, label %120
86: ; preds = %81
%87 = load i8*, i8** %9
%88 = sub i64 %19, 1
%89 = trunc i64 %88 to i32
%90 = call i64 @readlink(i8* %87, i8* %21, i32 %89)
store i64 %90, i64* %14
%91 = load i64, i64* %14
%92 = icmp ult i64 %91, 0
br i1 %92, label %93, label %94
93: ; preds = %86
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
94: ; preds = %86
%95 = load i64, i64* %14
%96 = getelementptr inbounds i8, i8* %21, i64 %95
store i8 0, i8* %96
%97 = load i8*, i8** %9
%98 = call i8* @remove_last_path_component(i8* %97)
%99 = load i8*, i8** %9
%100 = load i32, i32* %11
%101 = sub nsw i32 %100, 1
%102 = call i32 @realpath_recurse(i8* %21, i8* %99, i32 %101)
%103 = icmp ne i32 %102, 0
br i1 %103, label %105, label %104
104: ; preds = %94
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
105: ; preds = %94
%106 = load i8*, i8** %9
%107 = call i64 @lstat(i8* %106, %struct.stat* %15)
%108 = icmp slt i64 %107, 0
br i1 %108, label %109, label %119
109: ; preds = %105
%110 = load i32, i32* %10
%111 = icmp ne i32 %110, 0
br i1 %111, label %112, label %118
112: ; preds = %109
%113 = load i64, i64* @errno
%114 = load i64, i64* @ENOENT
%115 = icmp eq i64 %113, %114
br i1 %115, label %116, label %118
116: ; preds = %112
%117 = load i8*, i8** %9
store i8* %117, i8** %6
store i32 1, i32* %16
br label %132
118: ; preds = %112, %109
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
119: ; preds = %105
br label %120
120: ; preds = %119, %81
%121 = load i32, i32* %10
%122 = icmp ne i32 %121, 0
br i1 %122, label %130, label %123
123: ; preds = %120
%124 = getelementptr inbounds %struct.stat, %struct.stat* %15, i32 0, i32 0
%125 = load i32, i32* %124
%126 = call i32 @S_ISDIR(i32 %125)
%127 = icmp ne i32 %126, 0
br i1 %127, label %130, label %128
128: ; preds = %123
%129 = load i64, i64* @ENOTDIR
store i64 %129, i64* @errno
store i8* null, i8** %6
store i32 1, i32* %16
br label %132
130: ; preds = %123, %120
%131 = load i8*, i8** %9
store i8* %131, i8** %6
store i32 1, i32* %16
br label %132
132: ; preds = %130, %128, %118, %116, %104, %93, %80, %78, %66, %57, %40, %29, %27
%133 = load i8*, i8** %12
%134 = load i8*, i8** %6
ret i8* %134
}

LLVM IR (-O2):
%struct.stat = type { i32 }
@PATH_MAX = global i32 0
@ENOENT = global i64 0
@errno = global i64 0
@ENOTDIR = global i64 0
define i8* @process_path_component(i8* %0, i64 %1, i8* %2, i32 %3, i32 %4) {
%6 = alloca %struct.stat
%7 = load i32, i32* @PATH_MAX
%8 = add nsw i32 %7, 1
%9 = zext i32 %8 to i64
%10 = alloca i8, i64 %9
%11 = bitcast %struct.stat* %6 to i8*
switch i64 %1, label %28 [
i64 0, label %12
i64 1, label %16
i64 2, label %19
]
12: ; preds = %5
%13 = icmp eq i32 %3, 0
br i1 %13, label %14, label %71
14: ; preds = %12
%15 = load i64, i64* @ENOENT
store i64 %15, i64* @errno
br label %71
16: ; preds = %5
%17 = load i8, i8* %0
%18 = icmp eq i8 %17, 46
br i1 %18, label %71, label %28
19: ; preds = %5
%20 = load i8, i8* %0
%21 = icmp eq i8 %20, 46
br i1 %21, label %22, label %28
22: ; preds = %19
%23 = getelementptr inbounds i8, i8* %0, i64 1
%24 = load i8, i8* %23
%25 = icmp eq i8 %24, 46
br i1 %25, label %26, label %28
26: ; preds = %22
%27 = tail call i8* @remove_last_path_component(i8* %2)
br label %71
28: ; preds = %16, %5, %22, %19
%29 = tail call i32 @append_path_component(i8* %2, i8* %0, i64 %1)
%30 = icmp eq i32 %29, 0
br i1 %30, label %71, label %31
31: ; preds = %28
%32 = call i64 @lstat(i8* %2, %struct.stat* %6)
%33 = icmp slt i64 %32, 0
br i1 %33, label %34, label %41
34: ; preds = %31
%35 = icmp eq i32 %3, 0
br i1 %35, label %40, label %36
36: ; preds = %34
%37 = load i64, i64* @errno
%38 = load i64, i64* @ENOENT
%39 = icmp eq i64 %37, %38
br i1 %39, label %71, label %40
40: ; preds = %36, %34
br label %71
41: ; preds = %31
%42 = getelementptr inbounds %struct.stat, %struct.stat* %6, i64 0, i32 0
%43 = load i32, i32* %42
%44 = tail call i64 @S_ISLNK(i32 %43)
%45 = icmp eq i64 %44, 0
br i1 %45, label %63, label %46
46: ; preds = %41
%47 = call i64 @readlink(i8* %2, i8* %10, i32 %7)
%48 = getelementptr inbounds i8, i8* %10, i64 %47
store i8 0, i8* %48
%49 = tail call i8* @remove_last_path_component(i8* %2)
%50 = add nsw i32 %4, -1
%51 = call i32 @realpath_recurse(i8* %10, i8* %2, i32 %50)
%52 = icmp eq i32 %51, 0
br i1 %52, label %71, label %53
53: ; preds = %46
%54 = call i64 @lstat(i8* %2, %struct.stat* %6)
%55 = icmp slt i64 %54, 0
br i1 %55, label %56, label %63
56: ; preds = %53
%57 = icmp eq i32 %3, 0
br i1 %57, label %62, label %58
58: ; preds = %56
%59 = load i64, i64* @errno
%60 = load i64, i64* @ENOENT
%61 = icmp eq i64 %59, %60
br i1 %61, label %71, label %62
62: ; preds = %58, %56
br label %71
63: ; preds = %53, %41
%64 = icmp eq i32 %3, 0
br i1 %64, label %65, label %71
65: ; preds = %63
%66 = load i32, i32* %42
%67 = call i32 @S_ISDIR(i32 %66)
%68 = icmp eq i32 %67, 0
br i1 %68, label %69, label %71
69: ; preds = %65
%70 = load i64, i64* @ENOTDIR
store i64 %70, i64* @errno
br label %71
71: ; preds = %63, %65, %58, %46, %36, %28, %16, %12, %69, %62, %40, %26, %14
%72 = phi i8* [ %27, %26 ], [ null, %40 ], [ null, %62 ], [ null, %69 ], [ null, %14 ], [ %2, %12 ], [ %2, %16 ], [ null, %28 ], [ %2, %36 ], [ null, %46 ], [ %2, %58 ], [ %2, %65 ], [ %2, %63 ]
ret i8* %72
}