18 changes: 9 additions & 9 deletions clang/test/Driver/windows-cross.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@
// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libstdc++ -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-RTLIB

// CHECK-RTLIB: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-RTLIB: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins.lib"

// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-C-LIBCXX

// CHECK-C-LIBCXX: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-C-LIBCXX: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins.lib"

// RUN: %clangxx -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libc++ -o /dev/null %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-LIBCXX

// CHECK-LIBCXX: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lc++" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-LIBCXX: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{.*}}.o" "-lc++" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins.lib"

// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -o shared.dll %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-SHARED

// CHECK-SHARED: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-SHARED: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins.lib"

// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -static -o shared.dll %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-SHARED-STATIC

// CHECK-SHARED-STATIC: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bstatic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-SHARED-STATIC: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bstatic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins.lib"

// RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -o shared.dll %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-NOSTARTFILES

// CHECK-NOSTARTFILES: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
// CHECK-NOSTARTFILES: {{[/\\]}}ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins.lib"

// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -nodefaultlibs -o shared.dll %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-STANDALONE
Expand All @@ -52,19 +52,19 @@
// RUN: | FileCheck %s --check-prefix CHECK-SANITIZE-ADDRESS

// CHECK-SANITIZE-ADDRESS: "-fsanitize=address"
// CHECK-SANITIZE-ADDRESS: "{{.*}}clang_rt.asan_dll_thunk-arm.lib"
// CHECK-SANITIZE-ADDRESS: "{{.*}}clang_rt.asan_dll_thunk.lib"

// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=lld-link2 -o test.exe -fsanitize=address -x c++ %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-SANITIZE-ADDRESS-EXE

// CHECK-SANITIZE-ADDRESS-EXE: "-fsanitize=address"
// CHECK-SANITIZE-ADDRESS-EXE: "{{.*}}clang_rt.asan_dynamic-arm.lib" "{{.*}}clang_rt.asan_dynamic_runtime_thunk-arm.lib" "--undefined" "__asan_seh_interceptor"
// CHECK-SANITIZE-ADDRESS-EXE: "{{.*}}clang_rt.asan_dynamic.lib" "{{.*}}clang_rt.asan_dynamic_runtime_thunk.lib" "--undefined" "__asan_seh_interceptor"

// RUN: %clang -### -target i686-windows-itanium -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=lld-link2 -o test.exe -fsanitize=address -x c++ %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-SANITIZE-ADDRESS-EXE-X86

// CHECK-SANITIZE-ADDRESS-EXE-X86: "-fsanitize=address"
// CHECK-SANITIZE-ADDRESS-EXE-X86: "{{.*}}clang_rt.asan_dynamic-i386.lib" "{{.*}}clang_rt.asan_dynamic_runtime_thunk-i386.lib" "--undefined" "___asan_seh_interceptor"
// CHECK-SANITIZE-ADDRESS-EXE-X86: "{{.*}}clang_rt.asan_dynamic.lib" "{{.*}}clang_rt.asan_dynamic_runtime_thunk.lib" "--undefined" "___asan_seh_interceptor"

// RUN: not %clang -### --target=armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=lld-link2 -shared -o shared.dll -fsanitize=tsan -x c++ %s 2>&1 \
// RUN: | FileCheck %s --check-prefix CHECK-SANITIZE-TSAN
Expand Down
12 changes: 6 additions & 6 deletions clang/test/Driver/zos-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// C-LD-SAME: "-S" "//'SYS1.CSSLIB'"
// C-LD-SAME: "//'CEE.SCEELIB(CELQS001)'"
// C-LD-SAME: "//'CEE.SCEELIB(CELQS003)'"
// C-LD-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}zos{{/|\\\\}}libclang_rt.builtins-s390x.a"
// C-LD-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}s390x-ibm-zos{{/|\\\\}}libclang_rt.builtins.a"

// 2. General C link for dll
// RUN: %clang -### --shared --target=s390x-ibm-zos %s 2>&1 \
Expand All @@ -30,7 +30,7 @@
// C-LD-DLL-SAME: "-S" "//'SYS1.CSSLIB'"
// C-LD-DLL-SAME: "//'CEE.SCEELIB(CELQS001)'"
// C-LD-DLL-SAME: "//'CEE.SCEELIB(CELQS003)'"
// C-LD-DLL-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}zos{{/|\\\\}}libclang_rt.builtins-s390x.a"
// C-LD-DLL-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}s390x-ibm-zos{{/|\\\\}}libclang_rt.builtins.a"

// 3. General C++ link for executable
// RUN: %clangxx -### --target=s390x-ibm-zos %s 2>&1 \
Expand All @@ -52,7 +52,7 @@
// CXX-LD-SAME: "//'CEE.SCEELIB(CRTDQCXA)'"
// CXX-LD-SAME: "//'CEE.SCEELIB(CRTDQXLA)'"
// CXX-LD-SAME: "//'CEE.SCEELIB(CRTDQUNW)'"
// CXX-LD-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}zos{{/|\\\\}}libclang_rt.builtins-s390x.a"
// CXX-LD-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}s390x-ibm-zos{{/|\\\\}}libclang_rt.builtins.a"

// 4. General C++ link for dll
// RUN: %clangxx -### --shared --target=s390x-ibm-zos %s 2>&1 \
Expand All @@ -74,7 +74,7 @@
// CXX-LD-DLL-SAME: "//'CEE.SCEELIB(CRTDQCXA)'"
// CXX-LD-DLL-SAME: "//'CEE.SCEELIB(CRTDQXLA)'"
// CXX-LD-DLL-SAME: "//'CEE.SCEELIB(CRTDQUNW)'"
// CXX-LD-DLL-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}zos{{/|\\\\}}libclang_rt.builtins-s390x.a"
// CXX-LD-DLL-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}s390x-ibm-zos{{/|\\\\}}libclang_rt.builtins.a"

// 5. C++ link for executable w/ -mzos-hlq-le=, -mzos-hlq-csslib=
// RUN: %clangxx -### --target=s390x-ibm-zos %s 2>&1 \
Expand All @@ -97,7 +97,7 @@
// CXX-LD5-SAME: "//'AAAA.SCEELIB(CRTDQCXA)'"
// CXX-LD5-SAME: "//'AAAA.SCEELIB(CRTDQXLA)'"
// CXX-LD5-SAME: "//'AAAA.SCEELIB(CRTDQUNW)'"
// CXX-LD5-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}zos{{/|\\\\}}libclang_rt.builtins-s390x.a"
// CXX-LD5-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}s390x-ibm-zos{{/|\\\\}}libclang_rt.builtins.a"

// 6. C++ link for executable w/ -mzos-hlq-clang=
// RUN: %clangxx -### --target=s390x-ibm-zos %s 2>&1 \
Expand All @@ -120,4 +120,4 @@
// CXX-LD6-SAME: "//'AAAA.SCEELIB(CRTDQCXA)'"
// CXX-LD6-SAME: "//'AAAA.SCEELIB(CRTDQXLA)'"
// CXX-LD6-SAME: "//'AAAA.SCEELIB(CRTDQUNW)'"
// CXX-LD6-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}zos{{/|\\\\}}libclang_rt.builtins-s390x.a"
// CXX-LD6-SAME: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}s390x-ibm-zos{{/|\\\\}}libclang_rt.builtins.a"
2 changes: 1 addition & 1 deletion clang/test/Lexer/cxx-features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
#error "wrong value for __cpp_char8_t"
#endif

#if check(concepts, 0, 0, 0, 0, 201907, 201907, 201907)
#if check(concepts, 0, 0, 0, 0, 202002, 202002, 202002)
#error "wrong value for __cpp_concepts"
#endif

Expand Down
3 changes: 1 addition & 2 deletions clang/test/Misc/warning-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This test serves two purposes:

The list of warnings below should NEVER grow. It should gradually shrink to 0.

CHECK: Warnings without flags (67):
CHECK: Warnings without flags (66):

CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: ext_explicit_specialization_storage_class
Expand Down Expand Up @@ -80,7 +80,6 @@ CHECK-NEXT: warn_register_objc_catch_parm
CHECK-NEXT: warn_related_result_type_compatibility_class
CHECK-NEXT: warn_related_result_type_compatibility_protocol
CHECK-NEXT: warn_template_export_unsupported
CHECK-NEXT: warn_tentative_incomplete_array
CHECK-NEXT: warn_typecheck_function_qualifiers
CHECK-NEXT: warn_undef_interface
CHECK-NEXT: warn_undef_interface_suggest
Expand Down
8 changes: 4 additions & 4 deletions clang/test/OpenMP/assumes_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ int lambda_outer() {
}
#pragma omp end assumes

