42 changes: 4 additions & 38 deletions clang/test/Driver/loongarch-msimd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,128 +2,94 @@

/// COM: -msimd=none
// RUN: %clang --target=loongarch64 -mlasx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX
// RUN: %clang --target=loongarch64 -mlasx -mlsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX

// RUN: %clang --target=loongarch64 -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mlsx -mno-lsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mno-lsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mlsx -mno-lsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -mno-lsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mno-lsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX

// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mlsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mlsx -msimd=none -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX


/// COM: -msimd=lsx
// RUN: %clang --target=loongarch64 -mlasx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX
// RUN: %clang --target=loongarch64 -mlasx -mlsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX

// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mno-lsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mlsx -mno-lsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -mno-lsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mno-lsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mlsx -mno-lsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX

// RUN: %clang --target=loongarch64 -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mlsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX


/// COM: -msimd=lasx
// RUN: %clang --target=loongarch64 -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX
// RUN: %clang --target=loongarch64 -mlasx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX
// RUN: %clang --target=loongarch64 -mlasx -mlsx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX
// RUN: %clang --target=loongarch64 -mlsx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,LASX

// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=NOLSX,NOLASX

// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mlsx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -msimd=lasx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX
// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -mlsx -msimd=lsx -fsyntax-only %s -### 2>&1 | \
// RUN: grep -o '"-target-feature" "+[[:alnum:]]\+"' | sort -r | \
// RUN: FileCheck %s --check-prefixes=LSX,NOLASX


// LSX: "-target-feature" "+lsx"
// LASX: "-target-feature" "+lasx"
// NOLSX-NOT: "-target-feature" "+lsx"
// NOLASX-NOT: "-target-feature" "+lasx"
// LSX-DAG: "-target-feature" "+lsx"
// LASX-DAG: "-target-feature" "+lasx"
// NOLSX-NOT: "-target-feature" "+lsx"
// NOLASX-NOT: "-target-feature" "+lasx"
1 change: 1 addition & 0 deletions clang/test/Driver/print-supported-extensions-riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
// CHECK-NEXT: xtheadsync 1.0 'xtheadsync' (T-Head multicore synchronization instructions)
// CHECK-NEXT: xtheadvdot 1.0 'xtheadvdot' (T-Head Vector Extensions for Dot)
// CHECK-NEXT: xventanacondops 1.0 'XVentanaCondOps' (Ventana Conditional Ops)
// CHECK-NEXT: xwchc 2.2 'Xwchc' (WCH/QingKe additional compressed opcodes)
// CHECK-EMPTY:
// CHECK-NEXT: Experimental extensions
// CHECK-NEXT: zicfilp 0.4 'Zicfilp' (Landing pad)
Expand Down
25 changes: 25 additions & 0 deletions clang/test/Driver/sanitizer-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@
// RUN: -static-libsan \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-ANDROID-STATICLIBASAN %s
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: -static-libasan \
// RUN: | FileCheck --check-prefix=CHECK-ASAN-ANDROID-STATICLIBASAN %s
//
// CHECK-ASAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld.lld{{(.exe)?}}"
// CHECK-ASAN-ANDROID-STATICLIBASAN: libclang_rt.asan.a"
// CHECK-ASAN-ANDROID-STATICLIBASAN-NOT: "-lpthread"
Expand Down Expand Up @@ -639,6 +646,24 @@
// CHECK-NSAN-LINUX: libclang_rt.nsan.a"
// CHECK-NSAN-LINUX: "-lpthread" "-lrt" "-lm" "-ldl" "-lresolv"

// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fuse-ld=ld -fsanitize=numerical -shared-libsan \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-NSAN-SHARED-LINUX %s

// CHECK-NSAN-SHARED-LINUX: libclang_rt.nsan.so"
// CHECK-NSAN-SHARED-LINUX-NOT: "-lpthread"
// CHECK-NSAN-SHARED-LINUX-NOT: "-ldl"
// CHECK-NSAN-SHARED-LINUX-NOT: "--dynamic-list

// RUN: %clang -### %s 2>&1 --target=x86_64-unknown-linux -fsanitize=numerical,undefined \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-NSAN-UBSAN %s

// CHECK-NSAN-UBSAN: "--whole-archive" "{{[^"]*}}libclang_rt.nsan.a" "--no-whole-archive"
// CHECK-NSAN-UBSAN-NOT: libclang_rt.ubsan

// CFI by itself does not link runtime libraries.
// RUN: not %clang -fsanitize=cfi -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -fuse-ld=ld -rtlib=platform \
Expand Down
3 changes: 3 additions & 0 deletions clang/test/Frontend/module-file-info-not-a-module.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// RUN: not %clang_cc1 -module-file-info %s 2>&1 | FileCheck %s

// CHECK: fatal error: file '{{.*}}module-file-info-not-a-module.c' is not a module file
26 changes: 25 additions & 1 deletion clang/test/Headers/float.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
// expected-no-diagnostics

