#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 */

/* Variables and functions */
int /*<<< orphan*/ die(char *, char const *);
int /*<<< orphan*/ strcpy(char *, char const *);
int strlen(char const *);
int /*<<< orphan*/ validate_map_path_piece(char const *, char const *);
void validate_map_path(const char *path) {
  if (strlen(path) >= 256) {
    die("too long: %s", path);
  }
  char copy[256];
  strcpy(copy, path);
  const char *piece = copy;
  for (char *pos = copy; *pos != '\0'; ++pos) {
    if (*pos == '/') {
      *pos = '\0';
      validate_map_path_piece(path, piece);
      piece = pos + 1;
    }
  }
  validate_map_path_piece(path, piece);
}


x86 assembly (clang, -O0):
<validate_map_path>:
push   %rbp
mov    %rsp,%rbp
sub    $0x120,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1050 <strlen@plt>
cmp    $0x100,%eax
jl     1173 <validate_map_path+0x33>
mov    -0x8(%rbp),%rsi
lea    0xe92(%rip),%rdi
call   1060 <die@plt>
lea    -0x110(%rbp),%rdi
mov    -0x8(%rbp),%rsi
call   1040 <strcpy@plt>
lea    -0x110(%rbp),%rax
mov    %rax,-0x118(%rbp)
lea    -0x110(%rbp),%rax
mov    %rax,-0x120(%rbp)
mov    -0x120(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     120d <validate_map_path+0xcd>
mov    -0x120(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
jne    11f1 <validate_map_path+0xb1>
mov    -0x120(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x8(%rbp),%rdi
mov    -0x118(%rbp),%rsi
call   1030 <validate_map_path_piece@plt>
mov    -0x120(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x118(%rbp)
jmp    11f6 <validate_map_path+0xb6>
mov    -0x120(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x120(%rbp)
jmp    119f <validate_map_path+0x5f>
mov    -0x8(%rbp),%rdi
mov    -0x118(%rbp),%rsi
call   1030 <validate_map_path_piece@plt>
add    $0x120,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<validate_map_path>:
push   %r15
push   %r14
push   %rbx
sub    $0x100,%rsp
mov    %rdi,%r14
call   1050 <strlen@plt>
cmp    $0x100,%eax
jl     116a <validate_map_path+0x2a>
lea    0xe9e(%rip),%rdi
mov    %r14,%rsi
call   1060 <die@plt>
mov    %rsp,%r15
mov    %r15,%rdi
mov    %r14,%rsi
call   1040 <strcpy@plt>
lea    0x1(%rsp),%rbx
jmp    1196 <validate_map_path+0x56>
nop
movb   $0x0,-0x1(%rbx)
mov    %r14,%rdi
mov    %r15,%rsi
call   1030 <validate_map_path_piece@plt>
mov    %rbx,%r15
add    $0x1,%rbx
movzbl -0x1(%rbx),%eax
cmp    $0x2f,%al
je     1180 <validate_map_path+0x40>
test   %al,%al
jne    1192 <validate_map_path+0x52>
mov    %r14,%rdi
mov    %r15,%rsi
call   1030 <validate_map_path_piece@plt>
add    $0x100,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@.str = [13 x i8] c"too long: %s\00"
define void @validate_map_path(i8* %0) {
%2 = alloca i8*
%3 = alloca [256 x i8]
%4 = alloca i8*
%5 = alloca i8*
store i8* %0, i8** %2
%6 = load i8*, i8** %2
%7 = call i32 @strlen(i8* %6)
%8 = icmp sge i32 %7, 256
br i1 %8, label %9, label %12
9: ; preds = %1
%10 = load i8*, i8** %2
%11 = call i32 @die(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* %10)
br label %12
12: ; preds = %9, %1
%13 = getelementptr inbounds [256 x i8], [256 x i8]* %3, i64 0, i64 0
%14 = load i8*, i8** %2
%15 = call i32 @strcpy(i8* %13, i8* %14)
%16 = getelementptr inbounds [256 x i8], [256 x i8]* %3, i64 0, i64 0
store i8* %16, i8** %4
%17 = getelementptr inbounds [256 x i8], [256 x i8]* %3, i64 0, i64 0
store i8* %17, i8** %5
br label %18
18: ; preds = %36, %12
%19 = load i8*, i8** %5
%20 = load i8, i8* %19
%21 = sext i8 %20 to i32
%22 = icmp ne i32 %21, 0
br i1 %22, label %23, label %39
23: ; preds = %18
%24 = load i8*, i8** %5
%25 = load i8, i8* %24
%26 = sext i8 %25 to i32
%27 = icmp eq i32 %26, 47
br i1 %27, label %28, label %35
28: ; preds = %23
%29 = load i8*, i8** %5
store i8 0, i8* %29
%30 = load i8*, i8** %2
%31 = load i8*, i8** %4
%32 = call i32 @validate_map_path_piece(i8* %30, i8* %31)
%33 = load i8*, i8** %5
%34 = getelementptr inbounds i8, i8* %33, i64 1
store i8* %34, i8** %4
br label %35
35: ; preds = %28, %23
br label %36
36: ; preds = %35
%37 = load i8*, i8** %5
%38 = getelementptr inbounds i8, i8* %37, i32 1
store i8* %38, i8** %5
br label %18
39: ; preds = %18
%40 = load i8*, i8** %2
%41 = load i8*, i8** %4
%42 = call i32 @validate_map_path_piece(i8* %40, i8* %41)
ret void
}

LLVM IR (-O2):
@.str = [13 x i8] c"too long: %s\00"
define void @validate_map_path(i8* %0) {
%2 = alloca [256 x i8]
%3 = tail call i32 @strlen(i8* %0)
%4 = icmp sgt i32 %3, 255
br i1 %4, label %5, label %7
5: ; preds = %1
%6 = tail call i32 @die(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i64 0, i64 0), i8* %0)
br label %7
7: ; preds = %5, %1
%8 = getelementptr inbounds [256 x i8], [256 x i8]* %2, i64 0, i64 0
%9 = call i32 @strcpy(i8* %8, i8* %0)
br label %10
10: ; preds = %19, %7
%11 = phi i8* [ %8, %7 ], [ %20, %19 ]
%12 = phi i8* [ %8, %7 ], [ %21, %19 ]
%13 = load i8, i8* %12
switch i8 %13, label %19 [
i8 0, label %14
i8 47, label %16
]
14: ; preds = %10
%15 = call i32 @validate_map_path_piece(i8* %0, i8* %11)
ret void
16: ; preds = %10
store i8 0, i8* %12
%17 = call i32 @validate_map_path_piece(i8* %0, i8* %11)
%18 = getelementptr inbounds i8, i8* %12, i64 1
br label %19
19: ; preds = %10, %16
%20 = phi i8* [ %18, %16 ], [ %11, %10 ]
%21 = getelementptr inbounds i8, i8* %12, i64 1
br label %10
}