// AST: __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void foo() {
// AST: void foo() __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) {
// AST-NEXT: }
// AST-NEXT: class BAR {
// AST-NEXT: public:
Expand All @@ -81,7 +81,7 @@ int lambda_outer() {
// AST-NEXT: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void bar() {
// AST-NEXT: BAR b;
// AST-NEXT: }
// AST-NEXT: void baz() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")));
// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz();
// AST-NEXT: template <typename T> class BAZ {
// AST-NEXT: public:
// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAZ<T>() {
Expand All @@ -95,8 +95,8 @@ int lambda_outer() {
// AST-NEXT: public:
// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAZ() {
// AST-NEXT: }
// AST-NEXT: void baz1() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")));
// AST-NEXT: static void baz2() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")));
// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz1();
// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) static void baz2();
// AST-NEXT: };
// AST-NEXT: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz() {
// AST-NEXT: BAZ<float> b;
Expand Down
2 changes: 1 addition & 1 deletion clang/test/OpenMP/assumes_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void baz() {
}
#pragma omp end assumes

// CHECK: __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void foo()
// CHECK: void foo() __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp")))
// CHECK: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void bar()
// CHECK: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void baz()

Expand Down
10 changes: 5 additions & 5 deletions clang/test/OpenMP/assumes_template_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ template <typename T>
struct S {
int a;
// CHECK: template <typename T> struct S {
// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() {
// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) {
void foo() {
#pragma omp parallel
{}
}
};

// CHECK: template<> struct S<int> {
// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() {
// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) {

#pragma omp begin assumes no_openmp
// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void S_with_assumes_no_call() {
// CHECK: __attribute__((assume("omp_no_openmp"))) void S_with_assumes_no_call() __attribute__((assume("ompx_global_assumption"))) {
void S_with_assumes_no_call() {
S<int> s;
s.a = 0;
}
// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void S_with_assumes_call() {
// CHECK: __attribute__((assume("omp_no_openmp"))) void S_with_assumes_call() __attribute__((assume("ompx_global_assumption"))) {
void S_with_assumes_call() {
S<int> s;
s.a = 0;
Expand All @@ -42,7 +42,7 @@ void S_with_assumes_call() {
}
#pragma omp end assumes

// CHECK: __attribute__((assume("ompx_global_assumption"))) void S_without_assumes() {
// CHECK: void S_without_assumes() __attribute__((assume("ompx_global_assumption"))) {
void S_without_assumes() {
S<int> s;
s.foo();
Expand Down
4 changes: 2 additions & 2 deletions clang/test/OpenMP/declare_simd_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ void h(int *hp, int *hp2, int *hq, int *lin)

class VV {
// CHECK: #pragma omp declare simd uniform(this, a) linear(val(b): a)
// CHECK-NEXT: __attribute__((cold)) int add(int a, int b) {
// CHECK-NEXT: int add(int a, int b) __attribute__((cold)) {
// CHECK-NEXT: return a + b;
// CHECK-NEXT: }
#pragma omp declare simd uniform(this, a) linear(val(b): a)
__attribute__((cold)) int add(int a, int b) { return a + b; }
int add(int a, int b) __attribute__((cold)) { return a + b; }

// CHECK: #pragma omp declare simd aligned(b: 4) aligned(a) linear(ref(b): 4) linear(val(this)) linear(val(a))
// CHECK-NEXT: float taddpf(float *a, float *&b) {
Expand Down
35 changes: 35 additions & 0 deletions clang/test/PCH/cxx23-deducing-this-lambda.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// RUN: %clang_cc1 -emit-pch -std=c++23 -o %t %s
// RUN: %clang_cc1 -include-pch %t -verify -fsyntax-only -DTEST -std=c++23 %s

// Test that dependence of 'this' and DREs due to by-value capture by a
// lambda with an explicit object parameter is serialised/deserialised
// properly.

#ifndef HEADER
#define HEADER
struct S {
int x;
auto f() {
return [*this] (this auto&&) {
int y;
x = 42;

const auto l = [y] (this auto&&) { y = 42; };
l();
};
}
};
#endif

// expected-error@* {{read-only variable is not assignable}}
// expected-error@* {{cannot assign to a variable captured by copy in a non-mutable lambda}}
// expected-note@* 2 {{in instantiation of}}

#ifdef TEST
void f() {
const auto l = S{}.f();
l(); // expected-note {{in instantiation of}}
}
#endif


5 changes: 5 additions & 0 deletions clang/test/Sema/tentative-array-decl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: %clang_cc1 -verify %s
// RUN: %clang_cc1 -verify=good -Wno-tentative-definition-array %s
// good-no-diagnostics

int foo[]; // expected-warning {{tentative array definition assumed to have one element}}
6 changes: 3 additions & 3 deletions clang/test/SemaCXX/attr-no-sanitize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ int f3() __attribute__((no_sanitize("address")));

// DUMP-LABEL: FunctionDecl {{.*}} f4
// DUMP: NoSanitizeAttr {{.*}} thread
// PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]]
// PRINT: {{\[\[}}clang::no_sanitize("thread")]] int f4()
[[clang::no_sanitize("thread")]] int f4();

// DUMP-LABEL: FunctionDecl {{.*}} f4
// DUMP: NoSanitizeAttr {{.*}} hwaddress
// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]]
// PRINT: {{\[\[}}clang::no_sanitize("hwaddress")]] int f4()
[[clang::no_sanitize("hwaddress")]] int f4();

// DUMP-LABEL: FunctionDecl {{.*}} f5
Expand All @@ -36,5 +36,5 @@ int f6() __attribute__((no_sanitize("unknown"))); // expected-warning{{unknown s

// DUMP-LABEL: FunctionDecl {{.*}} f7
// DUMP: NoSanitizeAttr {{.*}} memtag
// PRINT: int f7() {{\[\[}}clang::no_sanitize("memtag")]]
// PRINT: {{\[\[}}clang::no_sanitize("memtag")]] int f7()
[[clang::no_sanitize("memtag")]] int f7();
8 changes: 4 additions & 4 deletions clang/test/SemaCXX/cxx11-attr-print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ int d [[deprecated("warning")]];
// CHECK: __attribute__((deprecated("warning", "fixit")));
int e __attribute__((deprecated("warning", "fixit")));

// CHECK: int cxx11_alignas alignas(4);
// CHECK: alignas(4) int cxx11_alignas;
alignas(4) int cxx11_alignas;

// CHECK: int c11_alignas _Alignas(int);
// CHECK: _Alignas(int) int c11_alignas;
_Alignas(int) int c11_alignas;

// CHECK: int foo() __attribute__((const));
Expand Down Expand Up @@ -66,7 +66,7 @@ void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
// CHECK: int n alignas(4
// CHECK: int p alignas(int
// CHECK: __attribute__((pure)) static int f()
// CHECK: static int g() {{\[}}[gnu::pure]]
// CHECK: {{\[}}[gnu::pure]] static int g()
template <typename T> struct S {
__attribute__((aligned(4))) int m;
alignas(4) int n;
Expand All @@ -82,7 +82,7 @@ template <typename T> struct S {
// CHECK: int m __attribute__((aligned(4
// CHECK: int n alignas(4
// CHECK: __attribute__((pure)) static int f()
// CHECK: static int g() {{\[}}[gnu::pure]]
// CHECK: {{\[}}[gnu::pure]] static int g()
template struct S<int>;

// CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int;
Expand Down
176 changes: 176 additions & 0 deletions clang/test/SemaCXX/cxx2b-deducing-this.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,118 @@ void TestMutationInLambda() {
[i = 0](this auto){ i++; }();
[i = 0](this const auto&){ i++; }();
// expected-error@-1 {{cannot assign to a variable captured by copy in a non-mutable lambda}}
// expected-note@-2 {{in instantiation of}}

int x;
const auto l1 = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
const auto l2 = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}

const auto l3 = [&x](this auto&) {
const auto l3a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l3a(); // expected-note {{in instantiation of}}
};

const auto l4 = [&x](this auto&) {
const auto l4a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l4a(); // expected-note {{in instantiation of}}
};

const auto l5 = [x](this auto&) {
const auto l5a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l5a(); // expected-note {{in instantiation of}}
};

const auto l6 = [=](this auto&) {
const auto l6a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l6a(); // expected-note {{in instantiation of}}
};

const auto l7 = [x](this auto&) {
const auto l7a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l7a(); // expected-note {{in instantiation of}}
};

const auto l8 = [=](this auto&) {
const auto l8a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l8a(); // expected-note {{in instantiation of}}
};

const auto l9 = [&](this auto&) {
const auto l9a = [x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l9a(); // expected-note {{in instantiation of}}
};

const auto l10 = [&](this auto&) {
const auto l10a = [=](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
l10a(); // expected-note {{in instantiation of}}
};

const auto l11 = [x](this auto&) {
const auto l11a = [&x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} expected-note {{while substituting}}
l11a();
};

const auto l12 = [x](this auto&) {
const auto l12a = [&](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} expected-note {{while substituting}}
l12a();
};

const auto l13 = [=](this auto&) {
const auto l13a = [&x](this auto&) { x = 42; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}} expected-note {{while substituting}}
l13a();
};

struct S {
int x;
auto f() {
return [*this] (this auto&&) {
x = 42; // expected-error {{read-only variable is not assignable}}
[*this] () mutable { x = 42; } ();
[*this] (this auto&&) { x = 42; } ();
[*this] () { x = 42; } (); // expected-error {{read-only variable is not assignable}}
const auto l = [*this] (this auto&&) { x = 42; }; // expected-error {{read-only variable is not assignable}}
l(); // expected-note {{in instantiation of}}

struct T {
int x;
auto g() {
return [&] (this auto&&) {
x = 42;
const auto l = [*this] (this auto&&) { x = 42; }; // expected-error {{read-only variable is not assignable}}
l(); // expected-note {{in instantiation of}}
};
}
};

const auto l2 = T{}.g();
l2(); // expected-note {{in instantiation of}}
};
}
};

const auto l14 = S{}.f();

l1(); // expected-note {{in instantiation of}}
l2(); // expected-note {{in instantiation of}}
l3(); // expected-note {{in instantiation of}}
l4(); // expected-note {{in instantiation of}}
l5(); // expected-note {{in instantiation of}}
l6(); // expected-note {{in instantiation of}}
l7(); // expected-note {{in instantiation of}}
l8(); // expected-note {{in instantiation of}}
l9(); // expected-note {{in instantiation of}}
l10(); // expected-note {{in instantiation of}}
l11(); // expected-note {{in instantiation of}}
l12(); // expected-note {{in instantiation of}}
l13(); // expected-note {{in instantiation of}}
l14(); // expected-note 3 {{in instantiation of}}

{
const auto l1 = [&x](this auto&) { x = 42; };
const auto l2 = [&](this auto&) { x = 42; };
l1();
l2();
}
}

struct Over_Call_Func_Example {
Expand Down Expand Up @@ -650,3 +762,67 @@ int bug() {
S{}.f(0);
}
}

namespace GH84163 {
struct S {
int x;

auto foo() {
return [*this](this auto&&) {
x = 10; // expected-error {{read-only variable is not assignable}}
};
}
};

int f() {
S s{ 5 };
const auto l = s.foo();
l(); // expected-note {{in instantiation of}}

const auto g = [x = 10](this auto&& self) { x = 20; }; // expected-error {{cannot assign to a variable captured by copy in a non-mutable lambda}}
g(); // expected-note {{in instantiation of}}
}
}

namespace GH86054 {
template<typename M>
struct unique_lock {
unique_lock(M&) {}
};
int f() {
struct mutex {} cursor_guard;
[&cursor_guard](this auto self) {
unique_lock a(cursor_guard);
}();
}
}

namespace GH86398 {
struct function {}; // expected-note 2 {{not viable}}
int f() {
function list;
[&list](this auto self) {
list = self; // expected-error {{no viable overloaded '='}}
}(); // expected-note {{in instantiation of}}
}

struct function2 {
function2& operator=(function2 const&) = delete; // expected-note {{candidate function not viable}}
};
int g() {
function2 list;
[&list](this auto self) {
list = self; // expected-error {{no viable overloaded '='}}
}(); // expected-note {{in instantiation of}}
}

struct function3 {
function3& operator=(function3 const&) = delete; // expected-note {{has been explicitly deleted}}
};
int h() {
function3 list;
[&list](this auto self) {
list = function3{}; // expected-error {{selected deleted operator '='}}
}();
}
}
67 changes: 67 additions & 0 deletions clang/test/SemaTemplate/instantiate-pure-virtual-function.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-func-template %s

namespace GH74016 {
template <typename T> class B {
public:
constexpr void foo(const T &) { bar(1); }
virtual constexpr void bar(unsigned int) = 0;
};

template <typename T> class D : public B<T> {
public:
constexpr void bar(unsigned int) override {}
};

void test() {
auto t = D<int>();
t.foo(0);
}
};

namespace call_pure_virtual_function_from_virtual {
template <typename T> class B {
public:
const void foo(const T &) { B::bar(1); } // expected-warning {{instantiation of function 'call_pure_virtual_function_from_virtual::B<int>::bar' required here, but no definition is available}}
// expected-note@-1 {{add an explicit instantiation declaration to suppress this warning if 'call_pure_virtual_function_from_virtual::B<int>::bar' is explicitly instantiated in another translation unit}}
virtual const void bar(unsigned int) = 0; // expected-note {{forward declaration of template entity is here}}
};

template <typename T> class D : public B<T> {
public:
const void bar(unsigned int) override {}
};

void test() {
auto t = D<int>();
t.foo(0); // expected-note {{in instantiation of member function 'call_pure_virtual_function_from_virtual::B<int>::foo' requested here}}
}
};

namespace non_pure_virtual_function {
template <typename T> class B {
public:
constexpr void foo(const T &) { bar(1); }

virtual constexpr void bar(unsigned int); // expected-warning {{inline function 'non_pure_virtual_function::B<int>::bar' is not defined}}
// expected-note@-1 {{forward declaration of template entity is here}}
// expected-note@-2 {{forward declaration of template entity is here}}
// expected-note@-3 {{forward declaration of template entity is here}}
};

template <typename T> class D : public B<T> { // expected-warning {{instantiation of function 'non_pure_virtual_function::B<int>::bar' required here, but no definition is available}}
// expected-warning@-1 {{instantiation of function 'non_pure_virtual_function::B<int>::bar' required here, but no definition is available}}
// expected-warning@-2 {{instantiation of function 'non_pure_virtual_function::B<int>::bar' required here, but no definition is available}}
// expected-note@-3 {{add an explicit instantiation declaration to suppress this warning if 'non_pure_virtual_function::B<int>::bar' is explicitly instantiated in another translation unit}}
// expected-note@-4 {{add an explicit instantiation declaration to suppress this warning if 'non_pure_virtual_function::B<int>::bar' is explicitly instantiated in another translation unit}}
// expected-note@-5 {{add an explicit instantiation declaration to suppress this warning if 'non_pure_virtual_function::B<int>::bar' is explicitly instantiated in another translation unit}}
// expected-note@-6 {{used here}}

public:
constexpr void bar(unsigned int) override { }
};

void test() {
auto t = D<int>();
t.foo(0);
}
};
44 changes: 41 additions & 3 deletions clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -Wno-unused-value -verify %s
// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -Wno-unused-value -verify %s

// expected-no-diagnostics
class A {
public:
template<class U> A(U p) {}
Expand Down Expand Up @@ -76,3 +75,42 @@ struct S {
int f<0>(int);
};
}

namespace UsesThis {
template<typename T>
struct A {
int x;

template<typename U>
static void f();

template<>
void f<int>() {
this->x; // expected-error {{invalid use of 'this' outside of a non-static member function}}
x; // expected-error {{invalid use of member 'x' in static member function}}
A::x; // expected-error {{invalid use of member 'x' in static member function}}
+x; // expected-error {{invalid use of member 'x' in static member function}}
+A::x; // expected-error {{invalid use of member 'x' in static member function}}
}

template<typename U>
void g();

template<>
void g<int>() {
this->x;
x;
A::x;
+x;
+A::x;
}

template<typename U>
static auto h() -> A*;

template<>
auto h<int>() -> decltype(this); // expected-error {{'this' cannot be used in a static member function declaration}}
};

template struct A<int>; // expected-note 2{{in instantiation of}}
}
1 change: 1 addition & 0 deletions clang/unittests/AST/Interp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_clang_unittest(InterpTests
Descriptor.cpp
toAPValue.cpp
)

clang_target_link_libraries(InterpTests
Expand Down
90 changes: 90 additions & 0 deletions clang/unittests/AST/Interp/toAPValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "../../../lib/AST/Interp/Context.h"
#include "../../../lib/AST/Interp/Descriptor.h"
#include "../../../lib/AST/Interp/Program.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"

using namespace clang;
using namespace clang::interp;
using namespace clang::ast_matchers;

/// Test the various toAPValue implementations.
TEST(ToAPValue, Pointers) {
constexpr char Code[] =
"struct A { bool a; bool z; };\n"
"struct S {\n"
" A a[3];\n"
"};\n"
"constexpr S d = {{{true, false}, {false, true}, {false, false}}};\n"
"constexpr const bool *b = &d.a[1].z;\n";

auto AST = tooling::buildASTFromCodeWithArgs(
Code, {"-fexperimental-new-constant-interpreter"});

auto &Ctx = AST->getASTContext().getInterpContext();
Program &Prog = Ctx.getProgram();

auto getDecl = [&](const char *Name) -> const ValueDecl * {
auto Nodes =
match(valueDecl(hasName(Name)).bind("var"), AST->getASTContext());
assert(Nodes.size() == 1);
const auto *D = Nodes[0].getNodeAs<ValueDecl>("var");
assert(D);
return D;
};
auto getGlobalPtr = [&](const char *Name) -> Pointer {
const VarDecl *D = cast<VarDecl>(getDecl(Name));
return Prog.getPtrGlobal(*Prog.getGlobal(D));
};

const Pointer &GP = getGlobalPtr("b");
const Pointer &P = GP.deref<Pointer>();
ASSERT_TRUE(P.isLive());
APValue A = P.toAPValue();
ASSERT_TRUE(A.isLValue());
ASSERT_TRUE(A.hasLValuePath());
const auto &Path = A.getLValuePath();
ASSERT_EQ(Path.size(), 3u);
ASSERT_EQ(A.getLValueBase(), getDecl("d"));
}

TEST(ToAPValue, FunctionPointers) {
constexpr char Code[] = " constexpr bool foo() { return true; }\n"
" constexpr bool (*func)() = foo;\n";

auto AST = tooling::buildASTFromCodeWithArgs(
Code, {"-fexperimental-new-constant-interpreter"});

auto &Ctx = AST->getASTContext().getInterpContext();
Program &Prog = Ctx.getProgram();

auto getDecl = [&](const char *Name) -> const ValueDecl * {
auto Nodes =
match(valueDecl(hasName(Name)).bind("var"), AST->getASTContext());
assert(Nodes.size() == 1);
const auto *D = Nodes[0].getNodeAs<ValueDecl>("var");
assert(D);
return D;
};

auto getGlobalPtr = [&](const char *Name) -> Pointer {
const VarDecl *D = cast<VarDecl>(getDecl(Name));
return Prog.getPtrGlobal(*Prog.getGlobal(D));
};

const Pointer &GP = getGlobalPtr("func");
const FunctionPointer &FP = GP.deref<FunctionPointer>();
ASSERT_FALSE(FP.isZero());
APValue A = FP.toAPValue();
ASSERT_TRUE(A.hasValue());
ASSERT_TRUE(A.isLValue());
ASSERT_TRUE(A.hasLValuePath());
const auto &Path = A.getLValuePath();
ASSERT_EQ(Path.size(), 0u);
ASSERT_FALSE(A.getLValueBase().isNull());
ASSERT_EQ(A.getLValueBase().dyn_cast<const ValueDecl *>(), getDecl("foo"));
}
2 changes: 2 additions & 0 deletions clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2321,6 +2321,8 @@ TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureOfVarDecl) {
matches("int main() { int cc; auto f = [=](){ return cc; }; }", matcher));
EXPECT_TRUE(
matches("int main() { int cc; auto f = [&](){ return cc; }; }", matcher));
EXPECT_TRUE(matches(
"void f(int a) { int cc[a]; auto f = [&](){ return cc;}; }", matcher));
}

TEST_P(ASTMatchersTest, LambdaCaptureTest_BindsToCaptureWithInitializer) {
Expand Down
50 changes: 24 additions & 26 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7977,39 +7977,37 @@ TEST_F(FormatTest, AllowAllArgumentsOnNextLineDontAlign) {
}

TEST_F(FormatTest, BreakFunctionDefinitionParameters) {
FormatStyle Style = getLLVMStyle();
EXPECT_FALSE(Style.BreakFunctionDefinitionParameters);
StringRef Input = "void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(int A, int B, int C) {}\n"
"Class::Class(int A, int B) : m_A(A), m_B(B) {}\n";
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(int A, int B, int C) {}\n"
"Class::Class(int A, int B) : m_A(A), m_B(B) {}\n"),
Input, Style);
"Class::Class(int A, int B) : m_A(A), m_B(B) {}";
verifyFormat(Input);

FormatStyle Style = getLLVMStyle();
EXPECT_FALSE(Style.BreakFunctionDefinitionParameters);
Style.BreakFunctionDefinitionParameters = true;
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(\n"
" int A, int B, int C) {}\n"
"Class::Class(\n"
" int A, int B)\n"
" : m_A(A), m_B(B) {}\n"),
verifyFormat("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(\n"
" int A, int B, int C) {}\n"
"Class::Class(\n"
" int A, int B)\n"
" : m_A(A), m_B(B) {}",
Input, Style);
// Test the style where all parameters are on their own lines

// Test the style where all parameters are on their own lines.
Style.AllowAllParametersOfDeclarationOnNextLine = false;
Style.BinPackParameters = false;
verifyFormat(StringRef("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(\n"
" int A,\n"
" int B,\n"
" int C) {}\n"
"Class::Class(\n"
" int A,\n"
" int B)\n"
" : m_A(A), m_B(B) {}\n"),
verifyFormat("void functionDecl(paramA, paramB, paramC);\n"
"void emptyFunctionDefinition() {}\n"
"void functionDefinition(\n"
" int A,\n"
" int B,\n"
" int C) {}\n"
"Class::Class(\n"
" int A,\n"
" int B)\n"
" : m_A(A), m_B(B) {}",
Input, Style);
}

Expand Down
103 changes: 51 additions & 52 deletions clang/unittests/Format/FormatTestTableGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ TEST_F(FormatTestTableGen, LiteralsAndIdentifiers) {
" let 0startID = $TokVarName;\n"
" let 0xstartInteger = 0x42;\n"
" let someIdentifier = $TokVarName;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, BangOperators) {
Expand Down Expand Up @@ -101,22 +101,22 @@ TEST_F(FormatTestTableGen, BangOperators) {
" \"zerozero\",\n"
" true: // default\n"
" \"positivepositive\");\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, Include) {
verifyFormat("include \"test/IncludeFile.h\"\n");
verifyFormat("include \"test/IncludeFile.h\"");
}

TEST_F(FormatTestTableGen, Types) {
verifyFormat("def Types : list<int>, bits<3>, list<list<string>> {}\n");
verifyFormat("def Types : list<int>, bits<3>, list<list<string>> {}");
}

TEST_F(FormatTestTableGen, SimpleValue1_SingleLiterals) {
verifyFormat("def SimpleValue {\n"
" let Integer = 42;\n"
" let String = \"some string\";\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, SimpleValue1_MultilineString) {
Expand All @@ -129,7 +129,7 @@ TEST_F(FormatTestTableGen, SimpleValue1_MultilineString) {
"delimited by \\[{ and }\\]. It can break across lines and the line "
"breaks are retained in the string. \n"
"(https://llvm.org/docs/TableGen/ProgRef.html#grammar-token-TokCode)}];\n"
"}\n";
"}";
StringRef DefWithCodeMessedUp =
"def SimpleValueCode { let \n"
"Code= \n"
Expand All @@ -139,23 +139,23 @@ TEST_F(FormatTestTableGen, SimpleValue1_MultilineString) {
"breaks are retained in the string. \n"
"(https://llvm.org/docs/TableGen/ProgRef.html#grammar-token-TokCode)}] \n"
" ; \n"
" } \n";
" } ";
verifyFormat(DefWithCode, DefWithCodeMessedUp);
}

TEST_F(FormatTestTableGen, SimpleValue2) {
verifyFormat("def SimpleValue2 {\n"
" let True = true;\n"
" let False = false;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, SimpleValue3) {
verifyFormat("class SimpleValue3<int x> { int Question = ?; }\n");
verifyFormat("class SimpleValue3<int x> { int Question = ?; }");
}

TEST_F(FormatTestTableGen, SimpleValue4) {
verifyFormat("def SimpleValue4 { let ValueList = {1, 2, 3}; }\n");
verifyFormat("def SimpleValue4 { let ValueList = {1, 2, 3}; }");
}

TEST_F(FormatTestTableGen, SimpleValue5) {
Expand All @@ -166,7 +166,7 @@ TEST_F(FormatTestTableGen, SimpleValue5) {
" list<int>>;\n"
" let SquareBitsListWithType = [ {1, 2},\n"
" {3, 4} ]<list<bits<8>>>;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, SimpleValue6) {
Expand All @@ -184,15 +184,15 @@ TEST_F(FormatTestTableGen, SimpleValue6) {
" );\n"
" let DAGArgBang = (!cast<SomeType>(\"Some\") i32:$src1,\n"
" i32:$src2);\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, SimpleValue7) {
verifyFormat("def SimpleValue7 { let Identifier = SimpleValue; }\n");
verifyFormat("def SimpleValue7 { let Identifier = SimpleValue; }");
}

TEST_F(FormatTestTableGen, SimpleValue8) {
verifyFormat("def SimpleValue8 { let Class = SimpleValue3<3>; }\n");
verifyFormat("def SimpleValue8 { let Class = SimpleValue3<3>; }");
}

TEST_F(FormatTestTableGen, ValueSuffix) {
Expand All @@ -203,19 +203,18 @@ TEST_F(FormatTestTableGen, ValueSuffix) {
" let Slice1 = value[1, ];\n"
" let Slice2 = value[4...7, 17, 2...3, 4];\n"
" let Field = value.field;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, PasteOperator) {
verifyFormat(
"def Paste#\"Operator\" { string Paste = \"Paste\"#operator; }\n");
verifyFormat("def Paste#\"Operator\" { string Paste = \"Paste\"#operator; }");

verifyFormat("def [\"Traring\", \"Paste\"]# {\n"
" string X = Traring#;\n"
" string Y = List<\"Operator\">#;\n"
" string Z = [\"Traring\", \"Paste\", \"Traring\", \"Paste\",\n"
" \"Traring\", \"Paste\"]#;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, ClassDefinition) {
Expand All @@ -229,9 +228,9 @@ TEST_F(FormatTestTableGen, ClassDefinition) {
" defvar Item6 = 6;\n"
" let Item7 = ?;\n"
" assert !ge(x, 0), \"Assert7\";\n"
"}\n");
"}");

verifyFormat("class FPFormat<bits<3> val> { bits<3> Value = val; }\n");
verifyFormat("class FPFormat<bits<3> val> { bits<3> Value = val; }");
}

TEST_F(FormatTestTableGen, Def) {
Expand All @@ -240,18 +239,18 @@ TEST_F(FormatTestTableGen, Def) {
" let Item2{1, 3...4} = {1, 2};\n"
" defvar Item3 = (ops nodty:$node1, nodty:$node2);\n"
" assert !le(Item2, 0), \"Assert4\";\n"
"}\n");
"}");

verifyFormat("class FPFormat<bits<3> val> { bits<3> Value = val; }\n");
verifyFormat("class FPFormat<bits<3> val> { bits<3> Value = val; }");

verifyFormat("def NotFP : FPFormat<0>;\n");
verifyFormat("def NotFP : FPFormat<0>;");
}

TEST_F(FormatTestTableGen, Let) {
verifyFormat("let x = 1, y = value<type>,\n"
" z = !and(!gt(!add(1, 2), !sub(3, 4)), !isa<Ty>($x)) in {\n"
" class Class1 : Parent<x, y> { let Item1 = z; }\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, MultiClass) {
Expand Down Expand Up @@ -287,7 +286,7 @@ TEST_F(FormatTestTableGen, MultiClass) {
" }\n"
" }\n"
" }\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, MultiClassesWithPasteOperator) {
Expand All @@ -297,25 +296,25 @@ TEST_F(FormatTestTableGen, MultiClassesWithPasteOperator) {
" def : Def#x<i>;\n"
" def : Def#y<i>;\n"
"}\n"
"multiclass MultiClass2<int i> { def : Def#x<i>; }\n");
"multiclass MultiClass2<int i> { def : Def#x<i>; }");
}

TEST_F(FormatTestTableGen, Defm) {
verifyFormat("defm : Multiclass<0>;\n");
verifyFormat("defm : Multiclass<0>;");

verifyFormat("defm Defm1 : Multiclass<1>;\n");
verifyFormat("defm Defm1 : Multiclass<1>;");
}

TEST_F(FormatTestTableGen, Defset) {
verifyFormat("defset list<Class> DefSet1 = {\n"
" def Def1 : Class<1>;\n"
" def Def2 : Class<2>;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, Defvar) {
verifyFormat("defvar DefVar1 = !cond(!ge(!size(PaseOperator.Paste), 1): 1,\n"
" true: 0);\n");
" true: 0);");
}

TEST_F(FormatTestTableGen, ForEach) {
Expand All @@ -325,21 +324,21 @@ TEST_F(FormatTestTableGen, ForEach) {
" (!if(!lt(x, i),\n"
" !shl(!mul(x, i), !size(\"string\")),\n"
" !size(!strconcat(\"a\", \"b\", \"c\"))))>;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, Dump) { verifyFormat("dump \"Dump\";\n"); }
TEST_F(FormatTestTableGen, Dump) { verifyFormat("dump \"Dump\";"); }

TEST_F(FormatTestTableGen, If) {
verifyFormat("if !gt(x, 0) then {\n"
" def : IfThen<x>;\n"
"} else {\n"
" def : IfElse<x>;\n"
"}\n");
"}");
}

TEST_F(FormatTestTableGen, Assert) {
verifyFormat("assert !le(DefVar1, 0), \"Assert1\";\n");
verifyFormat("assert !le(DefVar1, 0), \"Assert1\";");
}

TEST_F(FormatTestTableGen, DAGArgBreakElements) {
Expand All @@ -349,33 +348,33 @@ TEST_F(FormatTestTableGen, DAGArgBreakElements) {
ASSERT_EQ(Style.TableGenBreakInsideDAGArg, FormatStyle::DAS_DontBreak);
verifyFormat("def Def : Parent {\n"
" let dagarg = (ins a:$src1, aa:$src2, aaa:$src3)\n"
"}\n",
"}",
Style);
// This option forces to break inside the DAGArg.
Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakElements;
verifyFormat("def Def : Parent {\n"
" let dagarg = (ins a:$src1,\n"
" aa:$src2,\n"
" aaa:$src3);\n"
"}\n",
"}",
Style);
verifyFormat("def Def : Parent {\n"
" let dagarg = (other a:$src1,\n"
" aa:$src2,\n"
" aaa:$src3);\n"
"}\n",
"}",
Style);
// Then, limit the DAGArg operator only to "ins".
Style.TableGenBreakingDAGArgOperators = {"ins"};
verifyFormat("def Def : Parent {\n"
" let dagarg = (ins a:$src1,\n"
" aa:$src2,\n"
" aaa:$src3);\n"
"}\n",
"}",
Style);
verifyFormat("def Def : Parent {\n"
" let dagarg = (other a:$src1, aa:$src2, aaa:$src3)\n"
"}\n",
"}",
Style);
}

Expand All @@ -385,7 +384,7 @@ TEST_F(FormatTestTableGen, DAGArgBreakAll) {
// By default, the DAGArg does not have a break inside.
verifyFormat("def Def : Parent {\n"
" let dagarg = (ins a:$src1, aa:$src2, aaa:$src3)\n"
"}\n",
"}",
Style);
// This option forces to break inside the DAGArg.
Style.TableGenBreakInsideDAGArg = FormatStyle::DAS_BreakAll;
Expand All @@ -395,15 +394,15 @@ TEST_F(FormatTestTableGen, DAGArgBreakAll) {
" aa:$src2,\n"
" aaa:$src3\n"
" );\n"
"}\n",
"}",
Style);
verifyFormat("def Def : Parent {\n"
" let dagarg = (other\n"
" a:$src1,\n"
" aa:$src2,\n"
" aaa:$src3\n"
" );\n"
"}\n",
"}",
Style);
// Then, limit the DAGArg operator only to "ins".
Style.TableGenBreakingDAGArgOperators = {"ins"};
Expand All @@ -413,11 +412,11 @@ TEST_F(FormatTestTableGen, DAGArgBreakAll) {
" aa:$src2,\n"
" aaa:$src3\n"
" );\n"
"}\n",
"}",
Style);
verifyFormat("def Def : Parent {\n"
" let dagarg = (other a:$src1, aa:$src2, aaa:$src3);\n"
"}\n",
"}",
Style);
}

Expand All @@ -432,11 +431,11 @@ TEST_F(FormatTestTableGen, DAGArgAlignment) {
" aa:$src2,\n"
" aaa:$src3\n"
" )\n"
"}\n",
"}",
Style);
verifyFormat("def Def : Parent {\n"
" let dagarg = (not a:$src1, aa:$src2, aaa:$src2)\n"
"}\n",
"}",
Style);
Style.AlignConsecutiveTableGenBreakingDAGArgColons.Enabled = true;
verifyFormat("def Def : Parent {\n"
Expand All @@ -445,11 +444,11 @@ TEST_F(FormatTestTableGen, DAGArgAlignment) {
" aa :$src2,\n"
" aaa:$src3\n"
" )\n"
"}\n",
"}",
Style);
verifyFormat("def Def : Parent {\n"
" let dagarg = (not a:$src1, aa:$src2, aaa:$src2)\n"
"}\n",
"}",
Style);
}

Expand All @@ -458,12 +457,12 @@ TEST_F(FormatTestTableGen, CondOperatorAlignment) {
Style.ColumnLimit = 60;
verifyFormat("let CondOpe1 = !cond(!eq(size, 1): 1,\n"
" !eq(size, 16): 1,\n"
" true: 0);\n",
" true: 0);",
Style);
Style.AlignConsecutiveTableGenCondOperatorColons.Enabled = true;
verifyFormat("let CondOpe1 = !cond(!eq(size, 1) : 1,\n"
" !eq(size, 16): 1,\n"
" true : 0);\n",
" true : 0);",
Style);
}

Expand All @@ -472,12 +471,12 @@ TEST_F(FormatTestTableGen, DefAlignment) {
Style.ColumnLimit = 60;
verifyFormat("def Def : Parent {}\n"
"def DefDef : Parent {}\n"
"def DefDefDef : Parent {}\n",
"def DefDefDef : Parent {}",
Style);
Style.AlignConsecutiveTableGenDefinitionColons.Enabled = true;
verifyFormat("def Def : Parent {}\n"
"def DefDef : Parent {}\n"
"def DefDefDef : Parent {}\n",
"def DefDefDef : Parent {}",
Style);
}

Expand Down
37 changes: 3 additions & 34 deletions clang/utils/TableGen/ClangAttrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1591,18 +1591,18 @@ writePrettyPrintFunction(const Record &R,
std::string Variety = Spellings[I].variety();

if (Variety == "GNU") {
Prefix = " __attribute__((";
Prefix = "__attribute__((";
Suffix = "))";
} else if (Variety == "CXX11" || Variety == "C23") {
Prefix = " [[";
Prefix = "[[";
Suffix = "]]";
std::string Namespace = Spellings[I].nameSpace();
if (!Namespace.empty()) {
Spelling += Namespace;
Spelling += "::";
}
} else if (Variety == "Declspec") {
Prefix = " __declspec(";
Prefix = "__declspec(";
Suffix = ")";
} else if (Variety == "Microsoft") {
Prefix = "[";
Expand Down Expand Up @@ -3316,37 +3316,6 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) {
OS << "#undef PRAGMA_SPELLING_ATTR\n";
}

// Emits the enumeration list for attributes.
void EmitClangAttrPrintList(const std::string &FieldName, RecordKeeper &Records,
raw_ostream &OS) {
emitSourceFileHeader(
"List of attributes that can be print on the left side of a decl", OS,
Records);

AttrClassHierarchy Hierarchy(Records);

std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
std::vector<Record *> PragmaAttrs;
bool first = false;

for (auto *Attr : Attrs) {
if (!Attr->getValueAsBit("ASTNode"))
continue;

if (!Attr->getValueAsBit(FieldName))
continue;

if (!first) {
first = true;
OS << "#define CLANG_ATTR_LIST_" << FieldName;
}

OS << " \\\n case attr::" << Attr->getName() << ":";
}

OS << '\n';
}

// Emits the enumeration list for attributes.
void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) {
emitSourceFileHeader(
Expand Down
16 changes: 0 additions & 16 deletions clang/utils/TableGen/TableGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ enum ActionType {
GenClangAttrSubjectMatchRulesParserStringSwitches,
GenClangAttrImpl,
GenClangAttrList,
GenClangAttrCanPrintLeftList,
GenClangAttrMustPrintLeftList,
GenClangAttrDocTable,
GenClangAttrSubjectMatchRuleList,
GenClangAttrPCHRead,
Expand Down Expand Up @@ -134,14 +132,6 @@ cl::opt<ActionType> Action(
"Generate clang attribute implementations"),
clEnumValN(GenClangAttrList, "gen-clang-attr-list",
"Generate a clang attribute list"),
clEnumValN(GenClangAttrCanPrintLeftList,
"gen-clang-attr-can-print-left-list",
"Generate list of attributes that can be printed on left "
"side of a decl"),
clEnumValN(GenClangAttrMustPrintLeftList,
"gen-clang-attr-must-print-left-list",
"Generate list of attributes that must be printed on left "
"side of a decl"),
clEnumValN(GenClangAttrDocTable, "gen-clang-attr-doc-table",
"Generate a table of attribute documentation"),
clEnumValN(GenClangAttrSubjectMatchRuleList,
Expand Down Expand Up @@ -345,12 +335,6 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
case GenClangAttrList:
EmitClangAttrList(Records, OS);
break;
case GenClangAttrCanPrintLeftList:
EmitClangAttrPrintList("CanPrintOnLeft", Records, OS);
break;
case GenClangAttrMustPrintLeftList:
EmitClangAttrPrintList("PrintOnLeft", Records, OS);
break;
case GenClangAttrDocTable:
EmitClangAttrDocTable(Records, OS);
break;
Expand Down
2 changes: 0 additions & 2 deletions clang/utils/TableGen/TableGenBackends.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ void EmitClangAttrSubjectMatchRulesParserStringSwitches(
void EmitClangAttrClass(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitClangAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitClangAttrList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitClangAttrPrintList(const std::string &FieldName,
llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
void EmitClangAttrSubjectMatchRuleList(llvm::RecordKeeper &Records,
llvm::raw_ostream &OS);
void EmitClangAttrPCHRead(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
Expand Down
12 changes: 2 additions & 10 deletions clang/www/cxx_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -544,16 +544,8 @@ <h2 id="cxx20">C++20 implementation status</h2>
</tr>
<tr> <!-- from Cologne -->
<td><a href="https://wg21.link/p0848r3">P0848R3</a></td>
<td rowspan="1" class="partial" align="center">
<details>
<summary>Clang 16 (Partial)</summary>
Because of other concepts implementation deficits, the __cpp_concepts macro is not yet set to 202002L.
Also, the related defect reports <a href="https://wg21.link/cwg1496">DR1496</a> and
<a href="https://wg21.link/cwg1734">DR1734</a> are not yet implemented. Accordingly, deleted
special member functions are treated as eligible even though they shouldn't be.
</details>
</td>
</tr>
<td rowspan="1" class="full" align="center">Clang 19</td>
</tr>
<tr>
<td><a href="https://wg21.link/p1616r1">P1616R1</a></td>
<td rowspan="2" class="full" align="center">Clang 10</td>
Expand Down
6 changes: 4 additions & 2 deletions compiler-rt/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,11 @@ if(APPLE)

set(DEFAULT_SANITIZER_MIN_OSX_VERSION 10.13)
set(DARWIN_osx_MIN_VER_FLAG "-mmacosx-version-min")

string(REGEX MATCH "${DARWIN_osx_MIN_VER_FLAG}=([.0-9]+)"
MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")

if(NOT SANITIZER_MIN_OSX_VERSION)
string(REGEX MATCH "${DARWIN_osx_MIN_VER_FLAG}=([.0-9]+)"
MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")
if(MACOSX_VERSION_MIN_FLAG)
set(MIN_OSX_VERSION "${CMAKE_MATCH_1}")
elseif(CMAKE_OSX_DEPLOYMENT_TARGET)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/memprof/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ macro(add_memprof_tests_for_arch arch)
LINK_FLAGS ${MEMPROF_UNITTEST_LINK_FLAGS} ${MEMPROF_UNITTEST_LINK_LIBRARIES})
endmacro()

# Interception unit tests testsuite.
# MemProf unit tests testsuite.
add_custom_target(MemProfUnitTests)
set_target_properties(MemProfUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST MEMPROF_SUPPORTED_ARCH)
Expand Down
3 changes: 2 additions & 1 deletion flang/include/flang/Parser/parse-tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,8 @@ struct ProcComponentDefStmt {
// R736 component-def-stmt -> data-component-def-stmt | proc-component-def-stmt
struct ComponentDefStmt {
UNION_CLASS_BOILERPLATE(ComponentDefStmt);
std::variant<DataComponentDefStmt, ProcComponentDefStmt, ErrorRecovery
std::variant<DataComponentDefStmt, ProcComponentDefStmt,
common::Indirection<CompilerDirective>, ErrorRecovery
// , TypeParamDefStmt -- PGI accidental extension, not enabled
>
u;
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Optimizer/Transforms/AddDebugFoundation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void AddDebugFoundationPass::runOnOperation() {
mlir::LLVM::DIFileAttr fileAttr = getFileAttr(inputFilePath);
mlir::StringAttr producer = mlir::StringAttr::get(context, "Flang");
mlir::LLVM::DICompileUnitAttr cuAttr = mlir::LLVM::DICompileUnitAttr::get(
context, mlir::DistinctAttr::create(mlir::UnitAttr::get(context)),
mlir::DistinctAttr::create(mlir::UnitAttr::get(context)),
llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer,
/*isOptimized=*/false, mlir::LLVM::DIEmissionKind::LineTablesOnly);

Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Parser/Fortran-parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,8 @@ TYPE_PARSER(construct<TypeParamDecl>(name, maybe("=" >> scalarIntConstantExpr)))
TYPE_PARSER(recovery(
withMessage("expected component definition"_err_en_US,
first(construct<ComponentDefStmt>(Parser<DataComponentDefStmt>{}),
construct<ComponentDefStmt>(Parser<ProcComponentDefStmt>{}))),
construct<ComponentDefStmt>(Parser<ProcComponentDefStmt>{}),
construct<ComponentDefStmt>(indirect(compilerDirective)))),
construct<ComponentDefStmt>(inStmtErrorRecovery)))

// R737 data-component-def-stmt ->
Expand Down
8 changes: 4 additions & 4 deletions flang/test/Driver/msvc-dependent-lib-flags.f90
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
! RUN: %flang -### --target=aarch64-windows-msvc -fms-runtime-lib=dll_dbg %S/Inputs/hello.f90 -v 2>&1 | FileCheck %s --check-prefixes=MSVC-DLL-DEBUG

! MSVC: -fc1
! MSVC-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-SAME: --dependent-lib=clang_rt.builtins.lib
! MSVC-SAME: -D_MT
! MSVC-SAME: --dependent-lib=libcmt
! MSVC-SAME: --dependent-lib=Fortran_main.static.lib
! MSVC-SAME: --dependent-lib=FortranRuntime.static.lib
! MSVC-SAME: --dependent-lib=FortranDecimal.static.lib

! MSVC-DEBUG: -fc1
! MSVC-DEBUG-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-DEBUG-SAME: --dependent-lib=clang_rt.builtins.lib
! MSVC-DEBUG-SAME: -D_MT
! MSVC-DEBUG-SAME: -D_DEBUG
! MSVC-DEBUG-SAME: --dependent-lib=libcmtd
Expand All @@ -21,7 +21,7 @@
! MSVC-DEBUG-SAME: --dependent-lib=FortranDecimal.static_dbg.lib

! MSVC-DLL: -fc1
! MSVC-DLL-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-DLL-SAME: --dependent-lib=clang_rt.builtins.lib
! MSVC-DLL-SAME: -D_MT
! MSVC-DLL-SAME: -D_DLL
! MSVC-DLL-SAME: --dependent-lib=msvcrt
Expand All @@ -30,7 +30,7 @@
! MSVC-DLL-SAME: --dependent-lib=FortranDecimal.dynamic.lib

! MSVC-DLL-DEBUG: -fc1
! MSVC-DLL-DEBUG-SAME: --dependent-lib=clang_rt.builtins-aarch64.lib
! MSVC-DLL-DEBUG-SAME: --dependent-lib=clang_rt.builtins.lib
! MSVC-DLL-DEBUG-SAME: -D_MT
! MSVC-DLL-DEBUG-SAME: -D_DEBUG
! MSVC-DLL-DEBUG-SAME: -D_DLL
Expand Down
4 changes: 4 additions & 0 deletions flang/test/Parser/compiler-directives.f90
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ module m
!dir$ optimize : 1
!dir$ loop count (10000)
!dir$ loop count (1, 500, 5000, 10000)
type stuff
real(8), allocatable :: d(:)
!dir$ align : 1024 :: d
end type stuff
end
24 changes: 0 additions & 24 deletions libc/include/llvm-libc-macros/math-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,9 @@
#define math_errhandling (MATH_ERRNO | MATH_ERREXCEPT)
#endif

// These must be type-generic functions. The C standard specifies them as
// being macros rather than functions, in fact. However, in C++ it's important
// that there be function declarations that don't interfere with other uses of
// the identifier, even in places with parentheses where a function-like macro
// will be expanded (such as a function declaration in a C++ namespace).

// TODO: Move generic functional math macros to a separate header file.
#ifdef __cplusplus

template <typename T> inline constexpr bool isfinite(T x) {
return __builtin_isfinite(x);
}

template <typename T> inline constexpr bool isinf(T x) {
return __builtin_isinf(x);
}

template <typename T> inline constexpr bool isnan(T x) {
return __builtin_isnan(x);
}

#else

#define isfinite(x) __builtin_isfinite(x)
#define isinf(x) __builtin_isinf(x)
#define isnan(x) __builtin_isnan(x)

#endif

#endif // LLVM_LIBC_MACROS_MATH_MACROS_H
2 changes: 2 additions & 0 deletions libc/test/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,7 @@ add_fp_unittest(
DEPENDS
libc.src.math.fmaf
libc.src.stdlib.rand
libc.src.stdlib.srand
libc.src.__support.FPUtil.fp_bits
FLAGS
FMA_OPT__ONLY
Expand All @@ -1286,6 +1287,7 @@ add_fp_unittest(
DEPENDS
libc.src.math.fma
libc.src.stdlib.rand
libc.src.stdlib.srand
libc.src.__support.FPUtil.fp_bits
)

Expand Down
3 changes: 3 additions & 0 deletions libc/test/src/math/FmaTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "src/__support/FPUtil/FPBits.h"
#include "src/stdlib/rand.h"
#include "src/stdlib/srand.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
Expand Down Expand Up @@ -76,6 +77,7 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
void test_subnormal_range(Func func) {
constexpr StorageType COUNT = 100'001;
constexpr StorageType STEP = (MAX_SUBNORMAL - MIN_SUBNORMAL) / COUNT;
LIBC_NAMESPACE::srand(1);
for (StorageType v = MIN_SUBNORMAL, w = MAX_SUBNORMAL;
v <= MAX_SUBNORMAL && w >= MIN_SUBNORMAL; v += STEP, w -= STEP) {
T x = FPBits(get_random_bit_pattern()).get_val(), y = FPBits(v).get_val(),
Expand All @@ -89,6 +91,7 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
void test_normal_range(Func func) {
constexpr StorageType COUNT = 100'001;
constexpr StorageType STEP = (MAX_NORMAL - MIN_NORMAL) / COUNT;
LIBC_NAMESPACE::srand(1);
for (StorageType v = MIN_NORMAL, w = MAX_NORMAL;
v <= MAX_NORMAL && w >= MIN_NORMAL; v += STEP, w -= STEP) {
T x = FPBits(v).get_val(), y = FPBits(w).get_val(),
Expand Down
4 changes: 1 addition & 3 deletions libcxx/docs/FeatureTestMacroTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_associative_heterogeneous_erasure`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_bind_back`` *unimplemented*
``__cpp_lib_bind_back`` ``202202L``
---------------------------------------------------------- -----------------
``__cpp_lib_byteswap`` ``202110L``
---------------------------------------------------------- -----------------
Expand Down Expand Up @@ -398,8 +398,6 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_atomic_min_max`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_bind_back`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_bind_front`` ``202306L``
---------------------------------------------------------- -----------------
``__cpp_lib_bitset`` ``202306L``
Expand Down
1 change: 1 addition & 0 deletions libcxx/docs/Status/Cxx23.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Paper Status
.. [#note-P0533R9] P0533R9: ``isfinite``, ``isinf``, ``isnan`` and ``isnormal`` are implemented.
.. [#note-P1413R3] P1413R3: ``std::aligned_storage_t`` and ``std::aligned_union_t`` are marked deprecated, but
clang doesn't issue a diagnostic for deprecated using template declarations.
.. [#note-P2387R3] P2387R3: ``bind_back`` only
.. [#note-P2520R0] P2520R0: Libc++ implemented this paper as a DR in C++20 as well.
.. [#note-P2711R1] P2711R1: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
.. [#note-P2770R0] P2770R0: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx23Papers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"`P1413R3 <https://wg21.link/P1413R3>`__","LWG","Deprecate ``std::aligned_storage`` and ``std::aligned_union``","February 2022","|Complete| [#note-P1413R3]_",""
"`P2255R2 <https://wg21.link/P2255R2>`__","LWG","A type trait to detect reference binding to temporary","February 2022","",""
"`P2273R3 <https://wg21.link/P2273R3>`__","LWG","Making ``std::unique_ptr`` constexpr","February 2022","|Complete|","16.0"
"`P2387R3 <https://wg21.link/P2387R3>`__","LWG","Pipe support for user-defined range adaptors","February 2022","","","|ranges|"
"`P2387R3 <https://wg21.link/P2387R3>`__","LWG","Pipe support for user-defined range adaptors","February 2022","|Partial| [#note-P2387R3]_","","|ranges|"
"`P2440R1 <https://wg21.link/P2440R1>`__","LWG","``ranges::iota``, ``ranges::shift_left`` and ``ranges::shift_right``","February 2022","","","|ranges|"
"`P2441R2 <https://wg21.link/P2441R2>`__","LWG","``views::join_with``","February 2022","|In Progress|","","|ranges|"
"`P2442R1 <https://wg21.link/P2442R1>`__","LWG","Windowing range adaptors: ``views::chunk`` and ``views::slide``","February 2022","","","|ranges|"
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cIssues.csv
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"`4023 <https://wg21.link/LWG4023>`__","Preconditions of ``std::basic_streambuf::setg/setp``","Tokyo March 2024","","",""
"`4025 <https://wg21.link/LWG4025>`__","Move assignment operator of ``std::expected<cv void, E>`` should not be conditionally deleted","Tokyo March 2024","","",""
"`4030 <https://wg21.link/LWG4030>`__","Clarify whether arithmetic expressions in ``[numeric.sat.func]`` are mathematical or C++","Tokyo March 2024","|Nothing To Do|","",""
"`4031 <https://wg21.link/LWG4031>`__","``bad_expected_access<void>`` member functions should be ``noexcept``","Tokyo March 2024","","",""
"`4031 <https://wg21.link/LWG4031>`__","``bad_expected_access<void>`` member functions should be ``noexcept``","Tokyo March 2024","|Complete|","16.0",""
"`4035 <https://wg21.link/LWG4035>`__","``single_view`` should provide ``empty``","Tokyo March 2024","","","|ranges|"
"`4036 <https://wg21.link/LWG4036>`__","``__alignof_is_defined`` is only implicitly specified in C++ and not yet deprecated","Tokyo March 2024","","",""
"`4037 <https://wg21.link/LWG4037>`__","Static data members of ``ctype_base`` are not yet required to be usable in constant expressions","Tokyo March 2024","","",""
Expand Down
12 changes: 6 additions & 6 deletions libcxx/include/__expected/bad_expected_access.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
template <>
class bad_expected_access<void> : public exception {
protected:
_LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) = default;
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) noexcept = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) noexcept = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) noexcept = default;
_LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) noexcept = default;
_LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override = default;

public:
// The way this has been designed (by using a class template below) means that we'll already
Expand Down
14 changes: 14 additions & 0 deletions libcxx/include/__functional/bind_back.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __bind_back(_Fn&& __f, _Args&&... __args) n
std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...));
}

# if _LIBCPP_STD_VER >= 23
template <class _Fn, class... _Args>
_LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) {
static_assert(is_constructible_v<decay_t<_Fn>, _Fn>, "bind_back requires decay_t<F> to be constructible from F");
static_assert(is_move_constructible_v<decay_t<_Fn>>, "bind_back requires decay_t<F> to be move constructible");
static_assert((is_constructible_v<decay_t<_Args>, _Args> && ...),
"bind_back requires all decay_t<Args> to be constructible from respective Args");
static_assert((is_move_constructible_v<decay_t<_Args>> && ...),
"bind_back requires all decay_t<Args> to be move constructible");
return __bind_back_t<decay_t<_Fn>, tuple<decay_t<_Args>...>>(
std::forward<_Fn>(__f), std::forward_as_tuple(std::forward<_Args>(__args)...));
}
# endif // _LIBCPP_STD_VER >= 23

#endif // _LIBCPP_STD_VER >= 20

_LIBCPP_END_NAMESPACE_STD
Expand Down
6 changes: 6 additions & 0 deletions libcxx/include/functional
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ binary_negate<Predicate> not2(const Predicate& pred);
template <class F>
constexpr unspecified not_fn(F&& f); // C++17, constexpr in C++20

// [func.bind.partial], function templates bind_front and bind_back
template<class F, class... Args>
constexpr unspecified bind_front(F&&, Args&&...); // C++20
template<class F, class... Args>
constexpr unspecified bind_back(F&&, Args&&...); // C++23

template<class T> struct is_bind_expression;
template<class T> struct is_placeholder;

Expand Down
7 changes: 2 additions & 5 deletions libcxx/include/version
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ __cpp_lib_atomic_shared_ptr 201711L <atomic>
__cpp_lib_atomic_value_initialization 201911L <atomic> <memory>
__cpp_lib_atomic_wait 201907L <atomic>
__cpp_lib_barrier 201907L <barrier>
__cpp_lib_bind_back 202306L <functional>
202202L // C++23
__cpp_lib_bind_back 202202L <functional>
__cpp_lib_bind_front 202306L <functional>
201907L // C++20
__cpp_lib_bit_cast 201806L <bit>
Expand Down Expand Up @@ -449,7 +448,7 @@ __cpp_lib_within_lifetime 202306L <type_traits>
# define __cpp_lib_adaptor_iterator_pair_constructor 202106L
# define __cpp_lib_allocate_at_least 202302L
// # define __cpp_lib_associative_heterogeneous_erasure 202110L
// # define __cpp_lib_bind_back 202202L
# define __cpp_lib_bind_back 202202L
# define __cpp_lib_byteswap 202110L
# define __cpp_lib_constexpr_bitset 202207L
# define __cpp_lib_constexpr_charconv 202207L
Expand Down Expand Up @@ -498,8 +497,6 @@ __cpp_lib_within_lifetime 202306L <type_traits>
#if _LIBCPP_STD_VER >= 26
// # define __cpp_lib_associative_heterogeneous_insertion 202306L
// # define __cpp_lib_atomic_min_max 202403L
# undef __cpp_lib_bind_back
// # define __cpp_lib_bind_back 202306L
# undef __cpp_lib_bind_front
# define __cpp_lib_bind_front 202306L
# define __cpp_lib_bitset 202306L
Expand Down
4 changes: 3 additions & 1 deletion libcxx/modules/std/functional.inc
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ export namespace std {
using std::not_fn;

// [func.bind.partial], function templates bind_front and bind_back
// using std::bind_back;
using std::bind_front;
#if _LIBCPP_STD_VER >= 23
using std::bind_back;
#endif

// [func.bind], bind
using std::is_bind_expression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

/* Constant Value
__cpp_lib_bind_back 202202L [C++23]
202306L [C++26]
__cpp_lib_bind_front 201907L [C++20]
202306L [C++26]
__cpp_lib_boyer_moore_searcher 201603L [C++17]
Expand Down Expand Up @@ -337,17 +336,11 @@

#elif TEST_STD_VER == 23

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++23"
# endif
# if __cpp_lib_bind_back != 202202L
# error "__cpp_lib_bind_back should have the value 202202L in c++23"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++23"
# endif
# if __cpp_lib_bind_back != 202202L
# error "__cpp_lib_bind_back should have the value 202202L in c++23"
# endif

# ifndef __cpp_lib_bind_front
Expand Down Expand Up @@ -447,17 +440,11 @@

#elif TEST_STD_VER > 23

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++26"
# endif
# if __cpp_lib_bind_back != 202306L
# error "__cpp_lib_bind_back should have the value 202306L in c++26"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++26"
# endif
# if __cpp_lib_bind_back != 202202L
# error "__cpp_lib_bind_back should have the value 202202L in c++26"
# endif

# ifndef __cpp_lib_bind_front
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
__cpp_lib_atomic_wait 201907L [C++20]
__cpp_lib_barrier 201907L [C++20]
__cpp_lib_bind_back 202202L [C++23]
202306L [C++26]
__cpp_lib_bind_front 201907L [C++20]
202306L [C++26]
__cpp_lib_bit_cast 201806L [C++20]
Expand Down Expand Up @@ -4605,17 +4604,11 @@
# endif
# endif

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++23"
# endif
# if __cpp_lib_bind_back != 202202L
# error "__cpp_lib_bind_back should have the value 202202L in c++23"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++23"
# endif
# if __cpp_lib_bind_back != 202202L
# error "__cpp_lib_bind_back should have the value 202202L in c++23"
# endif

# ifndef __cpp_lib_bind_front
Expand Down Expand Up @@ -6240,17 +6233,11 @@
# endif
# endif

# if !defined(_LIBCPP_VERSION)
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++26"
# endif
# if __cpp_lib_bind_back != 202306L
# error "__cpp_lib_bind_back should have the value 202306L in c++26"
# endif
# else // _LIBCPP_VERSION
# ifdef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should not be defined because it is unimplemented in libc++!"
# endif
# ifndef __cpp_lib_bind_back
# error "__cpp_lib_bind_back should be defined in c++26"
# endif
# if __cpp_lib_bind_back != 202202L
# error "__cpp_lib_bind_back should have the value 202202L in c++26"
# endif

# ifndef __cpp_lib_bind_front
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,12 @@

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// const char* what() const noexcept override;
// Make sure std::bad_expected_access<E> inherits from std::bad_expected_access<void>.

#include <expected>
#include <utility>
#include <type_traits>

template <class T>
concept WhatNoexcept =
requires(const T& t) {
{ t.what() } noexcept;
};
struct Foo {};

struct foo{};

static_assert(!WhatNoexcept<foo>);
static_assert(WhatNoexcept<std::bad_expected_access<int>>);
static_assert(WhatNoexcept<std::bad_expected_access<foo>>);
static_assert(std::is_base_of_v<std::bad_expected_access<void>, std::bad_expected_access<int>>);
static_assert(std::is_base_of_v<std::bad_expected_access<void>, std::bad_expected_access<Foo>>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//===----------------------------------------------------------------------===//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// template<>
// class bad_expected_access<void> : public exception {
// protected:
// bad_expected_access() noexcept;
// bad_expected_access(const bad_expected_access&) noexcept;
// bad_expected_access(bad_expected_access&&) noexcept;
// bad_expected_access& operator=(const bad_expected_access&) noexcept;
// bad_expected_access& operator=(bad_expected_access&&) noexcept;
// ~bad_expected_access();
//
// public:
// const char* what() const noexcept override;
// };

#include <cassert>
#include <exception>
#include <expected>
#include <type_traits>
#include <utility>

#include "test_macros.h"

struct Inherit : std::bad_expected_access<void> {};

int main(int, char**) {
// base class
static_assert(std::is_base_of_v<std::exception, std::bad_expected_access<void>>);

// default constructor
{
Inherit exc;
ASSERT_NOEXCEPT(Inherit());
}

// copy constructor
{
Inherit exc;
Inherit copy(exc);
ASSERT_NOEXCEPT(Inherit(exc));
}

// move constructor
{
Inherit exc;
Inherit copy(std::move(exc));
ASSERT_NOEXCEPT(Inherit(std::move(exc)));
}

// copy assignment
{
Inherit exc;
Inherit copy;
[[maybe_unused]] Inherit& result = (copy = exc);
ASSERT_NOEXCEPT(copy = exc);
}

// move assignment
{
Inherit exc;
Inherit copy;
[[maybe_unused]] Inherit& result = (copy = std::move(exc));
ASSERT_NOEXCEPT(copy = std::move(exc));
}

// what()
{
Inherit exc;
char const* what = exc.what();
assert(what != nullptr);
ASSERT_NOEXCEPT(exc.what());
}

return 0;
}
35 changes: 35 additions & 0 deletions libcxx/test/std/utilities/expected/expected.bad/what.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===----------------------------------------------------------------------===//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// const char* what() const noexcept override;

#include <expected>
#include <cassert>
#include <utility>

#include "test_macros.h"

struct Foo {};

int main(int, char**) {
{
std::bad_expected_access<int> const exc(99);
char const* what = exc.what();
assert(what != nullptr);
ASSERT_NOEXCEPT(exc.what());
}
{
std::bad_expected_access<Foo> const exc(Foo{});
char const* what = exc.what();
assert(what != nullptr);
ASSERT_NOEXCEPT(exc.what());
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,381 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// <functional>

// template<class F, class... Args>
// constexpr unspecified bind_back(F&& f, Args&&... args);

#include <functional>

#include <cassert>
#include <concepts>
#include <tuple>
#include <utility>

#include "callable_types.h"
#include "types.h"

constexpr void test_basic_bindings() {
{ // Bind arguments, call without arguments
{
auto f = std::bind_back(MakeTuple{});
assert(f() == std::make_tuple());
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{});
assert(f() == std::make_tuple(Elem<1>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{});
assert(f() == std::make_tuple(Elem<1>{}, Elem<2>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
assert(f() == std::make_tuple(Elem<1>{}, Elem<2>{}, Elem<3>{}));
}
}

{ // Bind no arguments, call with arguments
{
auto f = std::bind_back(MakeTuple{});
assert(f(Elem<1>{}) == std::make_tuple(Elem<1>{}));
}
{
auto f = std::bind_back(MakeTuple{});
assert(f(Elem<1>{}, Elem<2>{}) == std::make_tuple(Elem<1>{}, Elem<2>{}));
}
{
auto f = std::bind_back(MakeTuple{});
assert(f(Elem<1>{}, Elem<2>{}, Elem<3>{}) == std::make_tuple(Elem<1>{}, Elem<2>{}, Elem<3>{}));
}
}

{ // Bind arguments, call with arguments
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{});
assert(f(Elem<10>{}) == std::make_tuple(Elem<10>{}, Elem<1>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{});
assert(f(Elem<10>{}) == std::make_tuple(Elem<10>{}, Elem<1>{}, Elem<2>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
assert(f(Elem<10>{}) == std::make_tuple(Elem<10>{}, Elem<1>{}, Elem<2>{}, Elem<3>{}));
}

{
auto f = std::bind_back(MakeTuple{}, Elem<1>{});
assert(f(Elem<10>{}, Elem<11>{}) == std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<1>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{});
assert(f(Elem<10>{}, Elem<11>{}) == std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<1>{}, Elem<2>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
assert(f(Elem<10>{}, Elem<11>{}) == std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<1>{}, Elem<2>{}, Elem<3>{}));
}
{
auto f = std::bind_back(MakeTuple{}, Elem<1>{}, Elem<2>{}, Elem<3>{});
assert(f(Elem<10>{}, Elem<11>{}, Elem<12>{}) ==
std::make_tuple(Elem<10>{}, Elem<11>{}, Elem<12>{}, Elem<1>{}, Elem<2>{}, Elem<3>{}));
}
}

{ // Basic tests with fundamental types
int n = 2;
int m = 1;
int sum = 0;
auto add = [](int x, int y) { return x + y; };
auto add_n = [](int a, int b, int c, int d, int e, int f) { return a + b + c + d + e + f; };
auto add_ref = [&](int x, int y) -> int& { return sum = x + y; };
auto add_rref = [&](int x, int y) -> int&& { return std::move(sum = x + y); };

auto a = std::bind_back(add, m, n);
assert(a() == 3);

auto b = std::bind_back(add_n, m, n, m, m, m, m);
assert(b() == 7);

auto c = std::bind_back(add_n, n, m);
assert(c(1, 1, 1, 1) == 7);

auto d = std::bind_back(add_ref, n, m);
std::same_as<int&> decltype(auto) dresult(d());
assert(dresult == 3);

auto e = std::bind_back(add_rref, n, m);
std::same_as<int&&> decltype(auto) eresult(e());
assert(eresult == 3);

auto f = std::bind_back(add, n);
assert(f(3) == 5);

auto g = std::bind_back(add, n, 1);
assert(g() == 3);

auto h = std::bind_back(add_n, 1, 1, 1);
assert(h(2, 2, 2) == 9);

auto i = std::bind_back(add_ref, n);
std::same_as<int&> decltype(auto) iresult(i(5));
assert(iresult == 7);

auto j = std::bind_back(add_rref, m);
std::same_as<int&&> decltype(auto) jresult(j(4));
assert(jresult == 5);
}
}

constexpr void test_edge_cases() {
{ // Make sure we don't treat std::reference_wrapper specially.
auto sub = [](std::reference_wrapper<int> a, std::reference_wrapper<int> b) { return a.get() - b.get(); };

int i = 1;
int j = 2;
auto f = std::bind_back(sub, std::ref(i));
assert(f(std::ref(j)) == 1);
}

{ // Make sure we can call a function that's a pointer to a member function.
struct MemberFunction {
constexpr int foo(int x, int y) { return x * y; }
};

MemberFunction value;
auto fn = std::bind_back(&MemberFunction::foo, 2, 3);
assert(fn(value) == 6);
}

{ // Make sure we can call a function that's a pointer to a member object.
struct MemberObject {
int obj;
};

MemberObject value{.obj = 3};
auto fn = std::bind_back(&MemberObject::obj);
assert(fn(value) == 3);
}
}

constexpr void test_passing_arguments() {
{ // Make sure that we copy the bound arguments into the unspecified-type.
auto add = [](int x, int y) { return x + y; };
int n = 2;
auto f = std::bind_back(add, n, 1);
n = 100;
assert(f() == 3);
}

{ // Make sure we pass the bound arguments to the function object
// with the right value category.
{
auto was_copied = [](CopyMoveInfo info) { return info.copy_kind == CopyMoveInfo::copy; };
CopyMoveInfo info;
auto f = std::bind_back(was_copied, info);
assert(f());
}

{
auto was_moved = [](CopyMoveInfo info) { return info.copy_kind == CopyMoveInfo::move; };
CopyMoveInfo info;
auto f = std::bind_back(was_moved, info);
assert(std::move(f)());
}
}
}

constexpr void test_function_objects() {
{ // Make sure we call the correctly cv-ref qualified operator()
// based on the value category of the bind_back unspecified-type.
struct X {
constexpr int operator()() & { return 1; }
constexpr int operator()() const& { return 2; }
constexpr int operator()() && { return 3; }
constexpr int operator()() const&& { return 4; }
};

auto f = std::bind_back(X{});
using F = decltype(f);
assert(static_cast<F&>(f)() == 1);
assert(static_cast<const F&>(f)() == 2);
assert(static_cast<F&&>(f)() == 3);
assert(static_cast<const F&&>(f)() == 4);
}

// Make sure the `bind_back` unspecified-type does not model invocable
// when the call would select a differently-qualified operator().
//
// For example, if the call to `operator()() &` is ill-formed, the call to the unspecified-type
// should be ill-formed and not fall back to the `operator()() const&` overload.
{ // Make sure we delete the & overload when the underlying call isn't valid.
{
struct X {
void operator()() & = delete;
void operator()() const&;
void operator()() &&;
void operator()() const&&;
};

using F = decltype(std::bind_back(X{}));
static_assert(!std::invocable<F&>);
static_assert(std::invocable<const F&>);
static_assert(std::invocable<F>);
static_assert(std::invocable<const F>);
}

// There's no way to make sure we delete the const& overload when the underlying call isn't valid,
// so we can't check this one.

{ // Make sure we delete the && overload when the underlying call isn't valid.
struct X {
void operator()() &;
void operator()() const&;
void operator()() && = delete;
void operator()() const&&;
};

using F = decltype(std::bind_back(X{}));
static_assert(std::invocable<F&>);
static_assert(std::invocable<const F&>);
static_assert(!std::invocable<F>);
static_assert(std::invocable<const F>);
}

{ // Make sure we delete the const&& overload when the underlying call isn't valid.
struct X {
void operator()() &;
void operator()() const&;
void operator()() &&;
void operator()() const&& = delete;
};

using F = decltype(std::bind_back(X{}));
static_assert(std::invocable<F&>);
static_assert(std::invocable<const F&>);
static_assert(std::invocable<F>);
static_assert(!std::invocable<const F>);
}
}

{ // Extra value category tests
struct X {};

{
struct Y {
void operator()(X&&) const&;
void operator()(X&&) && = delete;
};

using F = decltype(std::bind_back(Y{}));
static_assert(std::invocable<F&, X>);
static_assert(!std::invocable<F, X>);
}

{
struct Y {
void operator()(const X&) const;
void operator()(X&&) const = delete;
};

using F = decltype(std::bind_back(Y{}, X{}));
static_assert(std::invocable<F&>);
static_assert(!std::invocable<F>);
}
}
}

constexpr void test_return_type() {
{ // Test properties of the constructor of the unspecified-type returned by bind_back.
{ // Test move constructor when function is move only.
MoveOnlyCallable<bool> value(true);
auto f = std::bind_back(std::move(value), 1);
assert(f());
assert(f(1, 2, 3));

auto f1 = std::move(f);
assert(!f());
assert(f1());
assert(f1(1, 2, 3));

using F = decltype(f);
static_assert(std::is_move_constructible<F>::value);
static_assert(!std::is_copy_constructible<F>::value);
static_assert(!std::is_move_assignable<F>::value);
static_assert(!std::is_copy_assignable<F>::value);
}

{ // Test move constructor when function is copyable but not assignable.
CopyCallable<bool> value(true);
auto f = std::bind_back(value, 1);
assert(f());
assert(f(1, 2, 3));

auto f1 = std::move(f);
assert(!f());
assert(f1());
assert(f1(1, 2, 3));

auto f2 = std::bind_back(std::move(value), 1);
assert(f1());
assert(f2());
assert(f2(1, 2, 3));

using F = decltype(f);
static_assert(std::is_move_constructible<F>::value);
static_assert(std::is_copy_constructible<F>::value);
static_assert(!std::is_move_assignable<F>::value);
static_assert(!std::is_copy_assignable<F>::value);
}

{ // Test constructors when function is copy assignable.
using F = decltype(std::bind_back(std::declval<CopyAssignableWrapper&>(), 1));
static_assert(std::is_move_constructible<F>::value);
static_assert(std::is_copy_constructible<F>::value);
static_assert(std::is_move_assignable<F>::value);
static_assert(std::is_copy_assignable<F>::value);
}

{ // Test constructors when function is move assignable only.
using F = decltype(std::bind_back(std::declval<MoveAssignableWrapper>(), 1));
static_assert(std::is_move_constructible<F>::value);
static_assert(!std::is_copy_constructible<F>::value);
static_assert(std::is_move_assignable<F>::value);
static_assert(!std::is_copy_assignable<F>::value);
}
}

{ // Make sure bind_back's unspecified type's operator() is SFINAE-friendly.
using F = decltype(std::bind_back(std::declval<int (*)(int, int)>(), 1));
static_assert(!std::is_invocable<F>::value);
static_assert(std::is_invocable<F, int>::value);
static_assert(!std::is_invocable<F, void*>::value);
static_assert(!std::is_invocable<F, int, int>::value);
}
}

constexpr bool test() {
test_basic_bindings();
test_edge_cases();
test_passing_arguments();
test_function_objects();
test_return_type();

return true;
}

int main(int, char**) {
test();
static_assert(test());

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// <functional>

// template<class F, class... Args>
// constexpr unspecified bind_back(F&& f, Args&&... args);

#include <functional>

#include "types.h"

constexpr int pass(int n) { return n; }

void test() {
{ // Test calling constexpr function from non-constexpr `bind_back` result
auto f1 = std::bind_back(pass, 1);
static_assert(f1() == 1); // expected-error {{static assertion expression is not an integral constant expression}}
}

{ // Test calling `bind_back` with template function
auto f1 = std::bind_back(do_nothing, 2);
// expected-error@-1 {{no matching function for call to 'bind_back'}}
}

{ // Mandates: is_constructible_v<decay_t<F>, F>
struct F {
F() = default;
F(const F&) = default;
F(F&) = delete;

void operator()() {}
};

F f;
auto f1 = std::bind_back(f);
// expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires decay_t<F> to be constructible from F}}
}

{ // Mandates: is_move_constructible_v<decay_t<F>>
struct F {
F() = default;
F(const F&) = default;
F(F&&) = delete;

void operator()() {}
};

F f;
auto f1 = std::bind_back(f);
// expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires decay_t<F> to be move constructible}}
}

{ // Mandates: (is_constructible_v<decay_t<Args>, Args> && ...)
struct Arg {
Arg() = default;
Arg(const Arg&) = default;
Arg(Arg&) = delete;
};

Arg x;
auto f = std::bind_back([](const Arg&) {}, x);
// expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires all decay_t<Args> to be constructible from respective Args}}
// expected-error@*:* {{no matching constructor for initialization}}
}

{ // Mandates: (is_move_constructible_v<decay_t<Args>> && ...)
struct Arg {
Arg() = default;
Arg(const Arg&) = default;
Arg(Arg&&) = delete;
};

Arg x;
auto f = std::bind_back([](Arg&) {}, x);
// expected-error-re@*:* {{static assertion failed{{.*}}bind_back requires all decay_t<Args> to be move constructible}}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef TEST_STD_UTILITIES_FUNCTION_OBJECTS_FUNC_BIND_PARTIAL_TYPES_H
#define TEST_STD_UTILITIES_FUNCTION_OBJECTS_FUNC_BIND_PARTIAL_TYPES_H

#include <tuple>
#include <utility>

struct MakeTuple {
template <class... Args>
constexpr auto operator()(Args&&... args) const {
return std::make_tuple(std::forward<Args>(args)...);
}
};

template <int X>
struct Elem {
template <int Y>
constexpr bool operator==(const Elem<Y>&) const {
return X == Y;
}
};

struct CopyMoveInfo {
enum { none, copy, move } copy_kind;

constexpr CopyMoveInfo() : copy_kind(none) {}
constexpr CopyMoveInfo(const CopyMoveInfo&) : copy_kind(copy) {}
constexpr CopyMoveInfo(CopyMoveInfo&&) : copy_kind(move) {}
};

template <class T>
T do_nothing(T t) {
return t;
}

#endif // TEST_STD_UTILITIES_FUNCTION_OBJECTS_FUNC_BIND_PARTIAL_TYPES_H
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <functional>
#include <cassert>
#include <concepts>
#include <tuple>
#include <type_traits>
#include <utility>
Expand Down Expand Up @@ -142,12 +143,13 @@ constexpr bool test() {

// Basic tests with fundamental types
{
int n = 2;
int m = 1;
auto add = [](int x, int y) { return x + y; };
auto addN = [](int a, int b, int c, int d, int e, int f) {
return a + b + c + d + e + f;
};
int n = 2;
int m = 1;
int sum = 0;
auto add = [](int x, int y) { return x + y; };
auto addN = [](int a, int b, int c, int d, int e, int f) { return a + b + c + d + e + f; };
auto add_ref = [&](int x, int y) -> int& { return sum = x + y; };
auto add_rref = [&](int x, int y) -> int&& { return std::move(sum = x + y); };

auto a = std::bind_front(add, m, n);
assert(a() == 3);
Expand All @@ -158,6 +160,14 @@ constexpr bool test() {
auto c = std::bind_front(addN, n, m);
assert(c(1, 1, 1, 1) == 7);

auto d = std::bind_front(add_ref, n, m);
std::same_as<int&> decltype(auto) dresult(d());
assert(dresult == 3);

auto e = std::bind_front(add_rref, n, m);
std::same_as<int&&> decltype(auto) eresult(e());
assert(eresult == 3);

auto f = std::bind_front(add, n);
assert(f(3) == 5);

Expand All @@ -166,6 +176,14 @@ constexpr bool test() {

auto h = std::bind_front(addN, 1, 1, 1);
assert(h(2, 2, 2) == 9);

auto i = std::bind_front(add_ref, n);
std::same_as<int&> decltype(auto) iresult(i(5));
assert(iresult == 7);

auto j = std::bind_front(add_rref, m);
std::same_as<int&&> decltype(auto) jresult(j(4));
assert(jresult == 5);
}

// Make sure we don't treat std::reference_wrapper specially.
Expand Down
3 changes: 1 addition & 2 deletions libcxx/utils/generate_feature_test_macro_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,9 @@ def add_version_header(tc):
"name": "__cpp_lib_bind_back",
"values": {
"c++23": 202202,
"c++26": 202306, # P2714R1 Bind front and back to NTTP callables
# "c++26": 202306, # P2714R1 Bind front and back to NTTP callables
},
"headers": ["functional"],
"unimplemented": True,
},
{
"name": "__cpp_lib_bind_front",
Expand Down
12 changes: 4 additions & 8 deletions lldb/bindings/interface/SBMemoryRegionInfoDocstrings.i
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,30 @@
"API clients can get information about memory regions in processes."
) lldb::SBMemoryRegionInfo;

%feature("autodoc", "
GetRegionEnd(SBMemoryRegionInfo self) -> lldb::addr_t
%feature("docstring", "
Returns whether this memory region has a list of modified (dirty)
pages available or not. When calling GetNumDirtyPages(), you will
have 0 returned for both \"dirty page list is not known\" and
\"empty dirty page list\" (that is, no modified pages in this
memory region). You must use this method to disambiguate."
) lldb::SBMemoryRegionInfo::HasDirtyMemoryPageList;

%feature("autodoc", "
GetNumDirtyPages(SBMemoryRegionInfo self) -> uint32_t
%feature("docstring", "
Return the number of dirty (modified) memory pages in this
memory region, if available. You must use the
SBMemoryRegionInfo::HasDirtyMemoryPageList() method to
determine if a dirty memory list is available; it will depend
on the target system can provide this information."
) lldb::SBMemoryRegionInfo::GetNumDirtyPages;

%feature("autodoc", "
GetDirtyPageAddressAtIndex(SBMemoryRegionInfo self, uint32_t idx) -> lldb::addr_t
%feature("docstring", "
Return the address of a modified, or dirty, page of memory.
If the provided index is out of range, or this memory region
does not have dirty page information, LLDB_INVALID_ADDRESS
is returned."
) lldb::SBMemoryRegionInfo::GetDirtyPageAddressAtIndex;

%feature("autodoc", "
GetPageSize(SBMemoryRegionInfo self) -> int
%feature("docstring", "
Return the size of pages in this memory region. 0 will be returned
if this information was unavailable."
) lldb::SBMemoryRegionInfo::GetPageSize();
Loading