/* Basic floating point conformance checks against:
- C23 Final Std.
- N1570 draft of C11 Std.
- N1256 draft of C99 Std.
- http://port70.net/~nsz/c/c89/c89-draft.html draft of C89/C90 Std.
*/
/*
C23, 5.2.5.3.3p21, pp. 25
C11, 5.2.4.2.2p11, pp. 30
C99, 5.2.4.2.2p9, pp. 25
C89, 2.2.4.2
Expand Down Expand Up @@ -225,6 +227,22 @@
_Static_assert(_Generic(INFINITY, float : 1, default : 0), ""); // finite-warning {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}}
_Static_assert(_Generic(NAN, float : 1, default : 0), ""); // finite-warning {{use of NaN is undefined behavior due to the currently enabled floating-point options}} \
finite-warning {{use of NaN via a macro is undefined behavior due to the currently enabled floating-point options}}

#ifndef FLT_NORM_MAX
#error "Mandatory macro FLT_NORM_MAX is missing."
#else
_Static_assert(FLT_NORM_MAX >= 1.0E+37F, "Mandatory macro FLT_NORM_MAX is invalid.");
#endif
#ifndef DBL_NORM_MAX
#error "Mandatory macro DBL_NORM_MAX is missing."
#else
_Static_assert(DBL_NORM_MAX >= 1.0E+37, "Mandatory macro DBL_NORM_MAX is invalid.");
#endif
#ifndef LDBL_NORM_MAX
#error "Mandatory macro LDBL_NORM_MAX is missing."
#else
_Static_assert(LDBL_NORM_MAX >= 1.0E+37L, "Mandatory macro LDBL_NORM_MAX is invalid.");
#endif
#else
#ifdef INFINITY
#error "Macro INFINITY should not be defined."
Expand Down Expand Up @@ -271,8 +289,14 @@ _Static_assert(FLT_MAX_10_EXP == __FLT_MAX_10_EXP__, "");
_Static_assert(DBL_MAX_10_EXP == __DBL_MAX_10_EXP__, "");
_Static_assert(LDBL_MAX_10_EXP == __LDBL_MAX_10_EXP__, "");

#if (__STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)) && __FINITE_MATH_ONLY__ == 0
#if __STDC_VERSION__ >= 202311L || !defined(__STRICT_ANSI__)
_Static_assert(FLT_NORM_MAX == __FLT_NORM_MAX__, "");
_Static_assert(DBL_NORM_MAX == __DBL_NORM_MAX__, "");
_Static_assert(LDBL_NORM_MAX == __LDBL_NORM_MAX__, "");

#if __FINITE_MATH_ONLY__ == 0
// Ensure INFINITY and NAN are suitable for use in a constant expression.
float f1 = INFINITY;
float f2 = NAN;
#endif
#endif
304 changes: 304 additions & 0 deletions clang/test/InstallAPI/reexport-with-linker-symbols.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
; RUN: rm -rf %t
; RUN: split-file %s %t

; RUN: yaml2obj %t/umbrella.yaml -o %t/System/Library/Frameworks/Umbrella.framework/Umbrella

; RUN: clang-installapi -target arm64-apple-macosx14 -install_name \
; RUN: /System/Library/Frameworks/Umbrella.framework/Versions/A/Umbrella \
; RUN: --verify-against=%t/System/Library/Frameworks/Umbrella.framework/Umbrella \
; RUN: -L%t/usr/lib -F%t/System/Library/Frameworks \
; RUN: %t/System/Library/Frameworks/Umbrella.framework --verify-mode=Pedantic -reexport-lBar \
; RUN: -o %t/Umbrella.tbd 2>&1 | FileCheck -allow-empty %s
; RUN: llvm-readtapi -compare %t/Umbrella.tbd %t/expected.tbd 2>&1 | FileCheck -allow-empty %s

; CHECK-NOT: error
; CHECK-NOT: warning

;--- System/Library/Frameworks/Umbrella.framework/Headers/Umbrella.h
extern const char ld_previous __asm("$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$");
extern void function();

;--- umbrella.yaml
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x100000C
cpusubtype: 0x0
filetype: 0x6
ncmds: 16
sizeofcmds: 856
flags: 0x85
reserved: 0x0
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 312
segname: __TEXT
vmaddr: 0
vmsize: 16384
fileoff: 0
filesize: 16384
maxprot: 5
initprot: 5
nsects: 3
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x3FB0
size: 4
offset: 0x3FB0
align: 2
reloff: 0x0
nreloc: 0
flags: 0x80000400
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: C0035FD6
- sectname: __const
segname: __TEXT
addr: 0x3FB4
size: 1
offset: 0x3FB4
align: 0
reloff: 0x0
nreloc: 0
flags: 0x0
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: '00'
- sectname: __unwind_info
segname: __TEXT
addr: 0x3FB8
size: 72
offset: 0x3FB8
align: 2
reloff: 0x0
nreloc: 0
flags: 0x0
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: 010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B53F00000000000034000000030000000C000100100001000000000000000002
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __LINKEDIT
vmaddr: 16384
vmsize: 16384
fileoff: 16384
filesize: 584
maxprot: 1
initprot: 1
nsects: 0
flags: 0
- cmd: LC_ID_DYLIB
cmdsize: 96
dylib:
name: 24
timestamp: 1
current_version: 0
compatibility_version: 0
Content: '/System/Library/Frameworks/Umbrella.framework/Versions/A/Umbrella'
ZeroPadBytes: 7
- cmd: LC_DYLD_CHAINED_FIXUPS
cmdsize: 16
dataoff: 16384
datasize: 48
- cmd: LC_DYLD_EXPORTS_TRIE
cmdsize: 16
dataoff: 16432
datasize: 104
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 16560
nsyms: 2
stroff: 16592
strsize: 96
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 0
iextdefsym: 0
nextdefsym: 2
iundefsym: 2
nundefsym: 0
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
- cmd: LC_UUID
cmdsize: 24
uuid: CCD7F304-D97B-3521-A980-CC936CCD34E8
- cmd: LC_BUILD_VERSION
cmdsize: 32
platform: 1
minos: 917504
sdk: 983040
ntools: 1
Tools:
- tool: 3
version: 62525440
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
- cmd: LC_SEGMENT_SPLIT_INFO
cmdsize: 16
dataoff: 16536
datasize: 16
- cmd: LC_REEXPORT_DYLIB
cmdsize: 48
dylib:
name: 24
timestamp: 2
current_version: 65536
compatibility_version: 65536
Content: '/usr/lib/libBar.dylib'
ZeroPadBytes: 3
- cmd: LC_LOAD_DYLIB
cmdsize: 56
dylib:
name: 24
timestamp: 2
current_version: 88539136
compatibility_version: 65536
Content: '/usr/lib/libSystem.B.dylib'
ZeroPadBytes: 6
- cmd: LC_FUNCTION_STARTS
cmdsize: 16
dataoff: 16552
datasize: 8
- cmd: LC_DATA_IN_CODE
cmdsize: 16
dataoff: 16560
datasize: 0
- cmd: LC_CODE_SIGNATURE
cmdsize: 16
dataoff: 16688
datasize: 280
LinkEditData:
ExportTrie:
TerminalSize: 0
NodeOffset: 0
Name: ''
Flags: 0x0
Address: 0x0
Other: 0x0
ImportName: ''
Children:
- TerminalSize: 3
NodeOffset: 94
Name: '$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$'
Flags: 0x0
Address: 0x3FB4
Other: 0x0
ImportName: ''
- TerminalSize: 3
NodeOffset: 99
Name: _function
Flags: 0x0
Address: 0x3FB0
Other: 0x0
ImportName: ''
NameList:
- n_strx: 2
n_type: 0xF
n_sect: 2
n_desc: 0
n_value: 16308
- n_strx: 82
n_type: 0xF
n_sect: 1
n_desc: 0
n_value: 16304
StringTable:
- ' '
- '$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$'
- _function
- ''
- ''
- ''
- ''
FunctionStarts: [ 0x3FB0 ]
ChainedFixups: [ 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x2C, 0x0,
0x0, 0x0, 0x2C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
...

;--- /usr/lib/libBar.dylib
{
"main_library": {
"exported_symbols": [
{
"text": {
"global": [
"$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$"
]
}
}
],
"flags": [
{
"attributes": [
"not_app_extension_safe"
]
}
],
"install_names": [
{
"name": "/usr/lib/libBar.dylib"
}
],
"target_info": [
{
"min_deployment": "13",
"target": "arm64-macos"
}
]
},
"tapi_tbd_version": 5
}

;--- expected.tbd
{
"main_library": {
"compatibility_versions": [ { "version": "0" } ],
"current_versions": [ { "version": "0" } ],
"exported_symbols": [
{
"data": {
"global": [
"$ld$previous$/usr/lib/libLdPreviousBindPrevious.1.dylib$$1$11.0$16.0$_function$"
]
},
"text": { "global": [ "_function" ] }
}
],
"flags": [
{ "attributes": [ "not_app_extension_safe" ] }
],
"install_names": [
{ "name": "/System/Library/Frameworks/Umbrella.framework/Versions/A/Umbrella" }
],
"reexported_libraries": [
{ "names": [ "/usr/lib/libBar.dylib" ] }
],
"target_info": [
{
"min_deployment": "14",
"target": "arm64-macos"
}
]
},
"tapi_tbd_version": 5
}
4 changes: 4 additions & 0 deletions clang/test/Preprocessor/init-aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
// AARCH64-NEXT: #define __DBL_MIN_10_EXP__ (-307)
// AARCH64-NEXT: #define __DBL_MIN_EXP__ (-1021)
// AARCH64-NEXT: #define __DBL_MIN__ 2.2250738585072014e-308
// AARCH64-NEXT: #define __DBL_NORM_MAX__ 1.7976931348623157e+308
// AARCH64-NEXT: #define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
// AARCH64-NEXT: #define __ELF__ 1
// AARCH64-NEXT: #define __FINITE_MATH_ONLY__ 0
Expand All @@ -91,6 +92,7 @@
// AARCH64-NEXT: #define __FLT16_MIN_10_EXP__ (-4)
// AARCH64-NEXT: #define __FLT16_MIN_EXP__ (-13)
// AARCH64-NEXT: #define __FLT16_MIN__ 6.103515625e-5F16
// AARCH64-NEXT: #define __FLT16_NORM_MAX__ 6.5504e+4F16
// AARCH64-NEXT: #define __FLT_DECIMAL_DIG__ 9
// AARCH64-NEXT: #define __FLT_DENORM_MIN__ 1.40129846e-45F
// AARCH64-NEXT: #define __FLT_DIG__ 6
Expand All @@ -105,6 +107,7 @@
// AARCH64-NEXT: #define __FLT_MIN_10_EXP__ (-37)
// AARCH64-NEXT: #define __FLT_MIN_EXP__ (-125)
// AARCH64-NEXT: #define __FLT_MIN__ 1.17549435e-38F
// AARCH64-NEXT: #define __FLT_NORM_MAX__ 3.40282347e+38F
// AARCH64-NEXT: #define __FLT_RADIX__ 2
// AARCH64-NEXT: #define __FPCLASS_NEGINF 0x0004
// AARCH64-NEXT: #define __FPCLASS_NEGNORMAL 0x0008
Expand Down Expand Up @@ -216,6 +219,7 @@
// AARCH64-NEXT: #define __LDBL_MIN_10_EXP__ (-4931)
// AARCH64-NEXT: #define __LDBL_MIN_EXP__ (-16381)
// AARCH64-NEXT: #define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
// AARCH64-NEXT: #define __LDBL_NORM_MAX__ 1.18973149535723176508575932662800702e+4932L
// AARCH64_LE-NEXT: #define __LITTLE_ENDIAN__ 1
// AARCH64-NEXT: #define __LLONG_WIDTH__ 64
// AARCH64-NEXT: #define __LONG_LONG_MAX__ 9223372036854775807LL
Expand Down
4 changes: 4 additions & 0 deletions clang/test/Preprocessor/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,7 @@
// WEBASSEMBLY-NEXT:#define __DBL_MIN_10_EXP__ (-307)
// WEBASSEMBLY-NEXT:#define __DBL_MIN_EXP__ (-1021)
// WEBASSEMBLY-NEXT:#define __DBL_MIN__ 2.2250738585072014e-308
// WEBASSEMBLY-NEXT:#define __DBL_NORM_MAX__ 1.7976931348623157e+308
// WEBASSEMBLY-NEXT:#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__
// WEBASSEMBLY-NOT:#define __ELF__
// EMSCRIPTEN-THREADS-NEXT:#define __EMSCRIPTEN_PTHREADS__ 1
Expand All @@ -1668,6 +1669,7 @@
// WEBASSEMBLY-NOT:#define __FLT16_MIN_10_EXP__
// WEBASSEMBLY-NOT:#define __FLT16_MIN_EXP__
// WEBASSEMBLY-NOT:#define __FLT16_MIN__
// WEBASSEMBLY-NOT:#define __FLT16_NORM_MAX__
// WEBASSEMBLY-NEXT:#define __FLT_DECIMAL_DIG__ 9
// WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6
Expand All @@ -1682,6 +1684,7 @@
// WEBASSEMBLY-NEXT:#define __FLT_MIN_10_EXP__ (-37)
// WEBASSEMBLY-NEXT:#define __FLT_MIN_EXP__ (-125)
// WEBASSEMBLY-NEXT:#define __FLT_MIN__ 1.17549435e-38F
// WEBASSEMBLY-NEXT:#define __FLT_NORM_MAX__ 3.40282347e+38F
// WEBASSEMBLY-NEXT:#define __FLT_RADIX__ 2
// WEBASSEMBLY-NEXT:#define __FPCLASS_NEGINF 0x0004
// WEBASSEMBLY-NEXT:#define __FPCLASS_NEGNORMAL 0x0008
Expand Down Expand Up @@ -1806,6 +1809,7 @@
// WEBASSEMBLY-NEXT:#define __LDBL_MIN_10_EXP__ (-4931)
// WEBASSEMBLY-NEXT:#define __LDBL_MIN_EXP__ (-16381)
// WEBASSEMBLY-NEXT:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
// WEBASSEMBLY-NEXT:#define __LDBL_NORM_MAX__ 1.18973149535723176508575932662800702e+4932L
// WEBASSEMBLY-NEXT:#define __LITTLE_ENDIAN__ 1
// WEBASSEMBLY-NEXT:#define __LLONG_WIDTH__ 64
// WEBASSEMBLY-NEXT:#define __LONG_LONG_MAX__ 9223372036854775807LL
Expand Down
50 changes: 12 additions & 38 deletions clang/test/Sema/arm-interrupt-attr.c
Original file line number Diff line number Diff line change
@@ -1,52 +1,26 @@
// RUN: %clang_cc1 %s -triple arm-apple-darwin -target-feature +vfp2 -verify -fsyntax-only
// RUN: %clang_cc1 %s -triple thumb-apple-darwin -target-feature +vfp3 -verify -fsyntax-only
// RUN: %clang_cc1 %s -triple armeb-none-eabi -target-feature +vfp4 -verify -fsyntax-only
// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon -verify -fsyntax-only
// RUN: %clang_cc1 %s -triple thumbeb-none-eabi -target-feature +neon -target-feature +soft-float -DSOFT -verify -fsyntax-only
// RUN: %clang_cc1 %s -triple arm-none-eabi -verify -fsyntax-only
// RUN: %clang_cc1 %s -triple arm-none-eabi -target-feature +vfp2 -verify -fsyntax-only

__attribute__((interrupt(IRQ))) void foo(void) {} // expected-error {{'interrupt' attribute requires a string}}
__attribute__((interrupt("irq"))) void foo1(void) {} // expected-warning {{'interrupt' attribute argument not supported: irq}}

#ifdef __ARM_FP
__attribute__((interrupt("IRQ"))) void float_irq(void); // expected-warning {{interrupt service routine with vfp enabled may clobber the interruptee's vfp state}}
#else // !defined(__ARM_FP)
__attribute__((interrupt("irq"))) void foo1(void) {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
__attribute__((interrupt(IRQ))) void foo(void) {} // expected-error {{'interrupt' attribute requires a string}}
__attribute__((interrupt("IRQ", 1))) void foo2(void) {} // expected-error {{'interrupt' attribute takes no more than 1 argument}}

__attribute__((interrupt("IRQ"))) void foo3(void) {}
__attribute__((interrupt("FIQ"))) void foo4(void) {}
__attribute__((interrupt("SWI"))) void foo5(void) {}
__attribute__((interrupt("ABORT"))) void foo6(void) {}
__attribute__((interrupt("UNDEF"))) void foo7(void) {}

__attribute__((interrupt)) void foo8(void) {}
__attribute__((interrupt())) void foo9(void) {}
__attribute__((interrupt(""))) void foo10(void) {}

#ifndef SOFT
// expected-note@+2 {{'callee1' declared here}}
#endif
void callee1(void);
__attribute__((interrupt("IRQ"))) void callee2(void);
void caller1(void) {
callee1();
callee2();
}

#ifndef SOFT
__attribute__((interrupt("IRQ"))) void caller2(void) {
callee1(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
callee2();
}

void (*callee3)(void);
__attribute__((interrupt("IRQ"))) void caller3(void) {
callee3(); // expected-warning {{call to function without interrupt attribute could clobber interruptee's VFP registers}}
}
#else
__attribute__((interrupt("IRQ"))) void caller2(void) {
callee1();
callee2();
}
__attribute__((interrupt("IRQ"))) void callee(void) {}

void (*callee3)(void);
__attribute__((interrupt("IRQ"))) void caller3(void) {
callee3();
void caller(void)
{
callee(); // expected-error {{interrupt service routine cannot be called directly}}
}
#endif
#endif // __ARM_FP
33 changes: 33 additions & 0 deletions clang/test/SemaCXX/pr98102.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
// expected-no-diagnostics

template <bool v>
struct BC {
static constexpr bool value = v;
};

template <typename T, typename Arg>
struct Constructible : BC<__is_constructible(T, Arg)> {};

template <typename T>
using Requires = T::value;

template <typename T>
struct optional {
template <typename U, Requires<Constructible<T, U>> = true>
optional(U) {}
};

struct MO {};
struct S : MO {};
struct TB {
TB(optional<S>) {}
};

class TD : TB, MO {
using TB::TB;
};

void foo() {
static_assert(Constructible<TD, TD>::value);
}
13 changes: 10 additions & 3 deletions clang/tools/driver/cc1_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static int PrintSupportedExtensions(std::string TargetStr) {
DescMap.insert({feature.Key, feature.Desc});

if (MachineTriple.isRISCV())
llvm::riscvExtensionsHelp(DescMap);
llvm::RISCVISAInfo::printSupportedExtensions(DescMap);
else if (MachineTriple.isAArch64())
llvm::AArch64::PrintSupportedExtensions();
else if (MachineTriple.isARM())
Expand Down Expand Up @@ -190,13 +190,20 @@ static int PrintEnabledExtensions(const TargetOptions& TargetOpts) {
for (const llvm::SubtargetFeatureKV &feature : Features)
EnabledFeatureNames.insert(feature.Key);

if (!MachineTriple.isAArch64()) {
if (MachineTriple.isAArch64())
llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);
else if (MachineTriple.isRISCV()) {
llvm::StringMap<llvm::StringRef> DescMap;
for (const llvm::SubtargetFeatureKV &feature : Features)
DescMap.insert({feature.Key, feature.Desc});
llvm::RISCVISAInfo::printEnabledExtensions(MachineTriple.isArch64Bit(),
EnabledFeatureNames, DescMap);
} else {
// The option was already checked in Driver::HandleImmediateArgs,
// so we do not expect to get here if we are not a supported architecture.
assert(0 && "Unhandled triple for --print-enabled-extensions option.");
return 1;
}
llvm::AArch64::printEnabledExtensions(EnabledFeatureNames);

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions clang/unittests/StaticAnalyzer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ add_clang_unittest(StaticAnalysisTests
CallDescriptionTest.cpp
CallEventTest.cpp
ConflictingEvalCallsTest.cpp
ExprEngineVisitTest.cpp
FalsePositiveRefutationBRVisitorTest.cpp
IsCLibraryFunctionTest.cpp
MemRegionDescriptiveNameTest.cpp
Expand Down
87 changes: 87 additions & 0 deletions clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//===- ExprEngineVisitTest.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CheckerRegistration.h"
#include "clang/AST/Stmt.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "gtest/gtest.h"

using namespace clang;
using namespace ento;

namespace {

void emitErrorReport(CheckerContext &C, const BugType &Bug,
const std::string &Desc) {
if (ExplodedNode *Node = C.generateNonFatalErrorNode(C.getState())) {
auto Report = std::make_unique<PathSensitiveBugReport>(Bug, Desc, Node);
C.emitReport(std::move(Report));
}
}

#define CREATE_EXPR_ENGINE_CHECKER(CHECKER_NAME, CALLBACK, STMT_TYPE, \
BUG_NAME) \
class CHECKER_NAME : public Checker<check::CALLBACK<STMT_TYPE>> { \
public: \
void check##CALLBACK(const STMT_TYPE *ASM, CheckerContext &C) const { \
emitErrorReport(C, Bug, "check" #CALLBACK "<" #STMT_TYPE ">"); \
} \
\
private: \
const BugType Bug{this, BUG_NAME}; \
};

CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPreChecker, PreStmt, GCCAsmStmt,
"GCCAsmStmtBug")
CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPostChecker, PostStmt, GCCAsmStmt,
"GCCAsmStmtBug")

void addExprEngineVisitPreChecker(AnalysisASTConsumer &AnalysisConsumer,
AnalyzerOptions &AnOpts) {
AnOpts.CheckersAndPackages = {{"ExprEngineVisitPreChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<ExprEngineVisitPreChecker>("ExprEngineVisitPreChecker",
"Desc", "DocsURI");
});
}

void addExprEngineVisitPostChecker(AnalysisASTConsumer &AnalysisConsumer,
AnalyzerOptions &AnOpts) {
AnOpts.CheckersAndPackages = {{"ExprEngineVisitPostChecker", true}};
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<ExprEngineVisitPostChecker>(
"ExprEngineVisitPostChecker", "Desc", "DocsURI");
});
}

TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) {
std::string Diags;
EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPreChecker>(R"(
void top() {
asm("");
}
)",
Diags));
EXPECT_EQ(Diags, "ExprEngineVisitPreChecker: checkPreStmt<GCCAsmStmt>\n");
}

TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) {
std::string Diags;
EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPostChecker>(R"(
void top() {
asm("");
}
)",
Diags));
EXPECT_EQ(Diags, "ExprEngineVisitPostChecker: checkPostStmt<GCCAsmStmt>\n");
}

} // namespace
5 changes: 3 additions & 2 deletions compiler-rt/cmake/Modules/AddCompilerRT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,9 @@ function(add_compiler_rt_runtime name type)
${ARGN})
set(libnames)
# Until we support this some other way, build compiler-rt runtime without LTO
# to allow non-LTO projects to link with it.
if(COMPILER_RT_HAS_FNO_LTO_FLAG)
# to allow non-LTO projects to link with it. GPU targets can currently only be
# distributed as LLVM-IR and ignore this.
if(COMPILER_RT_HAS_FNO_LTO_FLAG AND NOT COMPILER_RT_GPU_BUILD)
set(NO_LTO_FLAGS "-fno-lto")
else()
set(NO_LTO_FLAGS "")
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/cmake/Modules/BuiltinTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ endfunction()
function(builtin_check_c_compiler_flag flag output)
if(NOT DEFINED ${output})
message(STATUS "Performing Test ${output}")
try_compile_only(result FLAGS ${flag})
try_compile_only(result FLAGS ${flag} ${CMAKE_REQUIRED_FLAGS})
set(${output} ${result} CACHE INTERNAL "Compiler supports ${flag}")
if(${result})
message(STATUS "Performing Test ${output} - Success")
Expand Down
27 changes: 26 additions & 1 deletion compiler-rt/cmake/Modules/CompilerRTUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ macro(test_target_arch arch def)
endmacro()

macro(detect_target_arch)
check_symbol_exists(__AMDGPU__ "" __AMDGPU)
check_symbol_exists(__arm__ "" __ARM)
check_symbol_exists(__AVR__ "" __AVR)
check_symbol_exists(__aarch64__ "" __AARCH64)
Expand All @@ -154,6 +155,7 @@ macro(detect_target_arch)
check_symbol_exists(__loongarch__ "" __LOONGARCH)
check_symbol_exists(__mips__ "" __MIPS)
check_symbol_exists(__mips64__ "" __MIPS64)
check_symbol_exists(__NVPTX__ "" __NVPTX)
check_symbol_exists(__powerpc__ "" __PPC)
check_symbol_exists(__powerpc64__ "" __PPC64)
check_symbol_exists(__powerpc64le__ "" __PPC64LE)
Expand All @@ -164,7 +166,9 @@ macro(detect_target_arch)
check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32)
check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64)
check_symbol_exists(__ve__ "" __VE)
if(__ARM)
if(__AMDGPU)
add_default_target_arch(amdgcn)
elseif(__ARM)
add_default_target_arch(arm)
elseif(__AVR)
add_default_target_arch(avr)
Expand Down Expand Up @@ -192,6 +196,8 @@ macro(detect_target_arch)
add_default_target_arch(mips64)
elseif(__MIPS)
add_default_target_arch(mips)
elseif(__NVPTX)
add_default_target_arch(nvptx64)
elseif(__PPC64) # must be checked before __PPC
add_default_target_arch(powerpc64)
elseif(__PPC64LE)
Expand Down Expand Up @@ -397,6 +403,21 @@ macro(construct_compiler_rt_default_triple)
set(COMPILER_RT_DEFAULT_TARGET_ARCH "i386")
endif()

# If we are directly targeting a GPU we need to check that the compiler is
# compatible and pass some default arguments.
if(COMPILER_RT_DEFAULT_TARGET_ONLY)

# Pass the necessary flags to make flag detection work.
if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn")
set(COMPILER_RT_GPU_BUILD ON)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nogpulib")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "nvptx")
set(COMPILER_RT_GPU_BUILD ON)
set(CMAKE_REQUIRED_FLAGS
"${CMAKE_REQUIRED_FLAGS} -flto -c -Wno-unused-command-line-argument")
endif()
endif()

# Determine if test target triple is specified explicitly, and doesn't match the
# default.
if(NOT COMPILER_RT_DEFAULT_TARGET_TRIPLE STREQUAL LLVM_TARGET_TRIPLE)
Expand Down Expand Up @@ -475,6 +496,10 @@ function(get_compiler_rt_target arch variable)
endif()
endif()
set(target "${arch}${triple_suffix}")
elseif("${arch}" MATCHES "^amdgcn")
set(target "amdgcn-amd-amdhsa")
elseif("${arch}" MATCHES "^nvptx")
set(target "nvptx64-nvidia-cuda")
else()
set(target "${arch}${triple_suffix}")
endif()
Expand Down
7 changes: 7 additions & 0 deletions compiler-rt/cmake/base-config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ macro(test_targets)
test_target_arch(x86_64 "" "")
endif()
endif()
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn")
test_target_arch(amdgcn "" "--target=amdgcn-amd-amdhsa" "-nogpulib"
"-flto" "-fconvergent-functions"
"-Xclang -mcode-object-version=none")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "loongarch64")
test_target_arch(loongarch64 "" "")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc64le|ppc64le")
Expand Down Expand Up @@ -254,6 +258,9 @@ macro(test_targets)
test_target_arch(mips "" "-mips32r2" "-mabi=32" "-D_LARGEFILE_SOURCE=1" "-D_FILE_OFFSET_BITS=64")
test_target_arch(mips64 "" "-mips64r2" "-mabi=64")
endif()
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "nvptx")
test_target_arch(nvptx64 "" "--nvptx64-nvidia-cuda" "-nogpulib" "-flto"
"-fconvergent-functions" "-c")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
if(WIN32)
test_target_arch(arm "" "" "")
Expand Down
13 changes: 10 additions & 3 deletions compiler-rt/cmake/builtin-config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ builtin_check_c_compiler_flag(-fno-profile-generate COMPILER_RT_HAS_FNO_PROFILE_
builtin_check_c_compiler_flag(-fno-profile-instr-generate COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
builtin_check_c_compiler_flag(-fno-profile-instr-use COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
builtin_check_c_compiler_flag(-Wno-pedantic COMPILER_RT_HAS_WNO_PEDANTIC)
builtin_check_c_compiler_flag(-nogpulib COMPILER_RT_HAS_NOGPULIB_FLAG)
builtin_check_c_compiler_flag(-flto COMPILER_RT_HAS_FLTO_FLAG)
builtin_check_c_compiler_flag(-fconvergent-functions COMPILER_RT_HAS_FCONVERGENT_FUNCTIONS_FLAG)
builtin_check_c_compiler_flag("-Xclang -mcode-object-version=none" COMPILER_RT_HAS_CODE_OBJECT_VERSION_FLAG)
builtin_check_c_compiler_flag(-Wbuiltin-declaration-mismatch COMPILER_RT_HAS_WBUILTIN_DECLARATION_MISMATCH_FLAG)
builtin_check_c_compiler_flag(/Zl COMPILER_RT_HAS_ZL_FLAG)

Expand Down Expand Up @@ -52,6 +56,7 @@ else()
set(OS_NAME "${CMAKE_SYSTEM_NAME}")
endif()

set(AMDGPU amdgcn)
set(ARM64 aarch64)
set(ARM32 arm armhf armv4t armv5te armv6 armv6m armv7m armv7em armv7 armv7s armv7k armv8m.base armv8m.main armv8.1m.main)
set(AVR avr)
Expand All @@ -61,6 +66,7 @@ set(X86_64 x86_64)
set(LOONGARCH64 loongarch64)
set(MIPS32 mips mipsel)
set(MIPS64 mips64 mips64el)
set(NVPTX nvptx64)
set(PPC32 powerpc powerpcspe)
set(PPC64 powerpc64 powerpc64le)
set(RISCV32 riscv32)
Expand All @@ -78,8 +84,8 @@ if(APPLE)
endif()

set(ALL_BUILTIN_SUPPORTED_ARCH
${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR}
${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64}
${X86} ${X86_64} ${AMDGPU} ${ARM32} ${ARM64} ${AVR}
${HEXAGON} ${MIPS32} ${MIPS64} ${NVPTX} ${PPC32} ${PPC64}
${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9}
${WASM32} ${WASM64} ${VE} ${LOONGARCH64})

Expand Down Expand Up @@ -245,7 +251,8 @@ else()
${ALL_BUILTIN_SUPPORTED_ARCH})
endif()

if (OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER)
if(OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER AND NOT
COMPILER_RT_GPU_BUILD)
set(COMPILER_RT_HAS_CRT TRUE)
else()
set(COMPILER_RT_HAS_CRT FALSE)
Expand Down
18 changes: 18 additions & 0 deletions compiler-rt/cmake/caches/GPU.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This file sets up a CMakeCache for GPU builds of compiler-rt. This supports
# amdgcn and nvptx builds targeting the builtins library.

set(COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "")
set(COMPILER_RT_HAS_SAFESTACK OFF CACHE BOOL "")

set(COMPILER_RT_BUILD_BUILTINS ON CACHE BOOL "")
set(COMPILER_RT_BAREMETAL_BUILD ON CACHE BOOL "")
set(COMPILER_RT_BUILD_CRT OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_PROFILE OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_XRAY_NO_PREINIT OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_ORC OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_GWP_ASAN OFF CACHE BOOL "")
set(COMPILER_RT_BUILD_SCUDO_SANTDALONE_WITH_LLVM_LIBC OFF CACHE BOOL "")
14 changes: 7 additions & 7 deletions compiler-rt/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,13 @@ else()
set(COMPILER_RT_HAS_ASAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux|Android|Fuchsia")
set(COMPILER_RT_HAS_HWASAN TRUE)
else()
set(COMPILER_RT_HAS_HWASAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND RTSAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Android|Darwin|Linux")
set(COMPILER_RT_HAS_RTSAN TRUE)
Expand Down Expand Up @@ -787,13 +794,6 @@ else()
set(COMPILER_RT_HAS_MSAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND HWASAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux|Android|Fuchsia")
set(COMPILER_RT_HAS_HWASAN TRUE)
else()
set(COMPILER_RT_HAS_HWASAN FALSE)
endif()

if (COMPILER_RT_HAS_SANITIZER_COMMON AND MEMPROF_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux")
set(COMPILER_RT_HAS_MEMPROF TRUE)
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ endif()
if(COMPILER_RT_BUILD_SANITIZERS)
if(COMPILER_RT_HAS_SANITIZER_COMMON)
add_subdirectory(stats)
# Contains RTLSanCommon used even without COMPILER_RT_HAS_LSAN.
add_subdirectory(lsan)
# Contains RTUbsan used even without COMPILER_RT_HAS_UBSAN.
add_subdirectory(ubsan)
endif()

Expand All @@ -47,11 +49,11 @@ if(COMPILER_RT_BUILD_SANITIZERS)
endforeach()
endif()

if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE)
if(COMPILER_RT_BUILD_PROFILE)
compiler_rt_build_runtime(profile)
endif()

if(COMPILER_RT_BUILD_CTX_PROFILE AND COMPILER_RT_HAS_CTX_PROFILE)
if(COMPILER_RT_BUILD_CTX_PROFILE)
compiler_rt_build_runtime(ctx_profile)
endif()

Expand Down
21 changes: 20 additions & 1 deletion compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ option(COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN
"Skip the atomic builtin (these should normally be provided by a shared library)"
On)

if(NOT FUCHSIA AND NOT COMPILER_RT_BAREMETAL_BUILD)
if(NOT FUCHSIA AND NOT COMPILER_RT_BAREMETAL_BUILD AND NOT COMPILER_RT_GPU_BUILD)
set(GENERIC_SOURCES
${GENERIC_SOURCES}
emutls.c
Expand Down Expand Up @@ -627,6 +627,8 @@ if (MINGW)
)
endif()

set(amdgcn_SOURCES ${GENERIC_SOURCES})

set(armv4t_SOURCES ${arm_min_SOURCES})
set(armv5te_SOURCES ${arm_min_SOURCES})
set(armv6_SOURCES ${arm_min_SOURCES})
Expand Down Expand Up @@ -706,6 +708,8 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES}
set(mips64el_SOURCES ${GENERIC_TF_SOURCES}
${mips_SOURCES})

set(nvptx64_SOURCES ${GENERIC_SOURCES})

set(powerpc_SOURCES ${GENERIC_SOURCES})

set(powerpcspe_SOURCES ${GENERIC_SOURCES})
Expand Down Expand Up @@ -811,6 +815,21 @@ else ()
endif()
endif()

# Directly targeting the GPU requires a few extra flags.
if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn|nvptx")
append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding BUILTIN_CFLAGS)
append_list_if(COMPILER_RT_HAS_NOGPULIB_FLAG -nogpulib BUILTIN_CFLAGS)
append_list_if(COMPILER_RT_HAS_FLTO_FLAG -flto BUILTIN_CFLAGS)
append_list_if(COMPILER_RT_HAS_FCONVERGENT_FUNCTIONS_FLAG
-fconvergent-functions BUILTIN_CFLAGS)

# AMDGPU targets want to use a generic ABI.
if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "amdgcn")
append_list_if(COMPILER_RT_HAS_CODE_OBJECT_VERSION_FLAG
"SHELL:-Xclang -mcode-object-version=none" BUILTIN_CFLAGS)
endif()
endif()

set(BUILTIN_DEFS "")

if(COMPILER_RT_BUILTINS_HIDE_SYMBOLS)
Expand Down
76 changes: 37 additions & 39 deletions compiler-rt/lib/gwp_asan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,48 +65,46 @@ set(GWP_ASAN_SEGV_HANDLER_HEADERS
set(GWP_ASAN_OPTIONS_PARSER_CFLAGS
${GWP_ASAN_CFLAGS})

if (COMPILER_RT_HAS_GWP_ASAN)
foreach(arch ${GWP_ASAN_SUPPORTED_ARCH})
add_compiler_rt_runtime(
clang_rt.gwp_asan
STATIC
ARCHS ${arch}
SOURCES ${GWP_ASAN_SOURCES}
ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS}
PARENT_TARGET gwp_asan
)
endforeach()
foreach(arch ${GWP_ASAN_SUPPORTED_ARCH})
add_compiler_rt_runtime(
clang_rt.gwp_asan
STATIC
ARCHS ${arch}
SOURCES ${GWP_ASAN_SOURCES}
ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS}
PARENT_TARGET gwp_asan
)
endforeach()

add_compiler_rt_object_libraries(RTGwpAsan
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES ${GWP_ASAN_SOURCES}
ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS})
add_compiler_rt_object_libraries(RTGwpAsan
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES ${GWP_ASAN_SOURCES}
ADDITIONAL_HEADERS ${GWP_ASAN_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS})

add_compiler_rt_object_libraries(RTGwpAsanOptionsParser
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES ${GWP_ASAN_OPTIONS_PARSER_SOURCES}
ADDITIONAL_HEADERS ${GWP_ASAN_OPTIONS_PARSER_HEADERS}
CFLAGS ${GWP_ASAN_OPTIONS_PARSER_CFLAGS})
add_compiler_rt_object_libraries(RTGwpAsanOptionsParser
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES ${GWP_ASAN_OPTIONS_PARSER_SOURCES}
ADDITIONAL_HEADERS ${GWP_ASAN_OPTIONS_PARSER_HEADERS}
CFLAGS ${GWP_ASAN_OPTIONS_PARSER_CFLAGS})

# As above, build the pre-implemented optional backtrace support libraries.
add_compiler_rt_object_libraries(RTGwpAsanBacktraceLibc
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES optional/backtrace_linux_libc.cpp
ADDITIONAL_HEADERS ${GWP_ASAN_BACKTRACE_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS})
add_compiler_rt_object_libraries(RTGwpAsanSegvHandler
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES optional/segv_handler_posix.cpp
ADDITIONAL_HEADERS ${GWP_ASAN_SEGV_HANDLER_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS})
add_compiler_rt_object_libraries(RTGwpAsanBacktraceSanitizerCommon
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES optional/backtrace_sanitizer_common.cpp
ADDITIONAL_HEADERS ${GWP_ASAN_BACKTRACE_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS} ${SANITIZER_COMMON_CFLAGS})
endif()
# As above, build the pre-implemented optional backtrace support libraries.
add_compiler_rt_object_libraries(RTGwpAsanBacktraceLibc
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES optional/backtrace_linux_libc.cpp
ADDITIONAL_HEADERS ${GWP_ASAN_BACKTRACE_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS})
add_compiler_rt_object_libraries(RTGwpAsanSegvHandler
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES optional/segv_handler_posix.cpp
ADDITIONAL_HEADERS ${GWP_ASAN_SEGV_HANDLER_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS})
add_compiler_rt_object_libraries(RTGwpAsanBacktraceSanitizerCommon
ARCHS ${GWP_ASAN_SUPPORTED_ARCH}
SOURCES optional/backtrace_sanitizer_common.cpp
ADDITIONAL_HEADERS ${GWP_ASAN_BACKTRACE_HEADERS}
CFLAGS ${GWP_ASAN_CFLAGS} ${SANITIZER_COMMON_CFLAGS})

if(COMPILER_RT_INCLUDE_TESTS)
add_subdirectory(tests)
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/lsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(LSAN_HEADERS

set(LSAN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})

# Used by asan/hwasan even without COMPILER_RT_HAS_LSAN.
add_compiler_rt_object_libraries(RTLSanCommon
OS ${SANITIZER_COMMON_SUPPORTED_OS}
ARCHS ${LSAN_COMMON_SUPPORTED_ARCH}
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/msan/msan_thread.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

#include "msan.h"
#include "msan_thread.h"
#include "msan_interface_internal.h"

#include "msan.h"
#include "msan_interface_internal.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"

namespace __msan {
Expand Down
103 changes: 85 additions & 18 deletions compiler-rt/lib/nsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ set(NSAN_SOURCES
nsan.cpp
nsan_flags.cpp
nsan_interceptors.cpp
nsan_malloc_linux.cpp
nsan_stats.cpp
nsan_suppressions.cpp
)
Expand All @@ -24,31 +25,97 @@ append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC NSAN_CFLAGS)
set(NSAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})

set(NSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
set(NSAN_DYNAMIC_CFLAGS ${NSAN_CFLAGS})

if (COMPILER_RT_HAS_NSAN)
foreach(arch ${NSAN_SUPPORTED_ARCH})
add_compiler_rt_runtime(
clang_rt.nsan
STATIC
ARCHS ${arch}
SOURCES ${NSAN_SOURCES}
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
$<TARGET_OBJECTS:RTUbsan.${arch}>
ADDITIONAL_HEADERS ${NSAN_HEADERS}
CFLAGS ${NSAN_CFLAGS}
PARENT_TARGET nsan
)
endforeach()
set(NSAN_COMMON_RUNTIME_OBJECT_LIBS
RTInterception
RTSanitizerCommon
RTSanitizerCommonLibc
RTSanitizerCommonCoverage
RTSanitizerCommonSymbolizer
RTSanitizerCommonSymbolizerInternal
RTUbsan)

set(NSAN_DYNAMIC_LIBS
${COMPILER_RT_UNWINDER_LINK_LIBS}
${SANITIZER_CXX_ABI_LIBRARIES}
${SANITIZER_COMMON_LINK_LIBS})

append_list_if(COMPILER_RT_HAS_LIBDL dl NSAN_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBRT rt NSAN_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBM m NSAN_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread NSAN_DYNAMIC_LIBS)

# Compile sources into an object library.

add_compiler_rt_object_libraries(RTNsan_dynamic
ARCHS ${NSAN_SUPPORTED_ARCH}
SOURCES ${NSAN_SOURCES}
ADDITIONAL_HEADERS ${NSAN_HEADERS}
CFLAGS ${NSAN_CFLAGS})

if(NOT APPLE)
add_compiler_rt_object_libraries(RTNsan
ARCHS ${NSAN_SUPPORTED_ARCH}
SOURCES ${NSAN_SOURCES}
ADDITIONAL_HEADERS ${NSAN_HEADERS}
CFLAGS ${NSAN_CFLAGS})

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
add_compiler_rt_object_libraries(RTNsan_dynamic_version_script_dummy
ARCHS ${NSAN_SUPPORTED_ARCH}
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
CFLAGS ${NSAN_DYNAMIC_CFLAGS})
endif()

add_compiler_rt_runtime(
clang_rt.nsan
STATIC
ARCHS ${NSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTNsan
${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
CFLAGS ${NSAN_CFLAGS}
PARENT_TARGET nsan)

if(NOT APPLE)
foreach(arch ${NSAN_SUPPORTED_ARCH})
if (COMPILER_RT_HAS_VERSION_SCRIPT)
add_sanitizer_rt_version_list(clang_rt.nsan-dynamic-${arch}
LIBS clang_rt.nsan-${arch}
EXTRA nsan.syms.extra)
set(VERSION_SCRIPT_FLAG
-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.nsan-dynamic-${arch}.vers)
# The Solaris 11.4 linker supports a subset of GNU ld version scripts,
# but requires a special option to enable it.
if (COMPILER_RT_HAS_GNU_VERSION_SCRIPT_COMPAT)
list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
endif()
set_property(SOURCE
${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
APPEND PROPERTY
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.nsan-dynamic-${arch}.vers)
else()
set(VERSION_SCRIPT_FLAG)
endif()

add_compiler_rt_runtime(
clang_rt.nsan
SHARED
ARCHS ${arch}
OBJECT_LIBS ${NSAN_COMMON_RUNTIME_OBJECT_LIBS}
RTNsan_dynamic
# The only purpose of RTNsan_dynamic_version_script_dummy is to
# carry a dependency of the shared runtime on the version script.
# Replacing it with a straightforward
# add_dependencies(clang_rt.nsan-dynamic-${arch} clang_rt.nsan-dynamic-${arch}-version-list)
# generates an order-only dependency in ninja.
RTNsan_dynamic_version_script_dummy
CFLAGS ${NSAN_DYNAMIC_CFLAGS}
LINK_FLAGS ${NSAN_DYNAMIC_LINK_FLAGS}
${VERSION_SCRIPT_FLAG}
LINK_LIBS ${NSAN_DYNAMIC_LIBS}
PARENT_TARGET nsan)
endforeach()
endif()

if(COMPILER_RT_INCLUDE_TESTS)
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/lib/nsan/nsan.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extern bool nsan_initialized;
extern bool nsan_init_is_running;

void InitializeInterceptors();
void InitializeMallocInterceptors();

// See notes in nsan_platform.
// printf-free (see comment in nsan_interceptors.cc).
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/nsan/nsan.syms.extra
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
nsan_*
__nsan_*
__ubsan_*
115 changes: 2 additions & 113 deletions compiler-rt/lib/nsan/nsan_interceptors.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-- nsan_interceptors.cc ----------------------------------------------===//
//===- nsan_interceptors.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand Down Expand Up @@ -29,26 +29,8 @@ using namespace __sanitizer;
using __nsan::nsan_init_is_running;
using __nsan::nsan_initialized;

constexpr uptr kEarlyAllocBufSize = 16384;
static uptr allocated_bytes;
static char early_alloc_buf[kEarlyAllocBufSize];

static bool isInEarlyAllocBuf(const void *ptr) {
return ((uptr)ptr >= (uptr)early_alloc_buf &&
((uptr)ptr - (uptr)early_alloc_buf) < sizeof(early_alloc_buf));
}

template <typename T> T min(T a, T b) { return a < b ? a : b; }

// Handle allocation requests early (before all interceptors are setup). dlsym,
// for example, calls calloc.
static void *HandleEarlyAlloc(uptr size) {
void *Mem = (void *)&early_alloc_buf[allocated_bytes];
allocated_bytes += size;
CHECK_LT(allocated_bytes, kEarlyAllocBufSize);
return Mem;
}

INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
// NOTE: This guard is needed because nsan's initialization code might call
// memset.
Expand Down Expand Up @@ -105,90 +87,6 @@ INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dst, const wchar_t *src, uptr size) {
return res;
}

INTERCEPTOR(void *, malloc, uptr size) {
// NOTE: This guard is needed because nsan's initialization code might call
// malloc.
if (nsan_init_is_running && REAL(malloc) == nullptr)
return HandleEarlyAlloc(size);

void *res = REAL(malloc)(size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
void *res = REAL(realloc)(ptr, size);
// FIXME: We might want to copy the types from the original allocation
// (although that would require that we know its size).
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, calloc, uptr Nmemb, uptr size) {
// NOTE: This guard is needed because nsan's initialization code might call
// calloc.
if (nsan_init_is_running && REAL(calloc) == nullptr) {
// Note: EarlyAllocBuf is initialized with zeros.
return HandleEarlyAlloc(Nmemb * size);
}

void *res = REAL(calloc)(Nmemb, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), Nmemb * size);
return res;
}

INTERCEPTOR(void, free, void *P) {
// There are only a few early allocation requests, so we simply skip the free.
if (isInEarlyAllocBuf(P))
return;
REAL(free)(P);
}

INTERCEPTOR(void *, valloc, uptr size) {
void *const res = REAL(valloc)(size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, memalign, uptr align, uptr size) {
void *const res = REAL(memalign)(align, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
void *const res = REAL(__libc_memalign)(align, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, pvalloc, uptr size) {
void *const res = REAL(pvalloc)(size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
void *const res = REAL(aligned_alloc)(align, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
int res = REAL(posix_memalign)(memptr, align, size);
if (res == 0 && *memptr)
__nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
return res;
}

INTERCEPTOR(char *, strfry, char *s) {
const auto Len = internal_strlen(s);
char *res = REAL(strfry)(s);
Expand Down Expand Up @@ -317,16 +215,7 @@ void __nsan::InitializeInterceptors() {
mallopt(-3, 32 * 1024); // M_MMAP_THRESHOLD
#endif

INTERCEPT_FUNCTION(malloc);
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(free);
INTERCEPT_FUNCTION(realloc);
INTERCEPT_FUNCTION(valloc);
INTERCEPT_FUNCTION(memalign);
INTERCEPT_FUNCTION(__libc_memalign);
INTERCEPT_FUNCTION(pvalloc);
INTERCEPT_FUNCTION(aligned_alloc);
INTERCEPT_FUNCTION(posix_memalign);
InitializeMallocInterceptors();

INTERCEPT_FUNCTION(memset);
INTERCEPT_FUNCTION(wmemset);
Expand Down
123 changes: 123 additions & 0 deletions compiler-rt/lib/nsan/nsan_malloc_linux.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//===- nsan_malloc_linux.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Interceptors for memory allocation functions on ELF OSes.
//
//===----------------------------------------------------------------------===//

#include "interception/interception.h"
#include "nsan/nsan.h"
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_platform.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"

#if !SANITIZER_APPLE && !SANITIZER_WINDOWS
using namespace __sanitizer;
using __nsan::nsan_initialized;

namespace {
struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
static bool UseImpl() { return !nsan_initialized; }
};
} // namespace

INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
void *res = REAL(aligned_alloc)(align, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
if (DlsymAlloc::Use())
return DlsymAlloc::Callocate(nmemb, size);

void *res = REAL(calloc)(nmemb, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
return res;
}

INTERCEPTOR(void, free, void *ptr) {
if (DlsymAlloc::PointerIsMine(ptr))
return DlsymAlloc::Free(ptr);
REAL(free)(ptr);
}

INTERCEPTOR(void *, malloc, uptr size) {
if (DlsymAlloc::Use())
return DlsymAlloc::Allocate(size);
void *res = REAL(malloc)(size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
return DlsymAlloc::Realloc(ptr, size);
void *res = REAL(realloc)(ptr, size);
// TODO: We might want to copy the types from the original allocation
// (although that would require that we know its size).
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

#if SANITIZER_INTERCEPT_REALLOCARRAY
INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
void *res = REAL(reallocarray)(ptr, nmemb, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
return res;
}
#endif // SANITIZER_INTERCEPT_REALLOCARRAY

INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
int res = REAL(posix_memalign)(memptr, align, size);
if (res == 0 && *memptr)
__nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
return res;
}

// Deprecated allocation functions (memalign, etc).
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void *, memalign, uptr align, uptr size) {
void *const res = REAL(memalign)(align, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}

INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
void *const res = REAL(__libc_memalign)(align, size);
if (res)
__nsan_set_value_unknown(static_cast<u8 *>(res), size);
return res;
}
#endif

void __nsan::InitializeMallocInterceptors() {
INTERCEPT_FUNCTION(aligned_alloc);
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(free);
INTERCEPT_FUNCTION(malloc);
INTERCEPT_FUNCTION(posix_memalign);
INTERCEPT_FUNCTION(realloc);
#if SANITIZER_INTERCEPT_REALLOCARRAY
INTERCEPT_FUNCTION(reallocarray);
#endif

#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPT_FUNCTION(memalign);
INTERCEPT_FUNCTION(__libc_memalign);
#endif
}

#endif
11 changes: 11 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset) {
CHECK_EQ(0, internal_sigprocmask(SIG_SETMASK, set, oldset));
}

// Block asynchronous signals
void BlockSignals(__sanitizer_sigset_t *oldset) {
__sanitizer_sigset_t set;
internal_sigfillset(&set);
Expand All @@ -169,7 +170,17 @@ void BlockSignals(__sanitizer_sigset_t *oldset) {
// If this signal is blocked, such calls cannot be handled and the process may
// hang.
internal_sigdelset(&set, 31);

// Don't block synchronous signals
internal_sigdelset(&set, SIGSEGV);
internal_sigdelset(&set, SIGBUS);
internal_sigdelset(&set, SIGILL);
internal_sigdelset(&set, SIGTRAP);
internal_sigdelset(&set, SIGABRT);
internal_sigdelset(&set, SIGFPE);
internal_sigdelset(&set, SIGPIPE);
# endif

SetSigProcMask(&set, oldset);
}

Expand Down
13 changes: 13 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,19 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
stacksize = kMaxThreadStackSize;
*stack_top = segment.end;
*stack_bottom = segment.end - stacksize;

uptr maxAddr = GetMaxUserVirtualAddress();
// Edge case: the stack mapping on some systems may be off-by-one e.g.,
// fffffffdf000-1000000000000 rw-p 00000000 00:00 0 [stack]
// instead of:
// fffffffdf000- ffffffffffff
// The out-of-range stack_top can result in an invalid shadow address
// calculation, since those usually assume the parameters are in range.
if (*stack_top == maxAddr + 1)
*stack_top = maxAddr;
else
CHECK_LE(*stack_top, maxAddr);

return;
}
uptr stacksize = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ posix_spawn_file_actions_adddup2 U
posix_spawn_file_actions_addopen U
posix_spawn_file_actions_destroy U
posix_spawn_file_actions_init U
printf U
putchar U
qsort U
raise U
rand U
Expand Down
94 changes: 46 additions & 48 deletions compiler-rt/lib/scudo/standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -195,60 +195,58 @@ if(COMPILER_RT_DEFAULT_TARGET_ARCH MATCHES "mips|mips64|mipsel|mips64el")
list(APPEND SCUDO_LINK_LIBS atomic)
endif()

if(COMPILER_RT_HAS_SCUDO_STANDALONE)
add_compiler_rt_object_libraries(RTScudoStandalone
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS})
add_compiler_rt_object_libraries(RTScudoStandaloneCWrappers
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES_C_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS})
add_compiler_rt_object_libraries(RTScudoStandaloneCxxWrappers
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES_CXX_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS})

add_compiler_rt_object_libraries(RTScudoStandalone
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS})
add_compiler_rt_object_libraries(RTScudoStandaloneCWrappers
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES_C_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS})
add_compiler_rt_object_libraries(RTScudoStandaloneCxxWrappers
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES_CXX_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS})

add_compiler_rt_runtime(clang_rt.scudo_standalone
STATIC
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES} ${SCUDO_SOURCES_C_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS}
OBJECT_LIBS ${SCUDO_OBJECT_LIBS}
PARENT_TARGET scudo_standalone)
add_compiler_rt_runtime(clang_rt.scudo_standalone_cxx
STATIC
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES_CXX_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS}
PARENT_TARGET scudo_standalone)

if(COMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED)
add_compiler_rt_runtime(clang_rt.scudo_standalone
STATIC
SHARED
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES} ${SCUDO_SOURCES_C_WRAPPERS}
SOURCES ${SCUDO_SOURCES} ${SCUDO_SOURCES_C_WRAPPERS} ${SCUDO_SOURCES_CXX_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS}
OBJECT_LIBS ${SCUDO_OBJECT_LIBS}
LINK_FLAGS ${SCUDO_LINK_FLAGS}
LINK_LIBS ${SCUDO_LINK_LIBS}
PARENT_TARGET scudo_standalone)
add_compiler_rt_runtime(clang_rt.scudo_standalone_cxx
STATIC
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES_CXX_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS}
PARENT_TARGET scudo_standalone)

if(COMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED)
add_compiler_rt_runtime(clang_rt.scudo_standalone
SHARED
ARCHS ${SCUDO_STANDALONE_SUPPORTED_ARCH}
SOURCES ${SCUDO_SOURCES} ${SCUDO_SOURCES_C_WRAPPERS} ${SCUDO_SOURCES_CXX_WRAPPERS}
ADDITIONAL_HEADERS ${SCUDO_HEADERS}
CFLAGS ${SCUDO_CFLAGS}
DEPS ${SCUDO_DEPS}
OBJECT_LIBS ${SCUDO_OBJECT_LIBS}
LINK_FLAGS ${SCUDO_LINK_FLAGS}
LINK_LIBS ${SCUDO_LINK_LIBS}
PARENT_TARGET scudo_standalone)
endif()
endif()

add_subdirectory(benchmarks)
if(COMPILER_RT_INCLUDE_TESTS)
add_subdirectory(tests)
endif()
add_subdirectory(benchmarks)
if(COMPILER_RT_INCLUDE_TESTS)
add_subdirectory(tests)
endif()
38 changes: 18 additions & 20 deletions compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,25 @@ macro(add_scudo_unittest testname)
RTGwpAsan RTGwpAsanBacktraceLibc RTGwpAsanSegvHandler)
endif()

if(COMPILER_RT_HAS_SCUDO_STANDALONE)
foreach(arch ${SCUDO_TEST_ARCH})
# Additional runtime objects get added along RTScudoStandalone
set(SCUDO_TEST_RTOBJECTS $<TARGET_OBJECTS:RTScudoStandalone.${arch}>)
foreach(rtobject ${TEST_ADDITIONAL_RTOBJECTS})
list(APPEND SCUDO_TEST_RTOBJECTS $<TARGET_OBJECTS:${rtobject}.${arch}>)
endforeach()
# Add the static runtime library made of all the runtime objects
set(RUNTIME RT${testname}.${arch})
add_library(${RUNTIME} STATIC ${SCUDO_TEST_RTOBJECTS})
set(ScudoUnitTestsObjects)
generate_compiler_rt_tests(ScudoUnitTestsObjects ScudoUnitTests
"${testname}-${arch}-Test" ${arch}
SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
COMPILE_DEPS ${SCUDO_TEST_HEADERS}
DEPS scudo_standalone
RUNTIME ${RUNTIME}
CFLAGS ${SCUDO_UNITTEST_CFLAGS}
LINK_FLAGS ${SCUDO_UNITTEST_LINK_FLAGS})
foreach(arch ${SCUDO_TEST_ARCH})
# Additional runtime objects get added along RTScudoStandalone
set(SCUDO_TEST_RTOBJECTS $<TARGET_OBJECTS:RTScudoStandalone.${arch}>)
foreach(rtobject ${TEST_ADDITIONAL_RTOBJECTS})
list(APPEND SCUDO_TEST_RTOBJECTS $<TARGET_OBJECTS:${rtobject}.${arch}>)
endforeach()
endif()
# Add the static runtime library made of all the runtime objects
set(RUNTIME RT${testname}.${arch})
add_library(${RUNTIME} STATIC ${SCUDO_TEST_RTOBJECTS})
set(ScudoUnitTestsObjects)
generate_compiler_rt_tests(ScudoUnitTestsObjects ScudoUnitTests
"${testname}-${arch}-Test" ${arch}
SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
COMPILE_DEPS ${SCUDO_TEST_HEADERS}
DEPS scudo_standalone
RUNTIME ${RUNTIME}
CFLAGS ${SCUDO_UNITTEST_CFLAGS}
LINK_FLAGS ${SCUDO_UNITTEST_LINK_FLAGS})
endforeach()
endmacro()

set(SCUDO_UNIT_TEST_SOURCES
Expand Down
229 changes: 202 additions & 27 deletions compiler-rt/lib/scudo/standalone/tests/timing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "timing.h"

#include <cstdlib>
#include <string>

class ScudoTimingTest : public Test {
Expand All @@ -33,54 +34,228 @@ class ScudoTimingTest : public Test {

void printAllTimersStats() { Manager.printAll(); }

void getAllTimersStats(scudo::ScopedString &Str) { Manager.getAll(Str); }

scudo::TimingManager &getTimingManager() { return Manager; }

void testCallTimers() {
scudo::ScopedTimer Outer(getTimingManager(), "Level1");
{
scudo::ScopedTimer Inner1(getTimingManager(), Outer, "Level2");
{ scudo::ScopedTimer Inner2(getTimingManager(), Inner1, "Level3"); }
}
}

private:
scudo::TimingManager Manager;
};

// Given that the output of statistics of timers are dumped through
// `scudo::Printf` which is platform dependent, so we don't have a reliable way
// to catch the output and verify the details. Now we only verify the number of
// invocations on linux.
TEST_F(ScudoTimingTest, SimpleTimer) {
#if SCUDO_LINUX
testing::internal::LogToStderr();
testing::internal::CaptureStderr();
#endif

testIgnoredTimer();
testChainedCalls();
printAllTimersStats();
scudo::ScopedString Str;
getAllTimersStats(Str);

#if SCUDO_LINUX
std::string output = testing::internal::GetCapturedStderr();
EXPECT_TRUE(output.find("testIgnoredTimer (1)") == std::string::npos);
EXPECT_TRUE(output.find("testChainedCalls (1)") != std::string::npos);
EXPECT_TRUE(output.find("testFunc2 (1)") != std::string::npos);
EXPECT_TRUE(output.find("testFunc1 (1)") != std::string::npos);
#endif
std::string Output(Str.data());
EXPECT_TRUE(Output.find("testIgnoredTimer (1)") == std::string::npos);
EXPECT_TRUE(Output.find("testChainedCalls (1)") != std::string::npos);
EXPECT_TRUE(Output.find("testFunc2 (1)") != std::string::npos);
EXPECT_TRUE(Output.find("testFunc1 (1)") != std::string::npos);
}

TEST_F(ScudoTimingTest, NestedTimer) {
#if SCUDO_LINUX
testing::internal::LogToStderr();
testing::internal::CaptureStderr();
#endif

{
scudo::ScopedTimer Outer(getTimingManager(), "Outer");
{
scudo::ScopedTimer Inner1(getTimingManager(), Outer, "Inner1");
{ scudo::ScopedTimer Inner2(getTimingManager(), Inner1, "Inner2"); }
}
}
printAllTimersStats();
scudo::ScopedString Str;
getAllTimersStats(Str);

std::string Output(Str.data());
EXPECT_TRUE(Output.find("Outer (1)") != std::string::npos);
EXPECT_TRUE(Output.find("Inner1 (1)") != std::string::npos);
EXPECT_TRUE(Output.find("Inner2 (1)") != std::string::npos);
}

TEST_F(ScudoTimingTest, VerifyChainedTimerCalculations) {
{
scudo::ScopedTimer Outer(getTimingManager(), "Level1");
sleep(1);
{
scudo::ScopedTimer Inner1(getTimingManager(), Outer, "Level2");
sleep(2);
{
scudo::ScopedTimer Inner2(getTimingManager(), Inner1, "Level3");
sleep(3);
}
}
}
scudo::ScopedString Str;
getAllTimersStats(Str);
std::string Output(Str.data());

// Get the individual timer values for the average and maximum, then
// verify that the timer values are being calculated properly.
Output = Output.substr(Output.find('\n') + 1);
char *end;
unsigned long long Level1AvgNs = std::strtoull(Output.c_str(), &end, 10);
ASSERT_TRUE(end != nullptr);
unsigned long long Level1MaxNs = std::strtoull(&end[6], &end, 10);
ASSERT_TRUE(end != nullptr);
EXPECT_EQ(Level1AvgNs, Level1MaxNs);

Output = Output.substr(Output.find('\n') + 1);
unsigned long long Level2AvgNs = std::strtoull(Output.c_str(), &end, 10);
ASSERT_TRUE(end != nullptr);
unsigned long long Level2MaxNs = std::strtoull(&end[6], &end, 10);
ASSERT_TRUE(end != nullptr);
EXPECT_EQ(Level2AvgNs, Level2MaxNs);

Output = Output.substr(Output.find('\n') + 1);
unsigned long long Level3AvgNs = std::strtoull(Output.c_str(), &end, 10);
ASSERT_TRUE(end != nullptr);
unsigned long long Level3MaxNs = std::strtoull(&end[6], &end, 10);
ASSERT_TRUE(end != nullptr);
EXPECT_EQ(Level3AvgNs, Level3MaxNs);

EXPECT_GT(Level1AvgNs, Level2AvgNs);
EXPECT_GT(Level2AvgNs, Level3AvgNs);

// The time for the first timer needs to be at least six seconds.
EXPECT_GT(Level1AvgNs, 6000000000U);
// The time for the second timer needs to be at least five seconds.
EXPECT_GT(Level2AvgNs, 5000000000U);
// The time for the third timer needs to be at least three seconds.
EXPECT_GT(Level3AvgNs, 3000000000U);
// The time between the first and second timer needs to be at least one
// second.
EXPECT_GT(Level1AvgNs - Level2AvgNs, 1000000000U);
// The time between the second and third timer needs to be at least two
// second.
EXPECT_GT(Level2AvgNs - Level3AvgNs, 2000000000U);
}

TEST_F(ScudoTimingTest, VerifyMax) {
for (size_t i = 0; i < 3; i++) {
scudo::ScopedTimer Outer(getTimingManager(), "Level1");
sleep(1);
}
scudo::ScopedString Str;
getAllTimersStats(Str);
std::string Output(Str.data());

Output = Output.substr(Output.find('\n') + 1);
char *end;
unsigned long long AvgNs = std::strtoull(Output.c_str(), &end, 10);
ASSERT_TRUE(end != nullptr);
unsigned long long MaxNs = std::strtoull(&end[6], &end, 10);
ASSERT_TRUE(end != nullptr);

EXPECT_GT(MaxNs, AvgNs);
}

TEST_F(ScudoTimingTest, VerifyMultipleTimerCalls) {
for (size_t i = 0; i < 5; i++)
testCallTimers();

scudo::ScopedString Str;
getAllTimersStats(Str);
std::string Output(Str.data());
EXPECT_TRUE(Output.find("Level1 (5)") != std::string::npos);
EXPECT_TRUE(Output.find("Level2 (5)") != std::string::npos);
EXPECT_TRUE(Output.find("Level3 (5)") != std::string::npos);
}

TEST_F(ScudoTimingTest, VerifyHeader) {
{ scudo::ScopedTimer Outer(getTimingManager(), "Timer"); }
scudo::ScopedString Str;
getAllTimersStats(Str);

std::string Output(Str.data());
std::string Header(Output.substr(0, Output.find('\n')));
EXPECT_EQ(Header, "-- Average Operation Time -- -- Maximum Operation Time -- "
"-- Name (# of Calls) --");
}

TEST_F(ScudoTimingTest, VerifyTimerFormat) {
testCallTimers();
scudo::ScopedString Str;
getAllTimersStats(Str);
std::string Output(Str.data());

// Check the top level line, should look similar to:
// 11718.0(ns) 11718(ns) Level1 (1)
Output = Output.substr(Output.find('\n') + 1);

// Verify that the Average Operation Time is in the correct location.
EXPECT_EQ(".0(ns) ", Output.substr(14, 7));

// Verify that the Maximum Operation Time is in the correct location.
EXPECT_EQ("(ns) ", Output.substr(45, 5));

// Verify that the first timer name is in the correct location.
EXPECT_EQ("Level1 (1)\n", Output.substr(61, 11));

// Check a chained timer, should look similar to:
// 5331.0(ns) 5331(ns) Level2 (1)
Output = Output.substr(Output.find('\n') + 1);

// Verify that the Average Operation Time is in the correct location.
EXPECT_EQ(".0(ns) ", Output.substr(14, 7));

// Verify that the Maximum Operation Time is in the correct location.
EXPECT_EQ("(ns) ", Output.substr(45, 5));

// Verify that the first timer name is in the correct location.
EXPECT_EQ(" Level2 (1)\n", Output.substr(61, 13));

// Check a secondary chained timer, should look similar to:
// 814.0(ns) 814(ns) Level3 (1)
Output = Output.substr(Output.find('\n') + 1);

// Verify that the Average Operation Time is in the correct location.
EXPECT_EQ(".0(ns) ", Output.substr(14, 7));

// Verify that the Maximum Operation Time is in the correct location.
EXPECT_EQ("(ns) ", Output.substr(45, 5));

// Verify that the first timer name is in the correct location.
EXPECT_EQ(" Level3 (1)\n", Output.substr(61, 15));
}

#if SCUDO_LINUX
std::string output = testing::internal::GetCapturedStderr();
EXPECT_TRUE(output.find("Outer (1)") != std::string::npos);
EXPECT_TRUE(output.find("Inner1 (1)") != std::string::npos);
EXPECT_TRUE(output.find("Inner2 (1)") != std::string::npos);
TEST_F(ScudoTimingTest, VerifyPrintMatchesGet) {
testing::internal::LogToStderr();
testing::internal::CaptureStderr();
testCallTimers();

{ scudo::ScopedTimer Outer(getTimingManager(), "Timer"); }
printAllTimersStats();
std::string PrintOutput = testing::internal::GetCapturedStderr();
EXPECT_TRUE(PrintOutput.size() != 0);

scudo::ScopedString Str;
getAllTimersStats(Str);
std::string GetOutput(Str.data());
EXPECT_TRUE(GetOutput.size() != 0);

EXPECT_EQ(PrintOutput, GetOutput);
}
#endif

#if SCUDO_LINUX
TEST_F(ScudoTimingTest, VerifyReporting) {
testing::internal::LogToStderr();
testing::internal::CaptureStderr();
// Every 100 calls generates a report, but run a few extra to verify the
// report happened at call 100.
for (size_t i = 0; i < 110; i++)
scudo::ScopedTimer Outer(getTimingManager(), "VerifyReportTimer");

std::string Output = testing::internal::GetCapturedStderr();
EXPECT_TRUE(Output.find("VerifyReportTimer (100)") != std::string::npos);
}
#endif
48 changes: 33 additions & 15 deletions compiler-rt/lib/scudo/standalone/timing.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class TimingManager {
strncpy(Timers[NumAllocatedTimers].Name, Name, MaxLenOfTimerName);
TimerRecords[NumAllocatedTimers].AccumulatedTime = 0;
TimerRecords[NumAllocatedTimers].Occurrence = 0;
TimerRecords[NumAllocatedTimers].MaxTime = 0;
return Timer(*this, NumAllocatedTimers++);
}

Expand Down Expand Up @@ -140,36 +141,47 @@ class TimingManager {

const u32 HandleId = T.HandleId;
CHECK_LT(HandleId, MaxNumberOfTimers);
TimerRecords[HandleId].AccumulatedTime += T.getAccumulatedTime();
u64 AccTime = T.getAccumulatedTime();
TimerRecords[HandleId].AccumulatedTime += AccTime;
if (AccTime > TimerRecords[HandleId].MaxTime) {
TimerRecords[HandleId].MaxTime = AccTime;
}
++TimerRecords[HandleId].Occurrence;
++NumEventsReported;
if (NumEventsReported % PrintingInterval == 0)
printAllImpl();
if (NumEventsReported % PrintingInterval == 0) {
ScopedString Str;
getAllImpl(Str);
Str.output();
}
}

void printAll() EXCLUDES(Mutex) {
ScopedString Str;
getAll(Str);
Str.output();
}

void getAll(ScopedString &Str) EXCLUDES(Mutex) {
ScopedLock L(Mutex);
printAllImpl();
getAllImpl(Str);
}

private:
void printAllImpl() REQUIRES(Mutex) {
static char NameHeader[] = "-- Name (# of Calls) --";
void getAllImpl(ScopedString &Str) REQUIRES(Mutex) {
static char AvgHeader[] = "-- Average Operation Time --";
ScopedString Str;
Str.append("%-15s %-15s\n", AvgHeader, NameHeader);
static char MaxHeader[] = "-- Maximum Operation Time --";
static char NameHeader[] = "-- Name (# of Calls) --";
Str.append("%-15s %-15s %-15s\n", AvgHeader, MaxHeader, NameHeader);

for (u32 I = 0; I < NumAllocatedTimers; ++I) {
if (Timers[I].Nesting != MaxNumberOfTimers)
continue;
printImpl(Str, I);
getImpl(Str, I);
}

Str.output();
}

void printImpl(ScopedString &Str, const u32 HandleId,
const u32 ExtraIndent = 0) REQUIRES(Mutex) {
void getImpl(ScopedString &Str, const u32 HandleId, const u32 ExtraIndent = 0)
REQUIRES(Mutex) {
const u64 AccumulatedTime = TimerRecords[HandleId].AccumulatedTime;
const u64 Occurrence = TimerRecords[HandleId].Occurrence;
const u64 Integral = Occurrence == 0 ? 0 : AccumulatedTime / Occurrence;
Expand All @@ -179,15 +191,20 @@ class TimingManager {
Occurrence == 0 ? 0
: ((AccumulatedTime % Occurrence) * 10) / Occurrence;

Str.append("%14" PRId64 ".%" PRId64 "(ns) %-11s", Integral, Fraction, " ");
// Average time.
Str.append("%14" PRId64 ".%" PRId64 "(ns) %-8s", Integral, Fraction, " ");

// Maximum time.
Str.append("%16" PRId64 "(ns) %-11s", TimerRecords[HandleId].MaxTime, " ");

// Name and num occurrences.
for (u32 I = 0; I < ExtraIndent; ++I)
Str.append("%s", " ");
Str.append("%s (%" PRId64 ")\n", Timers[HandleId].Name, Occurrence);

for (u32 I = 0; I < NumAllocatedTimers; ++I)
if (Timers[I].Nesting == HandleId)
printImpl(Str, I, ExtraIndent + 1);
getImpl(Str, I, ExtraIndent + 1);
}

// Instead of maintaining pages for timer registration, a static buffer is
Expand All @@ -199,6 +216,7 @@ class TimingManager {
struct Record {
u64 AccumulatedTime = 0;
u64 Occurrence = 0;
u64 MaxTime = 0;
};

struct TimerInfo {
Expand Down
22 changes: 14 additions & 8 deletions compiler-rt/lib/tsan/rtl/tsan_rtl_access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,22 +672,28 @@ void MemoryAccessRangeT(ThreadState* thr, uptr pc, uptr addr, uptr size) {

#if SANITIZER_DEBUG
if (!IsAppMem(addr)) {
Printf("Access to non app mem %zx\n", addr);
Printf("Access to non app mem start: %p\n", (void*)addr);
DCHECK(IsAppMem(addr));
}
if (!IsAppMem(addr + size - 1)) {
Printf("Access to non app mem %zx\n", addr + size - 1);
Printf("Access to non app mem end: %p\n", (void*)(addr + size - 1));
DCHECK(IsAppMem(addr + size - 1));
}
if (!IsShadowMem(shadow_mem)) {
Printf("Bad shadow addr %p (%zx)\n", static_cast<void*>(shadow_mem), addr);
Printf("Bad shadow start addr: %p (%p)\n", shadow_mem, (void*)addr);
DCHECK(IsShadowMem(shadow_mem));
}
if (!IsShadowMem(shadow_mem + size * kShadowCnt - 1)) {
Printf("Bad shadow addr %p (%zx)\n",
static_cast<void*>(shadow_mem + size * kShadowCnt - 1),
addr + size - 1);
DCHECK(IsShadowMem(shadow_mem + size * kShadowCnt - 1));

RawShadow* shadow_mem_end = reinterpret_cast<RawShadow*>(
reinterpret_cast<uptr>(shadow_mem) + size * kShadowMultiplier - 1);
if (!IsShadowMem(shadow_mem_end)) {
Printf("Bad shadow end addr: %p (%p)\n", shadow_mem_end,
(void*)(addr + size - 1));
Printf(
"Shadow start addr (ok): %p (%p); size: 0x%zx; kShadowMultiplier: "
"%zx\n",
shadow_mem, (void*)addr, size, kShadowMultiplier);
DCHECK(IsShadowMem(shadow_mem_end));
}
#endif

Expand Down
54 changes: 26 additions & 28 deletions compiler-rt/lib/ubsan_minimal/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,30 @@ add_compiler_rt_object_libraries(RTUbsan_minimal
SOURCES ${UBSAN_MINIMAL_SOURCES} CFLAGS ${UBSAN_CFLAGS})


if(COMPILER_RT_HAS_UBSAN_MINIMAL)
# Standalone minimal UBSan runtimes.
add_compiler_rt_runtime(clang_rt.ubsan_minimal
STATIC
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_minimal
CFLAGS ${UBSAN_CFLAGS}
PARENT_TARGET ubsan-minimal)

add_compiler_rt_runtime(clang_rt.ubsan_minimal
SHARED
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_minimal
CFLAGS ${UBSAN_CFLAGS}
LINK_FLAGS ${UBSAN_LINK_FLAGS}
LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
PARENT_TARGET ubsan-minimal)

if (SANITIZER_USE_SYMBOLS AND NOT APPLE)
set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386 i686)
add_sanitizer_rt_symbols(clang_rt.ubsan_minimal
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan-minimal
EXTRA ubsan.syms.extra)
endif()
# Standalone minimal UBSan runtimes.
add_compiler_rt_runtime(clang_rt.ubsan_minimal
STATIC
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_minimal
CFLAGS ${UBSAN_CFLAGS}
PARENT_TARGET ubsan-minimal)

add_compiler_rt_runtime(clang_rt.ubsan_minimal
SHARED
OS ${UBSAN_SUPPORTED_OS}
ARCHS ${UBSAN_SUPPORTED_ARCH}
OBJECT_LIBS RTUbsan_minimal
CFLAGS ${UBSAN_CFLAGS}
LINK_FLAGS ${UBSAN_LINK_FLAGS}
LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
PARENT_TARGET ubsan-minimal)

if (SANITIZER_USE_SYMBOLS AND NOT APPLE)
set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386 i686)
add_sanitizer_rt_symbols(clang_rt.ubsan_minimal
ARCHS ${ARCHS_FOR_SYMBOLS}
PARENT_TARGET ubsan-minimal
EXTRA ubsan.syms.extra)
endif()
15 changes: 5 additions & 10 deletions compiler-rt/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,13 @@ umbrella_lit_testsuite_begin(check-compiler-rt)
function(compiler_rt_test_runtime runtime)
string(TOUPPER ${runtime} runtime_uppercase)
if(COMPILER_RT_HAS_${runtime_uppercase})
if (${runtime} STREQUAL scudo_standalone)
if (${runtime} STREQUAL cfi AND NOT COMPILER_RT_HAS_UBSAN)
# CFI tests require diagnostic mode, which is implemented in UBSan.
elseif (${runtime} STREQUAL scudo_standalone)
add_subdirectory(scudo/standalone)
else()
add_subdirectory(${runtime})
endif()
foreach(directory ${ARGN})
add_subdirectory(${directory})
endforeach()
endif()
endfunction()

Expand All @@ -70,8 +69,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
compiler_rt_test_runtime(interception)

compiler_rt_test_runtime(lsan)
# CFI tests require diagnostic mode, which is implemented in UBSan.
compiler_rt_test_runtime(ubsan cfi)
compiler_rt_test_runtime(ubsan)
compiler_rt_test_runtime(sanitizer_common)

# OpenBSD not supporting asan, cannot run the tests
Expand All @@ -83,10 +81,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
endif()

foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD})
# cfi testing is gated on ubsan
if(NOT ${sanitizer} STREQUAL cfi)
compiler_rt_test_runtime(${sanitizer})
endif()
compiler_rt_test_runtime(${sanitizer})
endforeach()
endif()
if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE)
Expand Down
4 changes: 1 addition & 3 deletions compiler-rt/test/cfi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ list(APPEND CFI_TEST_DEPS
ubsan
stats
)
if(COMPILER_RT_HAS_CFI)
list(APPEND CFI_TEST_DEPS cfi)
endif()
list(APPEND CFI_TEST_DEPS cfi)

if(NOT COMPILER_RT_STANDALONE_BUILD)
list(APPEND CFI_TEST_DEPS
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/gwp_asan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ set(GWP_ASAN_TEST_DEPS
# exported libc++ from the Android NDK is x86-64, even though it's part of the
# ARM[64] toolchain... See similar measures for ASan and sanitizer-common that
# disable unit tests for Android.
if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_GWP_ASAN AND NOT ANDROID)
if (COMPILER_RT_INCLUDE_TESTS AND NOT ANDROID)
list(APPEND GWP_ASAN_TEST_DEPS GwpAsanUnitTests)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg.py)
list(APPEND GWP_ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/unit)
endif()

if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE AND COMPILER_RT_HAS_GWP_ASAN)
if (COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE)
foreach(arch ${GWP_ASAN_SUPPORTED_ARCH})
set(GWP_ASAN_TEST_TARGET_ARCH ${arch})
string(TOLOWER "-${arch}" GWP_ASAN_TEST_CONFIG_SUFFIX)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/msan/Linux/sigandorset.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_msan -DLEFT_OK -std=c++11 -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_msan -DRIGHT_OK -std=c++11 -O0 -g %s -o %t && not %run %t 2<&1 | FileCheck %s
// RUN: %clangxx_msan -DRIGHT_OK -std=c++11 -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_msan -DLEFT_OK -DRIGHT_OK -std=c++11 -O0 -g %s -o %t && %run %t
// REQUIRES: !android

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/orc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if (NOT ANDROID AND NOT COMPILER_RT_STANDALONE_BUILD AND
endif()

set(ORC_TEST_ARCH ${ORC_SUPPORTED_ARCH})
if (COMPILER_RT_BUILD_ORC AND COMPILER_RT_HAS_ORC)
if (COMPILER_RT_BUILD_ORC)
list(APPEND ORC_TEST_DEPS orc)
foreach(arch ${ORC_TEST_ARCH})
set(ORC_TEST_TARGET_ARCH ${arch})
Expand Down
24 changes: 11 additions & 13 deletions compiler-rt/test/rtsan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,18 @@ if(APPLE)
darwin_filter_host_archs(RTSAN_SUPPORTED_ARCH RTSAN_TEST_ARCH)
endif()

if (COMPILER_RT_HAS_RTSAN)
foreach(arch ${RTSAN_TEST_ARCH})
set(RTSAN_TEST_TARGET_ARCH ${arch})
string(TOLOWER "-${arch}-${OS_NAME}" RTSAN_TEST_CONFIG_SUFFIX)
get_test_cc_for_arch(${arch} RTSAN_TEST_TARGET_CC RTSAN_TEST_TARGET_CFLAGS)
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
foreach(arch ${RTSAN_TEST_ARCH})
set(RTSAN_TEST_TARGET_ARCH ${arch})
string(TOLOWER "-${arch}-${OS_NAME}" RTSAN_TEST_CONFIG_SUFFIX)
get_test_cc_for_arch(${arch} RTSAN_TEST_TARGET_CC RTSAN_TEST_TARGET_CFLAGS)
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)

configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py)
list(APPEND RTSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
endforeach()
endif()
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py)
list(APPEND RTSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
endforeach()

if(COMPILER_RT_INCLUDE_TESTS)
configure_lit_site_cfg(
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/scudo/standalone/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if(COMPILER_RT_INCLUDE_TESTS AND COMPILER_RT_HAS_SCUDO_STANDALONE)
if(COMPILER_RT_INCLUDE_TESTS)
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/unit/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/unit/lit.site.cfg.py)
Expand Down
5 changes: 2 additions & 3 deletions compiler-rt/test/xray/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ set(XRAY_FDR_TESTSUITES)

set(XRAY_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} xray)

if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_BUILD_XRAY AND
COMPILER_RT_HAS_XRAY)
if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_BUILD_XRAY)
list(APPEND XRAY_TEST_DEPS llvm-xray)
endif()

set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH})
if (COMPILER_RT_BUILD_XRAY AND COMPILER_RT_HAS_XRAY)
if (COMPILER_RT_BUILD_XRAY)
foreach(arch ${XRAY_TEST_ARCH})
set(XRAY_TEST_TARGET_ARCH ${arch})
string(TOLOWER "-${arch}-${OS_NAME}" XRAY_TEST_CONFIG_SUFFIX)
Expand Down
5 changes: 3 additions & 2 deletions flang/docs/Intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ MALLOC
```
CALL FDATE(TIME)
CALL GETLOG(USRNAME)
CALL GETENV(NAME [, VALUE, LENGTH, STATUS, TRIM_NAME, ERRMSG ])
```

## Intrinsic Procedure Name Resolution
Expand Down Expand Up @@ -768,7 +769,7 @@ This phase currently supports all the intrinsic procedures listed above but the
| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SIGNAL, SLEEP, SYSTEM, SYSTEM_CLOCK |
| Atomic intrinsic subroutines | ATOMIC_ADD |
| Collective intrinsic subroutines | CO_REDUCE |
| Library subroutines | FDATE, GETLOG |
| Library subroutines | FDATE, GETLOG, GETENV |


### Intrinsic Function Folding
Expand Down Expand Up @@ -999,4 +1000,4 @@ PROGRAM example_getcwd
PRINT *, cwd
PRINT *, status
END PROGRAM
```
```
7 changes: 5 additions & 2 deletions flang/lib/Evaluate/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
// compatibility and builtins.
static const std::pair<const char *, const char *> genericAlias[]{
{"and", "iand"},
{"getenv", "get_environment_variable"},
{"imag", "aimag"},
{"lshift", "shiftl"},
{"or", "ior"},
Expand Down Expand Up @@ -2594,7 +2595,8 @@ bool IntrinsicProcTable::Implementation::IsIntrinsicFunction(
return name == "__builtin_c_loc" || name == "null";
}
bool IntrinsicProcTable::Implementation::IsIntrinsicSubroutine(
const std::string &name) const {
const std::string &name0) const {
const std::string &name{ResolveAlias(name0)};
auto subrRange{subroutines_.equal_range(name)};
if (subrRange.first != subrRange.second) {
return true;
Expand Down Expand Up @@ -3151,7 +3153,8 @@ std::optional<SpecificCall> IntrinsicProcTable::Implementation::Probe(
}

if (call.isSubroutineCall) {
auto subrRange{subroutines_.equal_range(call.name)};
const std::string &name{ResolveAlias(call.name)};
auto subrRange{subroutines_.equal_range(name)};
for (auto iter{subrRange.first}; iter != subrRange.second; ++iter) {
if (auto specificCall{iter->second->Match(
call, defaults_, arguments, context, builtinsScope_)}) {
Expand Down
6 changes: 4 additions & 2 deletions flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertBoxedSequenceType(

offset += dimsSize;
mlir::LLVM::DISubrangeAttr subrangeTy = mlir::LLVM::DISubrangeAttr::get(
context, nullptr, lowerAttr, countAttr, nullptr);
context, countAttr, lowerAttr, /*upperBound=*/nullptr,
/*stride=*/nullptr);
elements.push_back(subrangeTy);
}
return mlir::LLVM::DICompositeTypeAttr::get(
Expand Down Expand Up @@ -183,7 +184,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim));
auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, 1));
auto subrangeTy = mlir::LLVM::DISubrangeAttr::get(
context, countAttr, lowerAttr, nullptr, nullptr);
context, countAttr, lowerAttr, /*upperBound=*/nullptr,
/*stride=*/nullptr);
elements.push_back(subrangeTy);
}
}
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Integration/debug-assumed-shape-array.f90
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ end subroutine ff

! CHECK-DAG: !DICompositeType(tag: DW_TAG_array_type{{.*}}elements: ![[ELEMS:[0-9]+]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
! CHECK-DAG: ![[ELEMS]] = !{![[ELEM1:[0-9]+]], ![[ELEM2:[0-9]+]]}
! CHECK-DAG: ![[ELEM1]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref))
! CHECK-DAG: ![[ELEM2]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
! CHECK-DAG: ![[ELEM1]] = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 32, DW_OP_deref), lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 24, DW_OP_deref))
! CHECK-DAG: ![[ELEM2]] = !DISubrange(count: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref), lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref))

Loading