| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,346 @@ | ||
| // RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s | ||
|
|
||
| // Test this with PCH. | ||
| // RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s | ||
| // RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s | ||
| #ifndef PCH_HELPER | ||
| #define PCH_HELPER | ||
|
|
||
| template<unsigned I, typename ConvertsToInt, typename Int> | ||
| void TemplUses(ConvertsToInt CTI, Int IsI) { | ||
| // CHECK: FunctionTemplateDecl{{.*}}TemplUses | ||
| // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'unsigned int' depth 0 index 0 I | ||
| // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 ConvertsToInt | ||
| // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 Int | ||
| // CHECK-NEXT: FunctionDecl{{.*}}TemplUses 'void (ConvertsToInt, Int)' | ||
| // CHECK-NEXT: ParmVarDecl{{.*}}CTI 'ConvertsToInt' | ||
| // CHECK-NEXT: ParmVarDecl{{.*}}IsI 'Int' | ||
| // CHECK-NEXT: CompoundStmt | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc loop vector | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'unsigned int' NonTypeTemplateParm{{.*}}'I' 'unsigned int' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc loop vector(I) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'ConvertsToInt' lvalue ParmVar{{.*}}'CTI' 'ConvertsToInt' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc loop vector(length:CTI) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'Int' lvalue ParmVar{{.*}}'IsI' 'Int' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc parallel | ||
| #pragma acc loop vector(length:IsI) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} serial | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc serial | ||
| #pragma acc loop vector | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'Int' lvalue ParmVar{{.*}}'IsI' 'Int' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc kernels | ||
| #pragma acc loop vector(length:IsI) | ||
| for(;;); | ||
|
|
||
|
|
||
| // Instantiations: | ||
| // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (Converts, int)' implicit_instantiation | ||
| // CHECK-NEXT: TemplateArgument integral '3U' | ||
| // CHECK-NEXT: TemplateArgument type 'Converts' | ||
| // CHECK-NEXT: RecordType{{.*}}'Converts' | ||
| // CHECK-NEXT: CXXRecord{{.*}}'Converts | ||
| // CHECK-NEXT: TemplateArgument type 'int' | ||
| // CHECK-NEXT: BuiltinType{{.*}}'int' | ||
| // CHECK-NEXT: ParmVarDecl{{.*}} CTI 'Converts' | ||
| // CHECK-NEXT: ParmVarDecl{{.*}} IsI 'int' | ||
| // CHECK-NEXT: CompoundStmt | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| // | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'unsigned int' | ||
| // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}}'unsigned int' depth 0 index 0 I | ||
| // CHECK-NEXT: IntegerLiteral{{.*}} 'unsigned int' 3 | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| // | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <UserDefinedConversion> | ||
| // CHECK-NEXT: CXXMemberCallExpr{{.*}}'int' | ||
| // CHECK-NEXT: MemberExpr{{.*}} .operator int | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'Converts' lvalue ParmVar{{.*}}'CTI' 'Converts' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| // | ||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <LValueToRValue> | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}}'IsI' 'int' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| // | ||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} serial | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| // | ||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <LValueToRValue> | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}}'IsI' 'int' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
|
|
||
|
|
||
| } | ||
|
|
||
| struct Converts{ | ||
| operator int(); | ||
| }; | ||
|
|
||
| void uses() { | ||
| // CHECK: FunctionDecl{{.*}} uses | ||
| // CHECK-NEXT: CompoundStmt | ||
|
|
||
| // CHECK-NEXT: CallExpr | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'void (*)(Converts, int)' <FunctionToPointerDecay> | ||
| // CHECK-NEXT: DeclRefExpr{{.*}} 'void (Converts, int)' lvalue Function{{.*}} 'TemplUses' 'void (Converts, int)' | ||
| // CHECK-NEXT: CXXFunctionalCastExpr{{.*}} 'Converts' functional cast to Converts <NoOp> | ||
| // CHECK-NEXT: InitListExpr | ||
| // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 5 | ||
| TemplUses<3>(Converts{}, 5); | ||
|
|
||
| // CHECK-NEXT: DeclStmt | ||
| // CHECK-NEXT: VarDecl{{.*}} | ||
| int i; | ||
| // CHECK-NEXT: DeclStmt | ||
| // CHECK-NEXT: VarDecl{{.*}} | ||
| // CHECK-NEXT: CXXConstructExpr | ||
| Converts C; | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc loop vector | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <LValueToRValue> | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc loop vector(i) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}}<orphan> | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <UserDefinedConversion> | ||
| // CHECK-NEXT: CXXMemberCallExpr{{.*}}'int' | ||
| // CHECK-NEXT: MemberExpr{{.*}} .operator int | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'Converts' lvalue Var{{.*}}'C' 'Converts' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc loop vector(length:C) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc parallel | ||
| #pragma acc loop vector | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <UserDefinedConversion> | ||
| // CHECK-NEXT: CXXMemberCallExpr{{.*}}'int' | ||
| // CHECK-NEXT: MemberExpr{{.*}} .operator int | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'Converts' lvalue Var{{.*}}'C' 'Converts' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc parallel | ||
| #pragma acc loop vector(C) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} parallel | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <LValueToRValue> | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc parallel | ||
| #pragma acc loop vector(length:i) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc kernels | ||
| #pragma acc loop vector | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <UserDefinedConversion> | ||
| // CHECK-NEXT: CXXMemberCallExpr{{.*}}'int' | ||
| // CHECK-NEXT: MemberExpr{{.*}} .operator int | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'Converts' lvalue Var{{.*}}'C' 'Converts' | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc kernels | ||
| #pragma acc loop vector(C) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} kernels | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ImplicitCastExpr{{.*}}'int' <LValueToRValue> | ||
| // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc kernels | ||
| #pragma acc loop vector(length:i) | ||
| for(;;); | ||
|
|
||
| // CHECK-NEXT: OpenACCComputeConstruct 0x[[COMPUTE_ADDR:[0-9a-f]+]]{{.*}} serial | ||
| // CHECK-NEXT: OpenACCLoopConstruct{{.*}} parent: 0x[[COMPUTE_ADDR]] | ||
| // CHECK-NEXT: vector clause | ||
| // CHECK-NEXT: ForStmt | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: <<<NULL>>> | ||
| // CHECK-NEXT: NullStmt | ||
| #pragma acc serial | ||
| #pragma acc loop vector | ||
| for(;;); | ||
| } | ||
| #endif // PCH_HELPER |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| // RUN: %clang_cc1 %s -fopenacc -verify | ||
|
|
||
| template<typename Int, typename NotInt, typename ConvertsToInt> | ||
| void TemplUses(Int I, NotInt NI, ConvertsToInt CTI) { | ||
| #pragma acc loop vector(I) | ||
| for(;;); | ||
|
|
||
| #pragma acc parallel | ||
| #pragma acc loop vector(length: I) | ||
| for(;;); | ||
|
|
||
| #pragma acc kernels | ||
| #pragma acc loop vector(CTI) | ||
| for(;;); | ||
|
|
||
| // expected-error@+2{{OpenACC clause 'vector' requires expression of integer type ('NoConvert' invalid)}} | ||
| #pragma acc kernels | ||
| #pragma acc loop vector(length: NI) | ||
| for(;;); | ||
|
|
||
| // expected-error@+2{{'num' argument on 'vector' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}} | ||
| #pragma acc serial | ||
| #pragma acc loop vector(length: I) | ||
| for(;;); | ||
|
|
||
| // expected-error@+3{{'num' argument to 'vector' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'vector_length' clause}} | ||
| // expected-note@+1{{previous clause is here}} | ||
| #pragma acc kernels vector_length(I) | ||
| #pragma acc loop vector(length: CTI) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| for(;;); | ||
| // expected-error@+2{{loop with a 'vector' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-note@-4{{previous clause is here}} | ||
| #pragma acc loop vector | ||
| for(;;); | ||
| for(;;); | ||
| } | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| for(;;); | ||
| // expected-error@+4{{loop with a 'vector' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-note@-6 3{{previous clause is here}} | ||
| #pragma acc loop vector, worker, gang | ||
| for(;;); | ||
| for(;;); | ||
| } | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| #pragma acc serial | ||
| #pragma acc loop vector | ||
| for(;;); | ||
| } | ||
| } | ||
|
|
||
| struct NoConvert{}; | ||
| struct Converts{ | ||
| operator int(); | ||
| }; | ||
|
|
||
| void uses() { | ||
| TemplUses(5, NoConvert{}, Converts{}); // expected-note{{in instantiation of function template specialization}} | ||
|
|
||
| unsigned i; | ||
| NoConvert NI; | ||
| Converts CTI; | ||
|
|
||
| #pragma acc loop vector(i) | ||
| for(;;); | ||
|
|
||
| #pragma acc parallel | ||
| #pragma acc loop vector(length: i) | ||
| for(;;); | ||
|
|
||
| #pragma acc kernels | ||
| #pragma acc loop vector(CTI) | ||
| for(;;); | ||
|
|
||
| // expected-error@+2{{OpenACC clause 'vector' requires expression of integer type ('NoConvert' invalid)}} | ||
| #pragma acc kernels | ||
| #pragma acc loop vector(length: NI) | ||
| for(;;); | ||
|
|
||
| // expected-error@+2{{'num' argument on 'vector' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}} | ||
| #pragma acc serial | ||
| #pragma acc loop vector(length: i) | ||
| for(;;); | ||
|
|
||
| // expected-error@+3{{'num' argument to 'vector' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'vector_length' clause}} | ||
| // expected-note@+1{{previous clause is here}} | ||
| #pragma acc kernels vector_length(i) | ||
| #pragma acc loop vector(length: i) | ||
| for(;;); | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| for(;;); | ||
| // expected-error@+2{{loop with a 'vector' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-note@-4{{previous clause is here}} | ||
| #pragma acc loop vector | ||
| for(;;); | ||
| for(;;); | ||
| } | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| #pragma acc serial | ||
| #pragma acc loop vector | ||
| for(;;); | ||
| } | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| for(;;); | ||
| // expected-error@+4{{loop with a 'vector' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'vector' clause}} | ||
| // expected-note@-6 3{{previous clause is here}} | ||
| #pragma acc loop vector, worker, gang | ||
| for(;;); | ||
| for(;;); | ||
| } | ||
|
|
||
| #pragma acc loop vector | ||
| for(;;) { | ||
| #pragma acc serial | ||
| #pragma acc loop vector, worker, gang | ||
| for(;;); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| // RUN: %clangxx_asan -fexceptions -O %s -o %t && %env_asan_opts=detect_stack_use_after_return=0 %run %t | ||
| // | ||
| // Test __sanitizer_copy_contiguous_container_annotations. | ||
|
|
||
| #include <algorithm> | ||
| #include <iostream> | ||
| #include <memory> | ||
| #include <numeric> | ||
| #include <vector> | ||
|
|
||
| #include <assert.h> | ||
| #include <sanitizer/asan_interface.h> | ||
| #include <stdio.h> | ||
| #include <stdlib.h> | ||
| #include <string.h> | ||
|
|
||
| static constexpr size_t kGranularity = 8; | ||
|
|
||
| template <class T> static constexpr T RoundDown(T x) { | ||
| return reinterpret_cast<T>(reinterpret_cast<uintptr_t>(x) & | ||
| ~(kGranularity - 1)); | ||
| } | ||
| template <class T> static constexpr T RoundUp(T x) { | ||
| return reinterpret_cast<T>( | ||
| RoundDown(reinterpret_cast<uintptr_t>(x) + kGranularity - 1)); | ||
| } | ||
|
|
||
| static std::vector<int> GetPoisonedState(char *begin, char *end) { | ||
| std::vector<int> result; | ||
| for (char *ptr = begin; ptr != end; ++ptr) { | ||
| result.push_back(__asan_address_is_poisoned(ptr)); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| static void RandomPoison(char *beg, char *end) { | ||
| assert(beg == RoundDown(beg)); | ||
| assert(end == RoundDown(end)); | ||
| __asan_poison_memory_region(beg, end - beg); | ||
| for (beg = RoundUp(beg); beg < end; beg += kGranularity) { | ||
| __asan_unpoison_memory_region(beg, rand() % (kGranularity + 1)); | ||
| } | ||
| } | ||
|
|
||
| template <bool benchmark> | ||
| static void Test(size_t capacity, size_t off_src, size_t off_dst, | ||
| char *src_buffer_beg, char *src_buffer_end, | ||
| char *dst_buffer_beg, char *dst_buffer_end) { | ||
| size_t dst_buffer_size = dst_buffer_end - dst_buffer_beg; | ||
| char *src_beg = src_buffer_beg + off_src; | ||
| char *src_end = src_beg + capacity; | ||
|
|
||
| char *dst_beg = dst_buffer_beg + off_dst; | ||
| char *dst_end = dst_beg + capacity; | ||
| if (benchmark) { | ||
| __sanitizer_copy_contiguous_container_annotations(src_beg, src_end, dst_beg, | ||
| dst_end); | ||
| return; | ||
| } | ||
|
|
||
| std::vector<int> src_poison_states = | ||
| GetPoisonedState(src_buffer_beg, src_buffer_end); | ||
| std::vector<int> dst_poison_before = | ||
| GetPoisonedState(dst_buffer_beg, dst_buffer_end); | ||
| __sanitizer_copy_contiguous_container_annotations(src_beg, src_end, dst_beg, | ||
| dst_end); | ||
| std::vector<int> dst_poison_after = | ||
| GetPoisonedState(dst_buffer_beg, dst_buffer_end); | ||
|
|
||
| // Create ideal copy of src over dst. | ||
| std::vector<int> dst_poison_exp = dst_poison_before; | ||
| for (size_t cur = 0; cur < capacity; ++cur) | ||
| dst_poison_exp[off_dst + cur] = src_poison_states[off_src + cur]; | ||
|
|
||
| // Unpoison prefixes of Asan granules. | ||
| for (size_t cur = dst_buffer_size - 1; cur > 0; --cur) { | ||
| if (cur % kGranularity != 0 && !dst_poison_exp[cur]) | ||
| dst_poison_exp[cur - 1] = 0; | ||
| } | ||
|
|
||
| if (dst_poison_after != dst_poison_exp) { | ||
| std::cerr << "[" << off_dst << ", " << off_dst + capacity << ")\n"; | ||
| for (size_t i = 0; i < dst_poison_after.size(); ++i) { | ||
| std::cerr << i << ":\t" << dst_poison_before[i] << "\t" | ||
| << dst_poison_after[i] << "\t" << dst_poison_exp[i] << "\n"; | ||
| } | ||
| std::cerr << "----------\n"; | ||
|
|
||
| assert(dst_poison_after == dst_poison_exp); | ||
| } | ||
| } | ||
|
|
||
| template <bool benchmark> | ||
| static void TestNonOverlappingContainers(size_t capacity, size_t off_src, | ||
| size_t off_dst) { | ||
| // Test will copy [off_src, off_src + capacity) to [off_dst, off_dst + capacity). | ||
| // Allocate buffers to have additional granule before and after tested ranges. | ||
| off_src += kGranularity; | ||
| off_dst += kGranularity; | ||
| size_t src_buffer_size = RoundUp(off_src + capacity) + kGranularity; | ||
| size_t dst_buffer_size = RoundUp(off_dst + capacity) + kGranularity; | ||
|
|
||
| std::unique_ptr<char[]> src_buffer = | ||
| std::make_unique<char[]>(src_buffer_size); | ||
| std::unique_ptr<char[]> dst_buffer = | ||
| std::make_unique<char[]>(dst_buffer_size); | ||
|
|
||
| char *src_buffer_beg = src_buffer.get(); | ||
| char *src_buffer_end = src_buffer_beg + src_buffer_size; | ||
| assert(RoundDown(src_buffer_beg) == src_buffer_beg); | ||
|
|
||
| char *dst_buffer_beg = dst_buffer.get(); | ||
| char *dst_buffer_end = dst_buffer_beg + dst_buffer_size; | ||
| assert(RoundDown(dst_buffer_beg) == dst_buffer_beg); | ||
|
|
||
| for (int i = 0; i < 35; i++) { | ||
| if (!benchmark || !i) { | ||
| RandomPoison(src_buffer_beg, src_buffer_end); | ||
| RandomPoison(dst_buffer_beg, dst_buffer_end); | ||
| } | ||
|
|
||
| Test<benchmark>(capacity, off_src, off_dst, src_buffer_beg, src_buffer_end, | ||
| dst_buffer_beg, dst_buffer_end); | ||
| } | ||
|
|
||
| __asan_unpoison_memory_region(src_buffer_beg, src_buffer_size); | ||
| __asan_unpoison_memory_region(dst_buffer_beg, dst_buffer_size); | ||
| } | ||
|
|
||
| template <bool benchmark> | ||
| static void TestOverlappingContainers(size_t capacity, size_t off_src, | ||
| size_t off_dst) { | ||
| // Test will copy [off_src, off_src + capacity) to [off_dst, off_dst + capacity). | ||
| // Allocate buffers to have additional granule before and after tested ranges. | ||
| off_src += kGranularity; | ||
| off_dst += kGranularity; | ||
| size_t buffer_size = | ||
| RoundUp(std::max(off_src, off_dst) + capacity) + kGranularity; | ||
|
|
||
| // Use unique_ptr with a custom deleter to manage the buffer | ||
| std::unique_ptr<char[]> buffer = std::make_unique<char[]>(buffer_size); | ||
|
|
||
| char *buffer_beg = buffer.get(); | ||
| char *buffer_end = buffer_beg + buffer_size; | ||
| assert(RoundDown(buffer_beg) == buffer_beg); | ||
|
|
||
| for (int i = 0; i < 35; i++) { | ||
| if (!benchmark || !i) | ||
| RandomPoison(buffer_beg, buffer_end); | ||
| Test<benchmark>(capacity, off_src, off_dst, buffer_beg, buffer_end, | ||
| buffer_beg, buffer_end); | ||
| } | ||
|
|
||
| __asan_unpoison_memory_region(buffer_beg, buffer_size); | ||
| } | ||
|
|
||
| int main(int argc, char **argv) { | ||
| int n = argc == 1 ? 64 : atoi(argv[1]); | ||
| for (size_t off_src = 0; off_src < kGranularity; off_src++) { | ||
| for (size_t off_dst = 0; off_dst < kGranularity; off_dst++) { | ||
| for (int capacity = 0; capacity <= n; capacity++) { | ||
| if (n < 1024) { | ||
| TestNonOverlappingContainers<false>(capacity, off_src, off_dst); | ||
| TestOverlappingContainers<false>(capacity, off_src, off_dst); | ||
| } else { | ||
| TestNonOverlappingContainers<true>(capacity, off_src, off_dst); | ||
| TestOverlappingContainers<true>(capacity, off_src, off_dst); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // Check that sanitizer prints registers dump_registers on dump_registers=1 | ||
| // RUN: %clangxx %s -o %t | ||
| // RUN: %env_tool_opts=dump_registers=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP | ||
| // RUN: not %run %t 2>&1 | FileCheck %s --strict-whitespace --check-prefix=CHECK-DUMP | ||
| // | ||
| // REQUIRES: aarch64-pc-windows-msvc | ||
|
|
||
| #include <windows.h> | ||
|
|
||
| int main() { | ||
| RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL); | ||
| // CHECK-DUMP: Register values | ||
| // CHECK-DUMP-NEXT: x0 = {{0x[0-9a-f]+}} x1 = {{0x[0-9a-f]+}} x2 = {{0x[0-9a-f]+}} x3 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT: x4 = {{0x[0-9a-f]+}} x5 = {{0x[0-9a-f]+}} x6 = {{0x[0-9a-f]+}} x7 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT: x8 = {{0x[0-9a-f]+}} x9 = {{0x[0-9a-f]+}} x10 = {{0x[0-9a-f]+}} x11 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT:x12 = {{0x[0-9a-f]+}} x13 = {{0x[0-9a-f]+}} x14 = {{0x[0-9a-f]+}} x15 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT:x16 = {{0x[0-9a-f]+}} x17 = {{0x[0-9a-f]+}} x18 = {{0x[0-9a-f]+}} x19 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT:x20 = {{0x[0-9a-f]+}} x21 = {{0x[0-9a-f]+}} x22 = {{0x[0-9a-f]+}} x23 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT:x24 = {{0x[0-9a-f]+}} x25 = {{0x[0-9a-f]+}} x26 = {{0x[0-9a-f]+}} x27 = {{0x[0-9a-f]+}} | ||
| // CHECK-DUMP-NEXT:x28 = {{0x[0-9a-f]+}} fp = {{0x[0-9a-f]+}} lr = {{0x[0-9a-f]+}} sp = {{0x[0-9a-f]+}} | ||
| // CHECK-NODUMP-NOT: Register values | ||
| return 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,5 +6,5 @@ def getRoot(config): | |
|
|
||
| root = getRoot(config) | ||
|
|
||
| if root.host_os in ["Windows"]: | ||
| config.unsupported = True | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,7 +32,6 @@ | |
| !CHECK: } | ||
| !CHECK: omp.yield | ||
| !CHECK: } | ||
| !CHECK: } | ||
| subroutine lastprivate_common | ||
| common /c/ x, y | ||
|
|
||