| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -fblocks -verify %s | ||
|
|
||
| int* f1(void) { | ||
| int x = 0; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // RUN: %clang --target=x86_64-pc-windows -fasync-exceptions -fsyntax-only %s -### 2>&1 | FileCheck %s | ||
| // RUN: %clang_cl --target=x86_64-pc-windows /EHa -fsyntax-only %s -### 2>&1 | FileCheck %s | ||
| // RUN: %clang --target=x86_64-pc-windows-gnu -fasync-exceptions -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefixes=GNU-ALL,GNU | ||
| // RUN: %clang_cl --target=x86_64-pc-windows-gnu /EHa -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefixes=GNU-ALL,CL-GNU | ||
|
|
||
| // CHECK-NOT: warning | ||
| // GNU: warning: argument unused during compilation: '-fasync-exceptions' [-Wunused-command-line-argument] | ||
| // CL-GNU: warning: argument unused during compilation: '/EHa' [-Wunused-command-line-argument] | ||
|
|
||
| // CHECK: -fasync-exceptions | ||
| // GNU-ALL-NOT: -fasync-exceptions | ||
| struct S { | ||
| union _Un { | ||
| ~_Un() {} | ||
| char _Buf[12]; | ||
| }; | ||
| _Un _un; | ||
| }; | ||
|
|
||
| struct Embed { | ||
| S v2; | ||
| }; | ||
|
|
||
| void PR62449() { Embed v{}; } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| // RUN: rm -rf %t | ||
| // RUN: mkdir -p %t | ||
| // RUN: split-file %s %t | ||
| // | ||
| // RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf %t/A.cppm -emit-module-interface -o %t/A.pcm | ||
| // RUN: %clang_cc1 -std=c++20 -fskip-odr-check-in-gmf %t/test.cpp -fprebuilt-module-path=%t -fsyntax-only -verify | ||
|
|
||
| //--- header.h | ||
| #pragma once | ||
| template <class _Tp> | ||
| class Optional {}; | ||
|
|
||
| template <class _Tp> | ||
| concept C = requires(const _Tp& __t) { | ||
| []<class _Up>(const Optional<_Up>&) {}(__t); | ||
| }; | ||
|
|
||
| //--- func.h | ||
| #include "header.h" | ||
| template <C T> | ||
| void func() {} | ||
|
|
||
| //--- test_func.h | ||
| #include "func.h" | ||
|
|
||
| inline void test_func() { | ||
| func<Optional<int>>(); | ||
| } | ||
|
|
||
| //--- A.cppm | ||
| module; | ||
| #include "header.h" | ||
| #include "test_func.h" | ||
| export module A; | ||
| export using ::test_func; | ||
|
|
||
| //--- test.cpp | ||
| // expected-no-diagnostics | ||
| import A; | ||
| #include "test_func.h" | ||
|
|
||
| void test() { | ||
| test_func(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // RUN: %clang_cc1 -std=c++20 -verify %s | ||
| // RUN: %clang_cc1 -std=c++23 -verify %s | ||
| // expected-no-diagnostics | ||
|
|
||
| struct B { | ||
| template <typename S> | ||
| void foo(); | ||
|
|
||
| void bar(); | ||
| }; | ||
|
|
||
| template <typename T, typename S> | ||
| struct A : T { | ||
| auto foo() { | ||
| static_assert(requires { T::template foo<S>(); }); | ||
| static_assert(requires { T::bar(); }); | ||
| } | ||
| }; | ||
|
|
||
| int main() { | ||
| A<B, double> a; | ||
| a.foo(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // RUN: fir-opt -split-input-file -verify-diagnostics %s | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %1 = fir.alloca i32 | ||
| %pinned = fir.alloca i1 | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %s = fir.load %1 : !fir.ref<i32> | ||
| // expected-error@+1{{'fir.cuda_allocate' op pinned and stream cannot appears at the same time}} | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> stream(%s : i32) pinned(%pinned : !fir.ref<i1>) {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %1 = fir.alloca i32 | ||
| // expected-error@+1{{'fir.cuda_allocate' op expect box to be a reference to/or a class or box type value}} | ||
| %2 = fir.cuda_allocate %1 : !fir.ref<i32> {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %c100 = arith.constant 100 : index | ||
| %7 = fir.alloca !fir.char<1,100> {bindc_name = "msg", uniq_name = "_QFsub1Emsg"} | ||
| %8:2 = hlfir.declare %7 typeparams %c100 {uniq_name = "_QFsub1Emsg"} : (!fir.ref<!fir.char<1,100>>, index) -> (!fir.ref<!fir.char<1,100>>, !fir.ref<!fir.char<1,100>>) | ||
| %9 = fir.embox %8#1 : (!fir.ref<!fir.char<1,100>>) -> !fir.box<!fir.char<1,100>> | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %16 = fir.convert %9 : (!fir.box<!fir.char<1,100>>) -> !fir.box<none> | ||
| // expected-error@+1{{'fir.cuda_allocate' op expect stat attribute when errmsg is provided}} | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %1 = fir.alloca i32 | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| // expected-error@+1{{'fir.cuda_allocate' op expect errmsg to be a reference to/or a box type value}} | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%1 : !fir.ref<i32>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32 | ||
| return | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| // RUN: fir-opt --split-input-file %s | fir-opt --split-input-file | FileCheck %s | ||
|
|
||
| // Simple round trip test of operations. | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> {cuda_attr = #fir.cuda<device>} -> i32 | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %1 = fir.alloca i32 | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %s = fir.load %1 : !fir.ref<i32> | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> stream(%s : i32) {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> stream(%{{.*}} : i32) {cuda_attr = #fir.cuda<device>} -> i32 | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %1 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "b", uniq_name = "_QFsub1Eb"} | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %5:2 = hlfir.declare %1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %12 = fir.convert %5#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> source(%12 : !fir.ref<!fir.box<none>>) {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> source(%{{.*}} : !fir.ref<!fir.box<none>>) {cuda_attr = #fir.cuda<device>} -> i32 | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %pinned = fir.alloca i1 | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> pinned(%pinned : !fir.ref<i1>) {cuda_attr = #fir.cuda<device>} -> i32 | ||
| return | ||
| } | ||
|
|
||
| // CHECK: fir.cuda_allocate %{{.*}} : !fir.ref<!fir.box<none>> pinned(%{{.*}} : !fir.ref<i1>) {cuda_attr = #fir.cuda<device>} -> i32 | ||
|
|
||
| // ----- | ||
|
|
||
| func.func @_QPsub1() { | ||
| %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {bindc_name = "a", uniq_name = "_QFsub1Ea"} | ||
| %4:2 = hlfir.declare %0 {cuda_attr = #fir.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub1Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) | ||
| %c100 = arith.constant 100 : index | ||
| %7 = fir.alloca !fir.char<1,100> {bindc_name = "msg", uniq_name = "_QFsub1Emsg"} | ||
| %8:2 = hlfir.declare %7 typeparams %c100 {uniq_name = "_QFsub1Emsg"} : (!fir.ref<!fir.char<1,100>>, index) -> (!fir.ref<!fir.char<1,100>>, !fir.ref<!fir.char<1,100>>) | ||
| %9 = fir.embox %8#1 : (!fir.ref<!fir.char<1,100>>) -> !fir.box<!fir.char<1,100>> | ||
| %11 = fir.convert %4#1 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>> | ||
| %16 = fir.convert %9 : (!fir.box<!fir.char<1,100>>) -> !fir.box<none> | ||
| %13 = fir.cuda_allocate %11 : !fir.ref<!fir.box<none>> errmsg(%16 : !fir.box<none>) {cuda_attr = #fir.cuda<device>, hasStat} -> i32 | ||
| return | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| ! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s | ||
| ! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s | ||
|
|
||
| ! CHECK: not yet implemented: Reduction modifiers are not supported | ||
|
|
||
| subroutine foo() | ||
| integer :: i, j | ||
| j = 0 | ||
| !$omp do reduction (inscan, *: j) | ||
| do i = 1, 10 | ||
| j = j + 1 | ||
| end do | ||
| end subroutine |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| ! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s | ||
| ! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s | ||
|
|
||
| subroutine foo() | ||
| integer :: i, j | ||
| j = 0 | ||
| ! CHECK: !$OMP DO REDUCTION(TASK,*:j) | ||
| ! PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct | ||
| ! PARSE-TREE: | | | OmpBeginLoopDirective | ||
| ! PARSE-TREE: | | | | OmpLoopDirective -> llvm::omp::Directive = do | ||
| ! PARSE-TREE: | | | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause | ||
| ! PARSE-TREE: | | | | | ReductionModifier = Task | ||
| ! PARSE-TREE: | | | | | OmpReductionOperator -> DefinedOperator -> IntrinsicOperator = Multiply | ||
| ! PARSE-TREE: | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j | ||
| !$omp do reduction (task, *: j) | ||
| do i = 1, 10 | ||
| j = j + 1 | ||
| end do | ||
| !$omp end do | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| add_flang_unittest(FlangRuntimeTests | ||
| AccessTest.cpp | ||
| Allocatable.cpp | ||
| ArrayConstructor.cpp | ||
| BufferTest.cpp | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| //===-- Definition of macros from fenv_t.h --------------------------------===// | ||
| // | ||
| // 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 LLVM_LIBC_HDR_FENV_T_H | ||
| #define LLVM_LIBC_HDR_FENV_T_H | ||
|
|
||
| #ifdef LIBC_FULL_BUILD | ||
|
|
||
| #include "include/llvm-libc-types/fenv_t.h" | ||
|
|
||
| #else // Overlay mode | ||
|
|
||
| #include <fenv.h> | ||
|
|
||
| #endif // LLVM_LIBC_FULL_BUILD | ||
|
|
||
| #endif // LLVM_LIBC_HDR_FENV_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| //===-- Definition of macros from fexcept_t.h -----------------------------===// | ||
| // | ||
| // 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 LLVM_LIBC_HDR_FEXCEPT_T_H | ||
| #define LLVM_LIBC_HDR_FEXCEPT_T_H | ||
|
|
||
| #ifdef LIBC_FULL_BUILD | ||
|
|
||
| #include "include/llvm-libc-types/fexcept_t.h" | ||
|
|
||
| #else // Overlay mode | ||
|
|
||
| #include <fenv.h> | ||
|
|
||
| #endif // LLVM_LIBC_FULL_BUILD | ||
|
|
||
| #endif // LLVM_LIBC_HDR_FENV_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // 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 _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H | ||
| #define _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H | ||
|
|
||
| #include <__config> | ||
| #include <cstddef> | ||
|
|
||
| #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
| # pragma GCC system_header | ||
| #endif | ||
|
|
||
| _LIBCPP_PUSH_MACROS | ||
| #include <__undef_macros> | ||
|
|
||
| _LIBCPP_BEGIN_NAMESPACE_STD | ||
| namespace __pstl { | ||
|
|
||
| // __cpu_traits | ||
| // | ||
| // This traits class encapsulates the basis operations for a CPU-based implementation of the PSTL. | ||
| // All the operations in the PSTL can be implemented from these basis operations, so a pure CPU backend | ||
| // only needs to customize these traits in order to get an implementation of the whole PSTL. | ||
| // | ||
| // Basis operations | ||
| // ================ | ||
| // | ||
| // template <class _RandomAccessIterator, class _Functor> | ||
| // optional<__empty> __for_each(_RandomAccessIterator __first, _RandomAccessIterator __last, _Functor __func); | ||
| // - __func must take a subrange of [__first, __last) that should be executed in serial | ||
| // | ||
| // template <class _Iterator, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduction> | ||
| // optional<_Tp> __transform_reduce(_Iterator __first, _Iterator __last, _UnaryOp, _Tp __init, _BinaryOp, _Reduction); | ||
| // | ||
| // template <class _RandomAccessIterator1, | ||
| // class _RandomAccessIterator2, | ||
| // class _RandomAccessIterator3, | ||
| // class _Compare, | ||
| // class _LeafMerge> | ||
| // optional<_RandomAccessIterator3> __merge(_RandomAccessIterator1 __first1, | ||
| // _RandomAccessIterator1 __last1, | ||
| // _RandomAccessIterator2 __first2, | ||
| // _RandomAccessIterator2 __last2, | ||
| // _RandomAccessIterator3 __outit, | ||
| // _Compare __comp, | ||
| // _LeafMerge __leaf_merge); | ||
| // | ||
| // template <class _RandomAccessIterator, class _Comp, class _LeafSort> | ||
| // optional<__empty> __stable_sort(_RandomAccessIterator __first, | ||
| // _RandomAccessIterator __last, | ||
| // _Comp __comp, | ||
| // _LeafSort __leaf_sort); | ||
| // | ||
| // void __cancel_execution(); | ||
| // Cancel the execution of other jobs - they aren't needed anymore. This is not a binding request, | ||
| // some backends may not actually be able to cancel jobs. | ||
| // | ||
| // constexpr size_t __lane_size; | ||
| // Size of SIMD lanes. | ||
| // TODO: Merge this with __native_vector_size from __algorithm/simd_utils.h | ||
| // | ||
| // | ||
| // Exception handling | ||
| // ================== | ||
| // | ||
| // CPU backends are expected to report errors (i.e. failure to allocate) by returning a disengaged `optional` from their | ||
| // implementation. Exceptions shouldn't be used to report an internal failure-to-allocate, since all exceptions are | ||
| // turned into a program termination at the front-end level. When a backend returns a disengaged `optional` to the | ||
| // frontend, the frontend will turn that into a call to `std::__throw_bad_alloc();` to report the internal failure to | ||
| // the user. | ||
|
|
||
| template <class _Backend> | ||
| struct __cpu_traits; | ||
|
|
||
| } // namespace __pstl | ||
| _LIBCPP_END_NAMESPACE_STD | ||
|
|
||
| _LIBCPP_POP_MACROS | ||
|
|
||
| #endif // _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // 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 _LIBCPP___UTILITY_IS_VALID_RANGE_H | ||
| #define _LIBCPP___UTILITY_IS_VALID_RANGE_H | ||
|
|
||
| #include <__algorithm/comp.h> | ||
| #include <__config> | ||
| #include <__type_traits/is_constant_evaluated.h> | ||
|
|
||
| #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||
| # pragma GCC system_header | ||
| #endif | ||
|
|
||
| _LIBCPP_BEGIN_NAMESPACE_STD | ||
|
|
||
| template <class _Tp> | ||
| _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_SANITIZE("address") bool | ||
| __is_valid_range(const _Tp* __first, const _Tp* __last) { | ||
| if (__libcpp_is_constant_evaluated()) { | ||
| // If this is not a constant during constant evaluation, that is because __first and __last are not | ||
| // part of the same allocation. If they are part of the same allocation, we must still make sure they | ||
| // are ordered properly. | ||
| return __builtin_constant_p(__first <= __last) && __first <= __last; | ||
| } | ||
|
|
||
| return !__less<>()(__last, __first); | ||
| } | ||
|
|
||
| _LIBCPP_END_NAMESPACE_STD | ||
|
|
||
| #endif // _LIBCPP___UTILITY_IS_VALID_RANGE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include <__utility/is_valid_range.h> | ||
| #include <cassert> | ||
|
|
||
| #include "test_macros.h" | ||
|
|
||
| template <class T, class TQualified> | ||
| TEST_CONSTEXPR_CXX14 void check_type() { | ||
| { | ||
| // We need to ensure that the addresses of i and j are ordered as &i < &j for | ||
| // the test below to work portably, so we define them in a struct. | ||
| struct { | ||
| T i = 0; | ||
| T j = 0; | ||
| } storage; | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(&storage.i), static_cast<TQualified*>(&storage.i))); | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(&storage.i), static_cast<TQualified*>(&storage.i + 1))); | ||
|
|
||
| assert(!std::__is_valid_range(static_cast<TQualified*>(&storage.j), static_cast<TQualified*>(&storage.i))); | ||
| assert(!std::__is_valid_range(static_cast<TQualified*>(&storage.i + 1), static_cast<TQualified*>(&storage.i))); | ||
|
|
||
| // We detect this as being a valid range even though it is not really valid. | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(&storage.i), static_cast<TQualified*>(&storage.j))); | ||
| } | ||
|
|
||
| { | ||
| T arr[3] = {1, 2, 3}; | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(&arr[0]), static_cast<TQualified*>(&arr[0]))); | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(&arr[0]), static_cast<TQualified*>(&arr[1]))); | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(&arr[0]), static_cast<TQualified*>(&arr[2]))); | ||
|
|
||
| assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[1]), static_cast<TQualified*>(&arr[0]))); | ||
| assert(!std::__is_valid_range(static_cast<TQualified*>(&arr[2]), static_cast<TQualified*>(&arr[0]))); | ||
| } | ||
|
|
||
| #if TEST_STD_VER >= 20 | ||
| { | ||
| T* arr = new int[4]{1, 2, 3, 4}; | ||
| assert(std::__is_valid_range(static_cast<TQualified*>(arr), static_cast<TQualified*>(arr + 4))); | ||
| delete[] arr; | ||
| } | ||
| #endif | ||
| } | ||
|
|
||
| TEST_CONSTEXPR_CXX14 bool test() { | ||
| check_type<int, int>(); | ||
| check_type<int, int const>(); | ||
| check_type<int, int volatile>(); | ||
| check_type<int, int const volatile>(); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| int main(int, char**) { | ||
| test(); | ||
| #if TEST_STD_VER >= 14 | ||
| static_assert(test(), ""); | ||
| #endif | ||
|
|
||
| return 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # REQUIRES: x86 | ||
| # RUN: split-file %s %t.dir | ||
|
|
||
| # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/lib.s -filetype=obj -o %t.dir/lib.obj | ||
| # RUN: lld-link -out:%t.dir/lib.dll -dll -entry:DllMainCRTStartup %t.dir/lib.obj -lldmingw -implib:%t.dir/lib.lib | ||
|
|
||
| # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj | ||
| # RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib -opt:ref -debug:dwarf | ||
|
|
||
| #--- main.s | ||
| .global main | ||
| .section .text$main,"xr",one_only,main | ||
| main: | ||
| ret | ||
|
|
||
| .global other | ||
| .section .text$other,"xr",one_only,other | ||
| other: | ||
| movq .refptr.variable(%rip), %rax | ||
| movl (%rax), %eax | ||
| ret | ||
|
|
||
| .section .rdata$.refptr.variable,"dr",discard,.refptr.variable | ||
| .global .refptr.variable | ||
| .refptr.variable: | ||
| .quad variable | ||
|
|
||
| .section .debug_info | ||
| .long 1 | ||
| .quad variable | ||
| .long 2 | ||
|
|
||
| #--- lib.s | ||
| .global variable | ||
| .global DllMainCRTStartup | ||
| .text | ||
| DllMainCRTStartup: | ||
| ret | ||
| .data | ||
| variable: | ||
| .long 42 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,5 +27,8 @@ | |
| .text | ||
| main: | ||
| movl data(%rip), %eax | ||
| ret | ||
| .global _pei386_runtime_relocator | ||
| _pei386_runtime_relocator: | ||
| ret | ||
| .data | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # REQUIRES: x86 | ||
| # RUN: split-file %s %t.dir | ||
|
|
||
| # RUN: llvm-dlltool -m i386:x86-64 -d %t.dir/lib.def -D lib.dll -l %t.dir/lib.lib | ||
|
|
||
| # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/main.s -filetype=obj -o %t.dir/main.obj | ||
| # RUN: llvm-mc -triple=x86_64-windows-gnu %t.dir/func.s -filetype=obj -o %t.dir/func.obj | ||
| # RUN: env LLD_IN_TEST=1 not lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/lib.lib 2>&1 | FileCheck %s --check-prefix=ERR | ||
|
|
||
| # RUN: lld-link -lldmingw -out:%t.dir/main.exe -entry:main %t.dir/main.obj %t.dir/func.obj %t.dir/lib.lib 2>&1 | FileCheck %s --check-prefix=NOERR --allow-empty | ||
|
|
||
| # ERR: error: output image has runtime pseudo relocations, but the function _pei386_runtime_relocator is missing; it is needed for fixing the relocations at runtime | ||
|
|
||
| # NOERR-NOT: error | ||
|
|
||
| #--- main.s | ||
| .global main | ||
| .text | ||
| main: | ||
| ret | ||
|
|
||
| .data | ||
| .long 1 | ||
| .quad variable | ||
| .long 2 | ||
|
|
||
| #--- func.s | ||
| .global _pei386_runtime_relocator | ||
| .text | ||
| _pei386_runtime_relocator: | ||
| ret | ||
|
|
||
| #--- lib.def | ||
| EXPORTS | ||
| variable DATA | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # REQUIRES: loongarch | ||
| ## Test `ld -r` not changes the addend of R_LARCH_ALIGN. | ||
|
|
||
| # RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o | ||
| # RUN: ld.lld -r %t.64.o %t.64.o -o %t.64.r | ||
| # RUN: llvm-objdump -dr --no-show-raw-insn %t.64.r | FileCheck %s | ||
|
|
||
| # CHECK: <.text>: | ||
| # CHECK-NEXT: break 1 | ||
| # CHECK-NEXT: nop | ||
| # CHECK-NEXT: {{0*}}04: R_LARCH_ALIGN .text+0x804 | ||
| # CHECK-NEXT: nop | ||
| # CHECK-NEXT: nop | ||
| # CHECK-NEXT: break 2 | ||
| # CHECK-NEXT: break 0 | ||
| # CHECK-NEXT: break 0 | ||
| # CHECK-NEXT: break 0 | ||
| # CHECK-NEXT: break 1 | ||
| # CHECK-NEXT: nop | ||
| # CHECK-NEXT: {{0*}}24: R_LARCH_ALIGN .text+0x804 | ||
| # CHECK-NEXT: nop | ||
| # CHECK-NEXT: nop | ||
| # CHECK-NEXT: break 2 | ||
|
|
||
| .text | ||
| break 1 | ||
| .p2align 4, , 8 | ||
| break 2 |