90 changes: 90 additions & 0 deletions clang/test/AST/ByteCode/constexpr-vectors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -std=c++14 -fsyntax-only -verify
// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -fexperimental-new-constant-interpreter -std=c++14 -fsyntax-only -verify

using FourCharsVecSize __attribute__((vector_size(4))) = char;
using FourIntsVecSize __attribute__((vector_size(16))) = int;
using FourLongLongsVecSize __attribute__((vector_size(32))) = long long;
using FourFloatsVecSize __attribute__((vector_size(16))) = float;
using FourDoublesVecSize __attribute__((vector_size(32))) = double;
using FourI128VecSize __attribute__((vector_size(64))) = __int128;

using FourCharsExtVec __attribute__((ext_vector_type(4))) = char;
using FourIntsExtVec __attribute__((ext_vector_type(4))) = int;
using FourI128ExtVec __attribute__((ext_vector_type(4))) = __int128;

// Only int vs float makes a difference here, so we only need to test 1 of each.
// Test Char to make sure the mixed-nature of shifts around char is evident.
void CharUsage() {
constexpr auto H = FourCharsVecSize{-1, -1, 0, -1};
constexpr auto InvH = -H;
static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, "");

constexpr auto ae = ~FourCharsVecSize{1, 2, 10, 20};
static_assert(ae[0] == -2 && ae[1] == -3 && ae[2] == -11 && ae[3] == -21, "");

constexpr auto af = !FourCharsVecSize{0, 1, 8, -1};
static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
}

void CharExtVecUsage() {
constexpr auto H = FourCharsExtVec{-1, -1, 0, -1};
constexpr auto InvH = -H;
static_assert(InvH[0] == 1 && InvH[1] == 1 && InvH[2] == 0 && InvH[3] == 1, "");

constexpr auto ae = ~FourCharsExtVec{1, 2, 10, 20};
static_assert(ae[0] == -2 && ae[1] == -3 && ae[2] == -11 && ae[3] == -21, "");

constexpr auto af = !FourCharsExtVec{0, 1, 8, -1};
static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
}

void FloatUsage() {
constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00};
constexpr auto Z = -Y;
static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, "");

// Operator ~ is illegal on floats.
constexpr auto ae = ~FourFloatsVecSize{0, 1, 8, -1}; // expected-error {{invalid argument type}}

constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1};
static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
}

void FloatVecUsage() {
constexpr auto Y = FourFloatsVecSize{1.200000e+01, 1.700000e+01, -1.000000e+00, -1.000000e+00};
constexpr auto Z = -Y;
static_assert(Z[0] == -1.200000e+01 && Z[1] == -1.700000e+01 && Z[2] == 1.000000e+00 && Z[3] == 1.000000e+00, "");

// Operator ~ is illegal on floats.
constexpr auto ae = ~FourFloatsVecSize{0, 1, 8, -1}; // expected-error {{invalid argument type}}

constexpr auto af = !FourFloatsVecSize{0, 1, 8, -1};
static_assert(af[0] == -1 && af[1] == 0 && af[2] == 0 && af[3] == 0, "");
}

void I128Usage() {
// Operator ~ is illegal on floats, so no test for that.
constexpr auto c = ~FourI128VecSize{1, 2, 10, 20};
static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, "");

constexpr auto d = !FourI128VecSize{0, 1, 8, -1};
static_assert(d[0] == -1 && d[1] == 0 && d[2] == 0 && d[3] == 0, "");
}

void I128VecUsage() {
// Operator ~ is illegal on floats, so no test for that.
constexpr auto c = ~FourI128ExtVec{1, 2, 10, 20};
static_assert(c[0] == -2 && c[1] == -3 && c[2] == -11 && c[3] == -21, "");

constexpr auto d = !FourI128ExtVec{0, 1, 8, -1};
static_assert(d[0] == -1 && d[1] == 0 && d[2] == 0 && d[3] == 0, "");
}

using FourBoolsExtVec __attribute__((ext_vector_type(4))) = bool;
void BoolVecUsage() {
constexpr auto j = !FourBoolsExtVec{true, false, true, false};
static_assert(j[0] == false && j[1] == true && j[2] == false && j[3] == true, "");

constexpr auto k = ~FourBoolsExtVec{true, false, true, false};
static_assert(k[0] == false && k[1] == true && k[2] == false && k[3] == true, "");
}
16 changes: 5 additions & 11 deletions clang/test/AST/ByteCode/new-delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ constexpr typename std::remove_reference<T>::type&& move(T &&t) noexcept {

namespace cxx2a {
struct A {
int* p = new int(42); // both-note 7{{heap allocation performed here}}
int* p = new int(42); // both-note 3{{heap allocation performed here}}
consteval int ret_i() const { return p ? *p : 0; }
consteval A ret_a() const { return A{}; }
constexpr ~A() { delete p; }
Expand Down Expand Up @@ -433,9 +433,7 @@ void test() {
{ A k = to_lvalue_ref(A()); } // both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \
// both-note {{reference to temporary is not a constant expression}} \
// both-note {{temporary created here}}
{ A k = to_lvalue_ref(A().ret_a()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \
// both-note {{heap-allocated object is not a constant expression}} \
// both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \
{ A k = to_lvalue_ref(A().ret_a()); } // both-error {{'cxx2a::to_lvalue_ref' is not a constant expression}} \
// both-note {{reference to temporary is not a constant expression}} \
// both-note {{temporary created here}}
{ int k = A().ret_a().ret_i(); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \
Expand All @@ -445,19 +443,15 @@ void test() {
{ int k = const_a_ref(a); }
{ int k = rvalue_ref(A()); }
{ int k = rvalue_ref(std::move(a)); }
{ int k = const_a_ref(A().ret_a()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \
// both-note {{is not a constant expression}}
{ int k = const_a_ref(to_lvalue_ref(A().ret_a())); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \
// both-note {{is not a constant expression}}
{ int k = const_a_ref(A().ret_a()); }
{ int k = const_a_ref(to_lvalue_ref(A().ret_a())); }
{ int k = const_a_ref(to_lvalue_ref(std::move(a))); }
{ int k = by_value_a(A().ret_a()); }
{ int k = by_value_a(to_lvalue_ref(static_cast<const A&&>(a))); }
{ int k = (A().ret_a(), A().ret_i()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \
// both-note {{is not a constant expression}} \
// both-warning {{left operand of comma operator has no effect}}
{ int k = (const_a_ref(A().ret_a()), A().ret_i()); } // both-error {{'cxx2a::A::ret_a' is not a constant expression}} \
// both-note {{is not a constant expression}} \
// both-warning {{left operand of comma operator has no effect}}
{ int k = (const_a_ref(A().ret_a()), A().ret_i()); } // both-warning {{left operand of comma operator has no effect}}
}
}

Expand Down
165 changes: 165 additions & 0 deletions clang/test/Analysis/block-in-critical-section-inheritance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,168 @@ void gh_99628() {
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
m.unlock();
}

void no_false_positive_gh_104241() {
std::mutex m;
m.lock();
// If inheritance not handled properly, this unlock might not match the lock
// above because technically they act on different memory regions:
// __mutex_base and mutex.
m.unlock();
sleep(10); // no-warning
}

struct TwoMutexes {
std::mutex m1;
std::mutex m2;
};

void two_mutexes_no_false_negative(TwoMutexes &tm) {
tm.m1.lock();
// expected-note@-1 {{Entering critical section here}}
tm.m2.unlock();
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
tm.m1.unlock();
}

struct MyMutexBase1 : std::mutex {
void lock1() { lock(); }
// expected-note@-1 {{Entering critical section here}}
void unlock1() { unlock(); }
};
struct MyMutexBase2 : std::mutex {
void lock2() { lock(); }
void unlock2() { unlock(); }
};
struct MyMutex : MyMutexBase1, MyMutexBase2 {};
// MyMutex has two distinct std::mutex as base classes

void custom_mutex_tp(MyMutexBase1 &mb) {
mb.lock();
// expected-note@-1 {{Entering critical section here}}
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
mb.unlock();
}

void custom_mutex_tn(MyMutexBase1 &mb) {
mb.lock();
mb.unlock();
sleep(10);
}

void custom_mutex_cast_tp(MyMutexBase1 &mb) {
static_cast<std::mutex&>(mb).lock();
// expected-note@-1 {{Entering critical section here}}
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
static_cast<std::mutex&>(mb).unlock();
}

void custom_mutex_cast_tn(MyMutexBase1 &mb) {
static_cast<std::mutex&>(mb).lock();
static_cast<std::mutex&>(mb).unlock();
sleep(10);
}

void two_custom_mutex_bases_tp(MyMutex &m) {
m.lock1();
// expected-note@-1 {{Calling 'MyMutexBase1::lock1'}}
// expected-note@-2 {{Returning from 'MyMutexBase1::lock1'}}
m.unlock2();
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
m.unlock1();
}

void two_custom_mutex_bases_tn(MyMutex &m) {
m.lock1();
m.unlock1();
sleep(10);
}

void two_custom_mutex_bases_casts_tp(MyMutex &m) {
static_cast<MyMutexBase1&>(m).lock();
// expected-note@-1 {{Entering critical section here}}
static_cast<MyMutexBase2&>(m).unlock();
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
static_cast<MyMutexBase1&>(m).unlock();
}

void two_custom_mutex_bases_casts_tn(MyMutex &m) {
static_cast<MyMutexBase1&>(m).lock();
static_cast<MyMutexBase1&>(m).unlock();
sleep(10);
}

struct MutexVirtBase1 : virtual std::mutex {
void lock1() { lock(); }
// expected-note@-1 {{Entering critical section here}}
void unlock1() { unlock(); }
};

struct MutexVirtBase2 : virtual std::mutex {
void lock2() { lock(); }
void unlock2() { unlock(); }
};

struct CombinedVirtMutex : MutexVirtBase1, MutexVirtBase2 {};

void virt_inherited_mutexes_same_base_tn1(CombinedVirtMutex &cvt) {
cvt.lock1();
cvt.unlock1();
sleep(10);
}

void virt_inherited_mutexes_different_bases_tn(CombinedVirtMutex &cvt) {
cvt.lock1();
cvt.unlock2(); // Despite a different name, unlock2 acts on the same mutex as lock1
sleep(10);
}

void virt_inherited_mutexes_different_bases_tp(CombinedVirtMutex &cvt) {
cvt.lock1();
// expected-note@-1 {{Calling 'MutexVirtBase1::lock1'}}
// expected-note@-2 {{Returning from 'MutexVirtBase1::lock1'}}
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
cvt.unlock1();
}

namespace std {
template <class... MutexTypes> struct scoped_lock {
explicit scoped_lock(MutexTypes&... m);
~scoped_lock();
};
template <class MutexType> class scoped_lock<MutexType> {
public:
explicit scoped_lock(MutexType& m) : m(m) { m.lock(); }
~scoped_lock() { m.unlock(); }
private:
MutexType& m;
};
} // namespace std

namespace gh_104241 {
int magic_number;
std::mutex m;

void fixed() {
int current;
for (int items_processed = 0; items_processed < 100; ++items_processed) {
{
std::scoped_lock<std::mutex> guard(m);
current = magic_number;
}
sleep(current); // expected no warning
}
}
} // namespace gh_104241
42 changes: 42 additions & 0 deletions clang/test/Analysis/block-in-critical-section-nested-namespace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

// RUN: %clang_analyze_cc1 \
// RUN: -analyzer-checker=unix.BlockInCriticalSection \
// RUN: -std=c++11 \
// RUN: -analyzer-output text \
// RUN: -verify %s

unsigned int sleep(unsigned int seconds) {return 0;}
namespace std {
namespace __detail {
class __mutex_base {
public:
void lock();
};
} // namespace __detail

class mutex : public __detail::__mutex_base{
public:
void unlock();
bool try_lock();
};
} // namespace std

void gh_99628() {
std::mutex m;
m.lock();
// expected-note@-1 {{Entering critical section here}}
sleep(10);
// expected-warning@-1 {{Call to blocking function 'sleep' inside of critical section}}
// expected-note@-2 {{Call to blocking function 'sleep' inside of critical section}}
m.unlock();
}

void no_false_positive_gh_104241() {
std::mutex m;
m.lock();
// If inheritance not handled properly, this unlock might not match the lock
// above because technically they act on different memory regions:
// __mutex_base and mutex.
m.unlock();
sleep(10); // no-warning
}
20 changes: 10 additions & 10 deletions clang/test/Analysis/copy-elision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,19 @@ ClassWithoutDestructor make1(AddressVector<ClassWithoutDestructor> &v) {
return ClassWithoutDestructor(v);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithoutDestructor' is still \
referred to by the stack variable 'v' upon returning to the caller}}
referred to by the caller variable 'v' upon returning to the caller}}
}
ClassWithoutDestructor make2(AddressVector<ClassWithoutDestructor> &v) {
return make1(v);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithoutDestructor' is still \
referred to by the stack variable 'v' upon returning to the caller}}
referred to by the caller variable 'v' upon returning to the caller}}
}
ClassWithoutDestructor make3(AddressVector<ClassWithoutDestructor> &v) {
return make2(v);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithoutDestructor' is still \
referred to by the stack variable 'v' upon returning to the caller}}
referred to by the caller variable 'v' upon returning to the caller}}
}

void testMultipleReturns() {
Expand All @@ -193,7 +193,7 @@ void testMultipleReturns() {
void consume(ClassWithoutDestructor c) {
c.push();
// expected-warning@-1 {{Address of stack memory associated with local \
variable 'c' is still referred to by the stack variable 'v' upon returning \
variable 'c' is still referred to by the caller variable 'v' upon returning \
to the caller}}
}

Expand Down Expand Up @@ -267,7 +267,7 @@ struct TestCtorInitializer {
: c(ClassWithDestructor(v)) {}
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithDestructor' is still referred \
to by the stack variable 'v' upon returning to the caller}}
to by the caller variable 'v' upon returning to the caller}}
};

void testCtorInitializer() {
Expand Down Expand Up @@ -303,19 +303,19 @@ ClassWithDestructor make1(AddressVector<ClassWithDestructor> &v) {
return ClassWithDestructor(v);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithDestructor' is still referred \
to by the stack variable 'v' upon returning to the caller}}
to by the caller variable 'v' upon returning to the caller}}
}
ClassWithDestructor make2(AddressVector<ClassWithDestructor> &v) {
return make1(v);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithDestructor' is still referred \
to by the stack variable 'v' upon returning to the caller}}
to by the caller variable 'v' upon returning to the caller}}
}
ClassWithDestructor make3(AddressVector<ClassWithDestructor> &v) {
return make2(v);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'ClassWithDestructor' is still referred \
to by the stack variable 'v' upon returning to the caller}}
to by the caller variable 'v' upon returning to the caller}}
}

void testMultipleReturnsWithDestructors() {
Expand Down Expand Up @@ -360,7 +360,7 @@ void testMultipleReturnsWithDestructors() {
void consume(ClassWithDestructor c) {
c.push();
// expected-warning@-1 {{Address of stack memory associated with local \
variable 'c' is still referred to by the stack variable 'v' upon returning \
variable 'c' is still referred to by the caller variable 'v' upon returning \
to the caller}}
}

Expand Down Expand Up @@ -407,7 +407,7 @@ struct Foo {
Foo make1(Foo **r) {
return Foo(r);
// no-elide-warning@-1 {{Address of stack memory associated with temporary \
object of type 'Foo' is still referred to by the stack \
object of type 'Foo' is still referred to by the caller \
variable 'z' upon returning to the caller}}
}

Expand Down
4 changes: 2 additions & 2 deletions clang/test/Analysis/incorrect-checker-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ char const *p;
void f0() {
char const str[] = "This will change";
p = str;
} // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
// expected-note@-1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
} // expected-warning@-1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
// expected-note@-2{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
2 changes: 1 addition & 1 deletion clang/test/Analysis/loop-block-counts.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ void callee(void **p) {
int x;
*p = &x;
// expected-warning@-1 {{Address of stack memory associated with local \
variable 'x' is still referred to by the stack variable 'arr' upon \
variable 'x' is still referred to by the caller variable 'arr' upon \
returning to the caller}}
}

Expand Down
59 changes: 56 additions & 3 deletions clang/test/Analysis/nullability.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,65 @@
// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability -Wno-deprecated-non-prototype -verify %s
// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability,debug.ExprInspection -verify %s

void clang_analyzer_warnIfReached(void);

void it_takes_two(int a, int b);
void function_pointer_arity_mismatch() {
void function_pointer_arity_mismatch(void) {
void(*fptr)() = it_takes_two;
fptr(1); // no-crash expected-warning {{Function taking 2 arguments is called with fewer (1)}}
// expected-warning@-1 {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}}
}

void block_arity_mismatch() {
void block_arity_mismatch(void) {
void(^b)() = ^(int a, int b) { };
b(1); // no-crash expected-warning {{Block taking 2 arguments is called with fewer (1)}}
// expected-warning@-1 {{passing arguments to a function without a prototype is deprecated in all versions of C and is not supported in C23}}
}

int *nonnull_return_annotation_indirect(void) __attribute__((returns_nonnull));
int *nonnull_return_annotation_indirect(void) {
int *x = 0;
return x; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
}

int *nonnull_return_annotation_direct(void) __attribute__((returns_nonnull));
int *nonnull_return_annotation_direct(void) {
return 0; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
} // expected-warning@-1 {{null returned from function that requires a non-null return value}}

int *nonnull_return_annotation_assumed(int* ptr) __attribute__((returns_nonnull));
int *nonnull_return_annotation_assumed(int* ptr) {
if (ptr) {
return ptr;
}
return ptr; // expected-warning {{Null returned from a function that is expected to return a non-null value}}
}

int *produce_nonnull_ptr(void) __attribute__((returns_nonnull));

__attribute__((returns_nonnull))
int *cannot_return_null(void) {
int *x = produce_nonnull_ptr();
if (!x) {
clang_analyzer_warnIfReached();
// expected-warning@-1 {{REACHABLE}}
// TODO: This warning is a false positive, according to the contract of
// produce_nonnull_ptr, x cannot be null.
}
// Regardless of the potential state split above, x cannot be nullptr
// according to the produce_nonnull_ptr annotation.
return x;
// False positive: expected-warning@-1 {{Null returned from a function that is expected to return a non-null value}}
}

__attribute__((returns_nonnull)) int *passthrough(int *p) {
return p; // no-warning: we have no evidence that `p` is null, i.e., violating the contract
}

__attribute__((returns_nonnull)) int *passthrough2(int *p);
int *passthrough2(int *p) {
return p; // expected-warning{{Null returned from a function that is expected to return a non-null value}}
}

void call_with_null(void) {
passthrough2(0);
}
2 changes: 1 addition & 1 deletion clang/test/Analysis/nullability.mm
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ -(Dummy *)callerWithParam:(Dummy * _Nonnull) p1 {

int * _Nonnull InlinedReturnNullOverSuppressionCallee(int * _Nonnull p2) {
int *result = 0;
return result; // no-warning; but this is an over suppression
return result; // expected-warning{{Null returned from a function that is expected to return a non-null value}}
}

int *InlinedReturnNullOverSuppressionCaller(int * _Nonnull p1) {
Expand Down
6 changes: 3 additions & 3 deletions clang/test/Analysis/stack-addr-ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@ void callTestRegister(void) {

void top_level_leaking(int **out) {
int local = 42;
*out = &local; // no-warning FIXME
*out = &local; // expected-warning{{Address of stack memory associated with local variable 'local' is still referred to by the caller variable 'out'}}
}

void callee_leaking_via_param(int **out) {
int local = 1;
*out = &local;
// expected-warning@-1{{Address of stack memory associated with local variable 'local' is still referred to by the stack variable 'ptr'}}
// expected-warning@-1{{Address of stack memory associated with local variable 'local' is still referred to by the caller variable 'ptr'}}
}

void caller_for_leaking_callee() {
Expand All @@ -115,7 +115,7 @@ void caller_for_leaking_callee() {
void callee_nested_leaking(int **out) {
int local = 1;
*out = &local;
// expected-warning@-1{{Address of stack memory associated with local variable 'local' is still referred to by the stack variable 'ptr'}}
// expected-warning@-1{{Address of stack memory associated with local variable 'local' is still referred to by the caller variable 'ptr'}}
}

void caller_mid_for_nested_leaking(int **mid) {
Expand Down
117 changes: 64 additions & 53 deletions clang/test/Analysis/stack-addr-ps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ void write_stack_address_to(char **q) {
char local;
*q = &local;
// expected-warning@-1 {{Address of stack memory associated with local \
variable 'local' is still referred to by the stack variable 'p' upon \
variable 'local' is still referred to by the caller variable 'p' upon \
returning to the caller}}
}

Expand Down Expand Up @@ -188,14 +188,14 @@ void* global_ptr;

void global_direct_pointer() {
int local = 42;
global_ptr = &local;
} // expected-warning{{local variable 'local' is still referred to by the global variable 'global_ptr'}}
global_ptr = &local; // expected-warning{{local variable 'local' is still referred to by the global variable 'global_ptr'}}
}

void static_direct_pointer_top() {
int local = 42;
static int* p = &local;
(void)p;
} // expected-warning{{local variable 'local' is still referred to by the static variable 'p'}}
(void)p; // expected-warning{{local variable 'local' is still referred to by the static variable 'p'}}
}

void static_direct_pointer_callee() {
int local = 42;
Expand All @@ -219,7 +219,7 @@ void lambda_to_context_direct_pointer() {
int *p = nullptr;
auto lambda = [&] {
int local = 42;
p = &local; // expected-warning{{local variable 'local' is still referred to by the stack variable 'p'}}
p = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'p'}}
};
lambda();
(void)p;
Expand All @@ -245,7 +245,7 @@ void lambda_to_context_direct_pointer_lifetime_extended() {
int *p = nullptr;
auto lambda = [&] {
int&& local = 42;
p = &local; // expected-warning{{'int' lifetime extended by local variable 'local' is still referred to by the stack variable 'p'}}
p = &local; // expected-warning{{'int' lifetime extended by local variable 'local' is still referred to by the caller variable 'p'}}
};
lambda();
(void)p;
Expand All @@ -254,7 +254,7 @@ void lambda_to_context_direct_pointer_lifetime_extended() {
template<typename Callback>
void lambda_param_capture_direct_pointer_callee(Callback& callee) {
int local = 42;
callee(local); // expected-warning{{'local' is still referred to by the stack variable 'p'}}
callee(local); // expected-warning{{'local' is still referred to by the caller variable 'p'}}
}

void lambda_param_capture_direct_pointer_caller() {
Expand All @@ -279,19 +279,19 @@ void** global_pp;
void global_ptr_local_to_ptr() {
int local = 42;
int* p = &local;
global_pp = (void**)&p;
} // expected-warning{{local variable 'p' is still referred to by the global variable 'global_pp'}}
global_pp = (void**)&p; // expected-warning{{local variable 'p' is still referred to by the global variable 'global_pp'}}
}

void global_ptr_to_ptr() {
int local = 42;
*global_pp = &local; // no-warning FIXME
*global_pp = &local; // expected-warning{{local variable 'local' is still referred to by the global variable 'global_pp'}}
}

void *** global_ppp;

void global_ptr_to_ptr_to_ptr() {
int local = 42;
**global_ppp = &local; // no-warning FIXME
**global_ppp = &local; // expected-warning{{local variable 'local' is still referred to by the global variable 'global_ppp'}}
}

void** get_some_pp();
Expand All @@ -304,12 +304,12 @@ void static_ptr_to_ptr() {

void param_ptr_to_ptr_top(void** pp) {
int local = 42;
*pp = &local; // no-warning FIXME
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'pp'}}
}

void param_ptr_to_ptr_callee(void** pp) {
int local = 42;
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the stack variable 'p'}}
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'p'}}
}

void param_ptr_to_ptr_caller() {
Expand All @@ -319,12 +319,12 @@ void param_ptr_to_ptr_caller() {

void param_ptr_to_ptr_to_ptr_top(void*** ppp) {
int local = 42;
**ppp = &local; // no-warning FIXME
**ppp = &local; // expected-warning {{local variable 'local' is still referred to by the caller variable 'ppp'}}
}

void param_ptr_to_ptr_to_ptr_callee(void*** ppp) {
int local = 42;
**ppp = &local; // expected-warning{{local variable 'local' is still referred to by the stack variable 'pp'}}
**ppp = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'pp'}}
}

void param_ptr_to_ptr_to_ptr_caller(void** pp) {
Expand All @@ -334,15 +334,15 @@ void param_ptr_to_ptr_to_ptr_caller(void** pp) {
void lambda_to_context_ptr_to_ptr(int **pp) {
auto lambda = [&] {
int local = 42;
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the stack variable 'pp'}}
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'pp'}}
};
lambda();
(void)*pp;
}

void param_ptr_to_ptr_fptr(int **pp) {
int local = 42;
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the stack variable 'p'}}
*pp = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'p'}}
}

void param_ptr_to_ptr_fptr_caller(void (*fptr)(int**)) {
Expand All @@ -363,7 +363,7 @@ void*& global_rtp = *make_ptr_to_ptr();
void global_ref_to_ptr() {
int local = 42;
int* p = &local;
global_rtp = p; // no-warning FIXME
global_rtp = p; // expected-warning{{local variable 'local' is still referred to by the global variable 'global_rtp'}}
}

void static_ref_to_ptr() {
Expand All @@ -376,13 +376,13 @@ void static_ref_to_ptr() {
void param_ref_to_ptr_top(void*& rp) {
int local = 42;
int* p = &local;
rp = p; // no-warning FIXME
rp = p; // expected-warning{{local variable 'local' is still referred to by the caller variable 'rp'}}
}

void param_ref_to_ptr_callee(void*& rp) {
int local = 42;
int* p = &local;
rp = p; // expected-warning{{local variable 'local' is still referred to by the stack variable 'p'}}
rp = p; // expected-warning{{local variable 'local' is still referred to by the caller variable 'p'}}
}

void param_ref_to_ptr_caller() {
Expand Down Expand Up @@ -418,26 +418,26 @@ void* global_aop[2];
void global_arr_of_ptr() {
int local = 42;
int* p = &local;
global_aop[1] = p;
} // expected-warning{{local variable 'local' is still referred to by the global variable 'global_aop'}}
global_aop[1] = p; // expected-warning{{local variable 'local' is still referred to by the global variable 'global_aop'}}
}

void static_arr_of_ptr() {
int local = 42;
static void* arr[2];
arr[1] = &local;
(void)arr[1];
} // expected-warning{{local variable 'local' is still referred to by the static variable 'arr'}}
(void)arr[1]; // expected-warning{{local variable 'local' is still referred to by the static variable 'arr'}}
}

void param_arr_of_ptr_top(void* arr[2]) {
int local = 42;
int* p = &local;
arr[1] = p; // no-warning FIXME
arr[1] = p; // expected-warning{{local variable 'local' is still referred to by the caller variable 'arr'}}
}

void param_arr_of_ptr_callee(void* arr[2]) {
int local = 42;
int* p = &local;
arr[1] = p; // expected-warning{{local variable 'local' is still referred to by the stack variable 'arrStack'}}
arr[1] = p; // expected-warning{{local variable 'local' is still referred to by the caller variable 'arrStack'}}
}

void param_arr_of_ptr_caller() {
Expand Down Expand Up @@ -474,26 +474,26 @@ void* global_aop[2];
void global_arr_of_ptr(int idx) {
int local = 42;
int* p = &local;
global_aop[idx] = p;
} // expected-warning{{local variable 'local' is still referred to by the global variable 'global_aop'}}
global_aop[idx] = p; // expected-warning{{local variable 'local' is still referred to by the global variable 'global_aop'}}
}

void static_arr_of_ptr(int idx) {
int local = 42;
static void* arr[2];
arr[idx] = &local;
(void)arr[idx];
} // expected-warning{{local variable 'local' is still referred to by the static variable 'arr'}}
(void)arr[idx]; // expected-warning{{local variable 'local' is still referred to by the static variable 'arr'}}
}

void param_arr_of_ptr_top(void* arr[2], int idx) {
int local = 42;
int* p = &local;
arr[idx] = p; // no-warning FIXME
arr[idx] = p; // expected-warning{{local variable 'local' is still referred to by the caller variable 'arr'}}
}

void param_arr_of_ptr_callee(void* arr[2], int idx) {
int local = 42;
int* p = &local;
arr[idx] = p; // expected-warning{{local variable 'local' is still referred to by the stack variable 'arrStack'}}
arr[idx] = p; // expected-warning{{local variable 'local' is still referred to by the caller variable 'arrStack'}}
}

void param_arr_of_ptr_caller(int idx) {
Expand All @@ -519,7 +519,7 @@ S returned_struct_with_ptr_callee() {
int local = 42;
S s;
s.p = &local;
return s; // expected-warning{{'local' is still referred to by the stack variable 's'}}
return s; // expected-warning{{'local' is still referred to by the caller variable 's'}}
}

void returned_struct_with_ptr_caller() {
Expand All @@ -531,15 +531,15 @@ S global_s;

void global_struct_with_ptr() {
int local = 42;
global_s.p = &local;
} // expected-warning{{'local' is still referred to by the global variable 'global_s'}}
global_s.p = &local; // expected-warning{{'local' is still referred to by the global variable 'global_s'}}
}

void static_struct_with_ptr() {
int local = 42;
static S s;
s.p = &local;
(void)s.p;
} // expected-warning{{'local' is still referred to by the static variable 's'}}
(void)s.p; // expected-warning{{'local' is still referred to by the static variable 's'}}
}
} // namespace leaking_via_struct_with_ptr

namespace leaking_via_ref_to_struct_with_ptr {
Expand All @@ -551,7 +551,7 @@ S &global_s = *(new S);

void global_ref_to_struct_with_ptr() {
int local = 42;
global_s.p = &local; // no-warning FIXME
global_s.p = &local; // expected-warning{{'local' is still referred to by the global variable 'global_s'}}
}

void static_ref_to_struct_with_ptr() {
Expand All @@ -563,12 +563,12 @@ void static_ref_to_struct_with_ptr() {

void param_ref_to_struct_with_ptr_top(S &s) {
int local = 42;
s.p = &local; // no-warning FIXME
s.p = &local; // expected-warning{{'local' is still referred to by the caller variable 's'}}
}

void param_ref_to_struct_with_ptr_callee(S &s) {
int local = 42;
s.p = &local; // expected-warning{{'local' is still referred to by the stack variable 'sStack'}}
s.p = &local; // expected-warning{{'local' is still referred to by the caller variable 'sStack'}}
}

void param_ref_to_struct_with_ptr_caller() {
Expand All @@ -579,7 +579,7 @@ void param_ref_to_struct_with_ptr_caller() {
template<typename Callable>
void lambda_param_capture_callee(Callable& callee) {
int local = 42;
callee(local); // expected-warning{{'local' is still referred to by the stack variable 'p'}}
callee(local); // expected-warning{{'local' is still referred to by the caller variable 'p'}}
}

void lambda_param_capture_caller() {
Expand Down Expand Up @@ -619,7 +619,7 @@ S* global_s;

void global_ptr_to_struct_with_ptr() {
int local = 42;
global_s->p = &local; // no-warning FIXME
global_s->p = &local; // expected-warning{{'local' is still referred to by the global variable 'global_s'}}
}

void static_ptr_to_struct_with_ptr_new() {
Expand All @@ -639,12 +639,12 @@ void static_ptr_to_struct_with_ptr_generated() {

void param_ptr_to_struct_with_ptr_top(S* s) {
int local = 42;
s->p = &local; // no-warning FIXME
s->p = &local; // expected-warning{{'local' is still referred to by the caller variable 's'}}
}

void param_ptr_to_struct_with_ptr_callee(S* s) {
int local = 42;
s->p = &local; // expected-warning{{'local' is still referred to by the stack variable 's'}}
s->p = &local; // expected-warning{{'local' is still referred to by the caller variable 's'}}
}

void param_ptr_to_struct_with_ptr_caller() {
Expand Down Expand Up @@ -682,8 +682,8 @@ S global_s[2];

void global_ptr_to_struct_with_ptr() {
int local = 42;
global_s[1].p = &local;
} // expected-warning{{'local' is still referred to by the global variable 'global_s'}}
global_s[1].p = &local; // expected-warning{{'local' is still referred to by the global variable 'global_s'}}
}

void static_ptr_to_struct_with_ptr_new() {
int local = 42;
Expand All @@ -702,12 +702,12 @@ void static_ptr_to_struct_with_ptr_generated() {

void param_ptr_to_struct_with_ptr_top(S s[2]) {
int local = 42;
s[1].p = &local; // no-warning FIXME
s[1].p = &local; // expected-warning{{'local' is still referred to by the caller variable 's'}}
}

void param_ptr_to_struct_with_ptr_callee(S s[2]) {
int local = 42;
s[1].p = &local; // expected-warning{{'local' is still referred to by the stack variable 's'}}
s[1].p = &local; // expected-warning{{'local' is still referred to by the caller variable 's'}}
}

void param_ptr_to_struct_with_ptr_caller() {
Expand All @@ -727,17 +727,17 @@ NestedAndTransitive global_nat;

void global_nested_and_transitive() {
int local = 42;
*global_nat.next[2]->next[1]->p = &local; // no-warning FIXME
*global_nat.next[2]->next[1]->p = &local; // expected-warning{{'local' is still referred to by the global variable 'global_nat'}}
}

void param_nested_and_transitive_top(NestedAndTransitive* nat) {
int local = 42;
*nat->next[2]->next[1]->p = &local; // no-warning FIXME
*nat->next[2]->next[1]->p = &local; // expected-warning{{'local' is still referred to by the caller variable 'nat'}}
}

void param_nested_and_transitive_callee(NestedAndTransitive* nat) {
int local = 42;
*nat->next[2]->next[1]->p = &local; // expected-warning{{local variable 'local' is still referred to by the stack variable 'natCaller'}}
*nat->next[2]->next[1]->p = &local; // expected-warning{{'local' is still referred to by the caller variable 'natCaller'}}
}

void param_nested_and_transitive_caller(NestedAndTransitive natCaller) {
Expand Down Expand Up @@ -769,7 +769,7 @@ void leaker(int ***leakerArg) {
// is no longer relevant.
// The message must refer to 'original_arg' instead, but there is no easy way to
// connect the SymRegion stored in 'original_arg' and 'original_arg' as variable.
**leakerArg = &local; // expected-warning{{ 'local' is still referred to by the stack variable 'arg'}}
**leakerArg = &local; // expected-warning{{ 'local' is still referred to by the caller variable 'arg'}}
}

int **tweak();
Expand All @@ -780,3 +780,14 @@ void foo(int **arg) {
leaker(&original_arg);
}
} // namespace origin_region_limitation

namespace leaking_via_indirect_global_invalidated {
void** global_pp;
void opaque();
void global_ptr_to_ptr() {
int local = 42;
*global_pp = &local;
opaque();
*global_pp = nullptr;
}
} // namespace leaking_via_indirect_global_invalidated
4 changes: 2 additions & 2 deletions clang/test/Analysis/stack-capture-leak-no-arc.mm
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ dispatch_block_t test_block_inside_block_async_leak() {
// called.
void output_block(dispatch_block_t * blk) {
int x = 0;
*blk = ^{ f(x); }; // expected-warning {{Address of stack-allocated block declared on line 43 is still referred to by the stack variable 'blk' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
*blk = ^{ f(x); }; // expected-warning {{Address of stack-allocated block declared on line 43 is still referred to by the caller variable 'blk' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
}

// The block literal captures nothing thus is treated as a constant.
Expand All @@ -54,7 +54,7 @@ void test_block_leak() {
__block dispatch_block_t blk;
int x = 0;
dispatch_block_t p = ^{
blk = ^{ // expected-warning {{Address of stack-allocated block declared on line 57 is still referred to by the stack variable 'blk' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
blk = ^{ // expected-warning {{Address of stack-allocated block declared on line 57 is still referred to by the caller variable 'blk' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
f(x);
};
};
Expand Down
8 changes: 4 additions & 4 deletions clang/test/Analysis/stackaddrleak.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ char const *p;
void f0(void) {
char const str[] = "This will change";
p = str;
} // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
} // expected-warning@-1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}

void f1(void) {
char const str[] = "This will change";
Expand All @@ -17,7 +17,7 @@ void f1(void) {

void f2(void) {
p = (const char *) __builtin_alloca(12);
} // expected-warning{{Address of stack memory allocated by call to alloca() on line 19 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
} // expected-warning@-1{{Address of stack memory allocated by call to alloca() on line 19 is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}

// PR 7383 - previously the stack address checker would crash on this example
// because it would attempt to do a direct load from 'pr7383_list'.
Expand All @@ -33,7 +33,7 @@ void test_multi_return(void) {
int x;
a = &x;
b = &x;
} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the static variable 'a' upon returning}} expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the static variable 'b' upon returning}}
} // expected-warning@-1{{Address of stack memory associated with local variable 'x' is still referred to by the static variable 'a' upon returning}} expected-warning@-1{{Address of stack memory associated with local variable 'x' is still referred to by the static variable 'b' upon returning}}

intptr_t returnAsNonLoc(void) {
int x;
Expand All @@ -49,7 +49,7 @@ void assignAsNonLoc(void) {
extern intptr_t ip;
int x;
ip = (intptr_t)&x;
} // expected-warning{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'ip' upon returning}}
} // expected-warning@-1{{Address of stack memory associated with local variable 'x' is still referred to by the global variable 'ip' upon returning}}

void assignAsBool(void) {
extern bool b;
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CXX/drs/cwg29xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// RUN: %clang_cc1 -std=c++23 -pedantic-errors -verify=expected %s
// RUN: %clang_cc1 -std=c++2c -pedantic-errors -verify=expected %s

namespace cwg2917 { // cwg2917: 20 open 2024-07-30
namespace cwg2917 { // cwg2917: 20 review 2024-07-30
template <typename>
class Foo;

Expand All @@ -33,7 +33,7 @@ void *operator new(std::size_t, void *p) { return p; }
void* operator new[] (std::size_t, void* p) {return p;}


namespace cwg2922 { // cwg2922: 20 open 2024-07-10
namespace cwg2922 { // cwg2922: 20 tentatively ready 2024-07-10
union U { int a, b; };
constexpr U nondeterministic(bool i) {
if(i) {
Expand Down
10 changes: 5 additions & 5 deletions clang/test/ClangScanDeps/pr61006.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang -print-resource-dir > %t/resource-dir.txt && \
// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \
// RUN: ln -s %clang++ %t/clang++ && \
// RUN: sed "s|EXPECTED_RESOURCE_DIR|%{readfile:%t/resource-dir.txt}|g; s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json && \
// RUN: env EXPECTED_RESOURCE_DIR=%{readfile:%t/resource-dir.txt} clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/a.cpp -DPREFIX=%/t && \
// RUN: env EXPECTED_RESOURCE_DIR=%{readfile:%t/resource-dir.txt} clang-scan-deps -format=p1689 \
// RUN: sed "s|EXPECTED_RESOURCE_DIR|$EXPECTED_RESOURCE_DIR|g; s|DIR|%/t|g" %t/P1689.json.in > %t/P1689.json && \
// RUN: clang-scan-deps -compilation-database %t/P1689.json -format=p1689 | FileCheck %t/a.cpp -DPREFIX=%/t && \
// RUN: clang-scan-deps -format=p1689 \
// RUN: -- %t/clang++ -std=c++20 -c -fprebuilt-module-path=%t %t/a.cpp -o %t/a.o \
// RUN: -resource-dir %{env:EXPECTED_RESOURCE_DIR} | FileCheck %t/a.cpp -DPREFIX=%/t
// RUN: -resource-dir $EXPECTED_RESOURCE_DIR | FileCheck %t/a.cpp -DPREFIX=%/t

//--- P1689.json.in
[
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeCompletion/variadic-template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ void f() {
// The important thing is that we provide OVERLOAD signature in all those cases.
//
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-5):7 %s -o - | FileCheck --check-prefix=CHECK-1 %s
// CHECK-1: OVERLOAD: [#void#]fun(<#T x#>, Args args...)
// CHECK-1: OVERLOAD: [#void#]fun(<#T x#>)
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-7):10 %s -o - | FileCheck --check-prefix=CHECK-2 %s
// CHECK-2: OVERLOAD: [#void#]fun(int x)
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-9):13 %s -o - | FileCheck --check-prefix=CHECK-3 %s
Expand Down
387 changes: 387 additions & 0 deletions clang/test/CodeGen/X86/x86-intrinsics-imm.c

Large diffs are not rendered by default.

16 changes: 15 additions & 1 deletion clang/test/CodeGen/builtins-nvptx.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// REQUIRES: nvptx-registered-target
// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_70 -target-feature +ptx63 \
// RUN: -fcuda-is-device -emit-llvm -o - -x cuda %s \
// RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PTX63_SM70 -check-prefix=LP64 %s
// RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu sm_80 -target-feature +ptx70 \
// RUN: -fcuda-is-device -emit-llvm -o - -x cuda %s \
// RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PTX70_SM80 -check-prefix=LP32 %s
Expand Down Expand Up @@ -238,7 +241,8 @@ __shared__ long long sll;

// Check for atomic intrinsics
// CHECK-LABEL: nvvm_atom
__device__ void nvvm_atom(float *fp, float f, double *dfp, double df, int *ip,
__device__ void nvvm_atom(float *fp, float f, double *dfp, double df,
unsigned short *usp, unsigned short us, int *ip,
int i, unsigned int *uip, unsigned ui, long *lp,
long l, long long *llp, long long ll) {
// CHECK: atomicrmw add ptr {{.*}} seq_cst, align 4
Expand Down Expand Up @@ -577,6 +581,16 @@ __device__ void nvvm_atom(float *fp, float f, double *dfp, double df, int *ip,
__nvvm_atom_sys_cas_gen_ll(&sll, ll, 0);
#endif

#if __CUDA_ARCH__ >= 700
// CHECK_PTX63_SM70: cmpxchg ptr {{.*}} seq_cst seq_cst, align 2
// CHECK_PTX63_SM70-NEXT: extractvalue { i16, i1 } {{%[0-9]+}}, 0
__nvvm_atom_cas_gen_us(usp, 0, us);
// CHECK_PTX63_SM70: call i16 @llvm.nvvm.atomic.cas.gen.i.cta.i16.p0
__nvvm_atom_cta_cas_gen_us(usp, 0, us);
// CHECK_PTX63_SM70: call i16 @llvm.nvvm.atomic.cas.gen.i.sys.i16.p0
__nvvm_atom_sys_cas_gen_us(usp, 0, us);
#endif

// CHECK: ret
}

Expand Down
5 changes: 5 additions & 0 deletions clang/test/CodeGen/ifunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=thread -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
// RUN: %clang_cc1 -triple arm64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
// RUN: %clang_cc1 -triple x86_64-apple-macosx -fsanitize=address -O2 -emit-llvm -o - %s | FileCheck %s --check-prefix=SAN
// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=AVR

/// The ifunc is emitted before its resolver.
int foo(int) __attribute__ ((ifunc("foo_ifunc")));
Expand Down Expand Up @@ -55,6 +56,10 @@ extern void hoo(int) __attribute__ ((ifunc("hoo_ifunc")));
// CHECK: @goo = ifunc void (), ptr @goo_ifunc
// CHECK: @hoo = ifunc void (i32), ptr @hoo_ifunc

// AVR: @foo = ifunc i16 (i16), ptr addrspace(1) @foo_ifunc
// AVR: @goo = ifunc void (), ptr addrspace(1) @goo_ifunc
// AVR: @hoo = ifunc void (i16), ptr addrspace(1) @hoo_ifunc

// CHECK: call i32 @foo(i32
// CHECK: call void @goo()

Expand Down
8 changes: 6 additions & 2 deletions clang/test/CodeGenCXX/always_destroy.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// RUN: %clang_cc1 %s -fno-c++-static-destructors -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | FileCheck %s
// RUN: %clang_cc1 %s -fc++-static-destructors=none -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | \
// RUN: FileCheck --check-prefixes=CHECK,NO-DTORS %s
// RUN: %clang_cc1 %s -fc++-static-destructors=thread-local -emit-llvm -triple x86_64-apple-macosx10.13.0 -o - | \
// RUN: FileCheck --check-prefixes=CHECK,THREAD-LOCAL-DTORS %s

struct NonTrivial {
~NonTrivial();
};

// CHECK-NOT: __cxa_atexit{{.*}}_ZN10NonTrivialD1Ev
NonTrivial nt1;
// CHECK-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
// NO-DTORS-NOT: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
// THREAD-LOCAL-DTORS: _tlv_atexit{{.*}}_ZN10NonTrivialD1Ev
thread_local NonTrivial nt2;

struct NonTrivial2 {
Expand Down
3 changes: 2 additions & 1 deletion clang/test/CodeGenCXX/attr-no-destroy-d54344.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR %s -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK-ATTR
// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR -fno-c++-static-destructors %s -o - | FileCheck %s --check-prefix=CHECK-FLAG
// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR -fc++-static-destructors=none %s -o - | FileCheck %s --check-prefix=CHECK-FLAG
// RUN: %clang_cc1 -std=c++2a -emit-llvm -O0 -triple x86_64-unknown-linux-gnu -DNOATTR -fc++-static-destructors=thread-local %s -o - | FileCheck %s --check-prefix=CHECK-FLAG

// Regression test for D54344. Class with no user-defined destructor
// that has an inherited member that has a non-trivial destructor
Expand Down
39 changes: 39 additions & 0 deletions clang/test/CodeGenCoroutines/coro-dwarf-O2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Check that we can still observe the value of the coroutine frame
// with optimizations.
//
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
// RUN: -emit-llvm %s -debug-info-kind=limited -dwarf-version=5 \
// RUN: -O2 -o - | FileCheck %s

#include "Inputs/coroutine.h"

template <>
struct std::coroutine_traits<void> {
struct promise_type {
void get_return_object();
std::suspend_always initial_suspend();
std::suspend_always final_suspend() noexcept;
void return_void();
void unhandled_exception();
};
};

struct ScalarAwaiter {
template <typename F> void await_suspend(F);
bool await_ready();
int await_resume();
};

extern "C" void UseScalar(int);

extern "C" void f() {
UseScalar(co_await ScalarAwaiter{});

int Val = co_await ScalarAwaiter{};

co_await ScalarAwaiter{};
}

// CHECK: define {{.*}}@f.resume({{.*}} %[[ARG:.*]])
// CHECK: #dbg_value(ptr %[[ARG]], ![[CORO_NUM:[0-9]+]], !DIExpression(DW_OP_deref)
// CHECK: ![[CORO_NUM]] = !DILocalVariable(name: "__coro_frame"
2 changes: 1 addition & 1 deletion clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ RWBuffer<float> Buf;
// CHECK: store ptr %[[HandleRes]], ptr %h, align 4

// CHECK-SPIRV: %[[HandleRes:[0-9]+]] = call ptr @llvm.spv.create.handle(i8 1)
// CHECK-SPIRV: store ptr %[[HandleRes]], ptr %h, align 8
// CHECK-SPIRV: store ptr %[[HandleRes]], ptr %h, align 8
268 changes: 92 additions & 176 deletions clang/test/CodeGenHLSL/builtins/all.hlsl

Large diffs are not rendered by default.

264 changes: 92 additions & 172 deletions clang/test/CodeGenHLSL/builtins/any.hlsl

Large diffs are not rendered by default.

84 changes: 32 additions & 52 deletions clang/test/CodeGenHLSL/builtins/frac.hlsl
Original file line number Diff line number Diff line change
@@ -1,84 +1,64 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,SPIR_CHECK,NATIVE_HALF,SPIR_NATIVE_HALF
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,SPIR_CHECK,NO_HALF,SPIR_NO_HALF
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv

// DXIL_NATIVE_HALF: define noundef half @
// SPIR_NATIVE_HALF: define spir_func noundef half @
// DXIL_NATIVE_HALF: %hlsl.frac = call half @llvm.dx.frac.f16(
// SPIR_NATIVE_HALF: %hlsl.frac = call half @llvm.spv.frac.f16(
// NATIVE_HALF: define [[FNATTRS]] half @
// NATIVE_HALF: %hlsl.frac = call half @llvm.[[TARGET]].frac.f16(
// NATIVE_HALF: ret half %hlsl.frac
// DXIL_NO_HALF: define noundef float @
// SPIR_NO_HALF: define spir_func noundef float @
// DXIL_NO_HALF: %hlsl.frac = call float @llvm.dx.frac.f32(
// SPIR_NO_HALF: %hlsl.frac = call float @llvm.spv.frac.f32(
// NO_HALF: define [[FNATTRS]] float @
// NO_HALF: %hlsl.frac = call float @llvm.[[TARGET]].frac.f32(
// NO_HALF: ret float %hlsl.frac
half test_frac_half(half p0) { return frac(p0); }
// DXIL_NATIVE_HALF: define noundef <2 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <2 x half> @
// DXIL_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.dx.frac.v2f16
// SPIR_NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.spv.frac.v2f16
// NATIVE_HALF: define [[FNATTRS]] <2 x half> @
// NATIVE_HALF: %hlsl.frac = call <2 x half> @llvm.[[TARGET]].frac.v2f16
// NATIVE_HALF: ret <2 x half> %hlsl.frac
// DXIL_NO_HALF: define noundef <2 x float> @
// SPIR_NO_HALF: define spir_func noundef <2 x float> @
// DXIL_NO_HALF: %hlsl.frac = call <2 x float> @llvm.dx.frac.v2f32(
// SPIR_NO_HALF: %hlsl.frac = call <2 x float> @llvm.spv.frac.v2f32(
// NO_HALF: define [[FNATTRS]] <2 x float> @
// NO_HALF: %hlsl.frac = call <2 x float> @llvm.[[TARGET]].frac.v2f32(
// NO_HALF: ret <2 x float> %hlsl.frac
half2 test_frac_half2(half2 p0) { return frac(p0); }
// DXIL_NATIVE_HALF: define noundef <3 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <3 x half> @
// DXIL_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.dx.frac.v3f16
// SPIR_NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.spv.frac.v3f16
// NATIVE_HALF: define [[FNATTRS]] <3 x half> @
// NATIVE_HALF: %hlsl.frac = call <3 x half> @llvm.[[TARGET]].frac.v3f16
// NATIVE_HALF: ret <3 x half> %hlsl.frac
// DXIL_NO_HALF: define noundef <3 x float> @
// SPIR_NO_HALF: define spir_func noundef <3 x float> @
// DXIL_NO_HALF: %hlsl.frac = call <3 x float> @llvm.dx.frac.v3f32(
// SPIR_NO_HALF: %hlsl.frac = call <3 x float> @llvm.spv.frac.v3f32(
// NO_HALF: define [[FNATTRS]] <3 x float> @
// NO_HALF: %hlsl.frac = call <3 x float> @llvm.[[TARGET]].frac.v3f32(
// NO_HALF: ret <3 x float> %hlsl.frac
half3 test_frac_half3(half3 p0) { return frac(p0); }
// DXIL_NATIVE_HALF: define noundef <4 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <4 x half> @
// DXIL_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.dx.frac.v4f16
// SPIR_NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.spv.frac.v4f16
// NATIVE_HALF: define [[FNATTRS]] <4 x half> @
// NATIVE_HALF: %hlsl.frac = call <4 x half> @llvm.[[TARGET]].frac.v4f16
// NATIVE_HALF: ret <4 x half> %hlsl.frac
// DXIL_NO_HALF: define noundef <4 x float> @
// SPIR_NO_HALF: define spir_func noundef <4 x float> @
// DXIL_NO_HALF: %hlsl.frac = call <4 x float> @llvm.dx.frac.v4f32(
// SPIR_NO_HALF: %hlsl.frac = call <4 x float> @llvm.spv.frac.v4f32(
// NO_HALF: define [[FNATTRS]] <4 x float> @
// NO_HALF: %hlsl.frac = call <4 x float> @llvm.[[TARGET]].frac.v4f32(
// NO_HALF: ret <4 x float> %hlsl.frac
half4 test_frac_half4(half4 p0) { return frac(p0); }

// DXIL_CHECK: define noundef float @
// SPIR_CHECK: define spir_func noundef float @
// DXIL_CHECK: %hlsl.frac = call float @llvm.dx.frac.f32(
// SPIR_CHECK: %hlsl.frac = call float @llvm.spv.frac.f32(
// CHECK: define [[FNATTRS]] float @
// CHECK: %hlsl.frac = call float @llvm.[[TARGET]].frac.f32(
// CHECK: ret float %hlsl.frac
float test_frac_float(float p0) { return frac(p0); }
// DXIL_CHECK: define noundef <2 x float> @
// SPIR_CHECK: define spir_func noundef <2 x float> @
// DXIL_CHECK: %hlsl.frac = call <2 x float> @llvm.dx.frac.v2f32
// SPIR_CHECK: %hlsl.frac = call <2 x float> @llvm.spv.frac.v2f32
// CHECK: define [[FNATTRS]] <2 x float> @
// CHECK: %hlsl.frac = call <2 x float> @llvm.[[TARGET]].frac.v2f32
// CHECK: ret <2 x float> %hlsl.frac
float2 test_frac_float2(float2 p0) { return frac(p0); }
// DXIL_CHECK: define noundef <3 x float> @
// SPIR_CHECK: define spir_func noundef <3 x float> @
// DXIL_CHECK: %hlsl.frac = call <3 x float> @llvm.dx.frac.v3f32
// SPIR_CHECK: %hlsl.frac = call <3 x float> @llvm.spv.frac.v3f32
// CHECK: define [[FNATTRS]] <3 x float> @
// CHECK: %hlsl.frac = call <3 x float> @llvm.[[TARGET]].frac.v3f32
// CHECK: ret <3 x float> %hlsl.frac
float3 test_frac_float3(float3 p0) { return frac(p0); }
// DXIL_CHECK: define noundef <4 x float> @
// SPIR_CHECK: define spir_func noundef <4 x float> @
// DXIL_CHECK: %hlsl.frac = call <4 x float> @llvm.dx.frac.v4f32
// SPIR_CHECK: %hlsl.frac = call <4 x float> @llvm.spv.frac.v4f32
// CHECK: define [[FNATTRS]] <4 x float> @
// CHECK: %hlsl.frac = call <4 x float> @llvm.[[TARGET]].frac.v4f32
// CHECK: ret <4 x float> %hlsl.frac
float4 test_frac_float4(float4 p0) { return frac(p0); }
58 changes: 23 additions & 35 deletions clang/test/CodeGenHLSL/builtins/lerp.hlsl
Original file line number Diff line number Diff line change
@@ -1,88 +1,76 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_NO_HALF,SPIR_CHECK
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv


// DXIL_NATIVE_HALF: %hlsl.lerp = call half @llvm.dx.lerp.f16(half %{{.*}}, half %{{.*}}, half %{{.*}})
// SPIR_NATIVE_HALF: %hlsl.lerp = call half @llvm.spv.lerp.f16(half %{{.*}}, half %{{.*}}, half %{{.*}})
// NATIVE_HALF: %hlsl.lerp = call half @llvm.[[TARGET]].lerp.f16(half %{{.*}}, half %{{.*}}, half %{{.*}})
// NATIVE_HALF: ret half %hlsl.lerp
// DXIL_NO_HALF: %hlsl.lerp = call float @llvm.dx.lerp.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
// SPIR_NO_HALF: %hlsl.lerp = call float @llvm.spv.lerp.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
// NO_HALF: %hlsl.lerp = call float @llvm.[[TARGET]].lerp.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
// NO_HALF: ret float %hlsl.lerp
half test_lerp_half(half p0) { return lerp(p0, p0, p0); }

// DXIL_NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.dx.lerp.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}, <2 x half> %{{.*}})
// SPIR_NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.spv.lerp.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}, <2 x half> %{{.*}})
// NATIVE_HALF: %hlsl.lerp = call <2 x half> @llvm.[[TARGET]].lerp.v2f16(<2 x half> %{{.*}}, <2 x half> %{{.*}}, <2 x half> %{{.*}})
// NATIVE_HALF: ret <2 x half> %hlsl.lerp
// DXIL_NO_HALF: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}})
// SPIR_NO_HALF: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}})
// NO_HALF: %hlsl.lerp = call <2 x float> @llvm.[[TARGET]].lerp.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}})
// NO_HALF: ret <2 x float> %hlsl.lerp
half2 test_lerp_half2(half2 p0) { return lerp(p0, p0, p0); }

// DXIL_NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.dx.lerp.v3f16(<3 x half> %{{.*}}, <3 x half> %{{.*}}, <3 x half> %{{.*}})
// SPIR_NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.spv.lerp.v3f16(<3 x half> %{{.*}}, <3 x half> %{{.*}}, <3 x half> %{{.*}})
// NATIVE_HALF: %hlsl.lerp = call <3 x half> @llvm.[[TARGET]].lerp.v3f16(<3 x half> %{{.*}}, <3 x half> %{{.*}}, <3 x half> %{{.*}})
// NATIVE_HALF: ret <3 x half> %hlsl.lerp
// DXIL_NO_HALF: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}})
// SPIR_NO_HALF: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}})
// NO_HALF: %hlsl.lerp = call <3 x float> @llvm.[[TARGET]].lerp.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}})
// NO_HALF: ret <3 x float> %hlsl.lerp
half3 test_lerp_half3(half3 p0) { return lerp(p0, p0, p0); }

// DXIL_NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.dx.lerp.v4f16(<4 x half> %{{.*}}, <4 x half> %{{.*}}, <4 x half> %{{.*}})
// SPIR_NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.spv.lerp.v4f16(<4 x half> %{{.*}}, <4 x half> %{{.*}}, <4 x half> %{{.*}})
// NATIVE_HALF: %hlsl.lerp = call <4 x half> @llvm.[[TARGET]].lerp.v4f16(<4 x half> %{{.*}}, <4 x half> %{{.*}}, <4 x half> %{{.*}})
// NATIVE_HALF: ret <4 x half> %hlsl.lerp
// DXIL_NO_HALF: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
// SPIR_NO_HALF: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
// NO_HALF: %hlsl.lerp = call <4 x float> @llvm.[[TARGET]].lerp.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
// NO_HALF: ret <4 x float> %hlsl.lerp
half4 test_lerp_half4(half4 p0) { return lerp(p0, p0, p0); }

// DXIL_CHECK: %hlsl.lerp = call float @llvm.dx.lerp.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
// SPIR_CHECK: %hlsl.lerp = call float @llvm.spv.lerp.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
// CHECK: %hlsl.lerp = call float @llvm.[[TARGET]].lerp.f32(float %{{.*}}, float %{{.*}}, float %{{.*}})
// CHECK: ret float %hlsl.lerp
float test_lerp_float(float p0) { return lerp(p0, p0, p0); }

// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}})
// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}})
// CHECK: %hlsl.lerp = call <2 x float> @llvm.[[TARGET]].lerp.v2f32(<2 x float> %{{.*}}, <2 x float> %{{.*}}, <2 x float> %{{.*}})
// CHECK: ret <2 x float> %hlsl.lerp
float2 test_lerp_float2(float2 p0) { return lerp(p0, p0, p0); }

// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}})
// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}})
// CHECK: %hlsl.lerp = call <3 x float> @llvm.[[TARGET]].lerp.v3f32(<3 x float> %{{.*}}, <3 x float> %{{.*}}, <3 x float> %{{.*}})
// CHECK: ret <3 x float> %hlsl.lerp
float3 test_lerp_float3(float3 p0) { return lerp(p0, p0, p0); }

// DXIL_CHECK: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
// SPIR_CHECK: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
// CHECK: %hlsl.lerp = call <4 x float> @llvm.[[TARGET]].lerp.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
// CHECK: ret <4 x float> %hlsl.lerp
float4 test_lerp_float4(float4 p0) { return lerp(p0, p0, p0); }

// CHECK: %[[b:.*]] = load <2 x float>, ptr %p1.addr, align 8
// CHECK: %[[c:.*]] = load <2 x float>, ptr %p1.addr, align 8
// DXIL_CHECK: %hlsl.lerp = call <2 x float> @llvm.dx.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %[[b]], <2 x float> %[[c]])
// SPIR_CHECK: %hlsl.lerp = call <2 x float> @llvm.spv.lerp.v2f32(<2 x float> %splat.splat, <2 x float> %[[b]], <2 x float> %[[c]])
// CHECK: %hlsl.lerp = call <2 x float> @llvm.[[TARGET]].lerp.v2f32(<2 x float> %splat.splat, <2 x float> %[[b]], <2 x float> %[[c]])
// CHECK: ret <2 x float> %hlsl.lerp
float2 test_lerp_float2_splat(float p0, float2 p1) { return lerp(p0, p1, p1); }

// CHECK: %[[b:.*]] = load <3 x float>, ptr %p1.addr, align 16
// CHECK: %[[c:.*]] = load <3 x float>, ptr %p1.addr, align 16
// DXIL_CHECK: %hlsl.lerp = call <3 x float> @llvm.dx.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %[[b]], <3 x float> %[[c]])
// SPIR_CHECK: %hlsl.lerp = call <3 x float> @llvm.spv.lerp.v3f32(<3 x float> %splat.splat, <3 x float> %[[b]], <3 x float> %[[c]])
// CHECK: %hlsl.lerp = call <3 x float> @llvm.[[TARGET]].lerp.v3f32(<3 x float> %splat.splat, <3 x float> %[[b]], <3 x float> %[[c]])
// CHECK: ret <3 x float> %hlsl.lerp
float3 test_lerp_float3_splat(float p0, float3 p1) { return lerp(p0, p1, p1); }

// CHECK: %[[b:.*]] = load <4 x float>, ptr %p1.addr, align 16
// CHECK: %[[c:.*]] = load <4 x float>, ptr %p1.addr, align 16
// DXIL_CHECK: %hlsl.lerp = call <4 x float> @llvm.dx.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %[[b]], <4 x float> %[[c]])
// SPIR_CHECK: %hlsl.lerp = call <4 x float> @llvm.spv.lerp.v4f32(<4 x float> %splat.splat, <4 x float> %[[b]], <4 x float> %[[c]])
// CHECK: %hlsl.lerp = call <4 x float> @llvm.[[TARGET]].lerp.v4f32(<4 x float> %splat.splat, <4 x float> %[[b]], <4 x float> %[[c]])
// CHECK: ret <4 x float> %hlsl.lerp
float4 test_lerp_float4_splat(float p0, float4 p1) { return lerp(p0, p1, p1); }
73 changes: 29 additions & 44 deletions clang/test/CodeGenHLSL/builtins/normalize.hlsl
Original file line number Diff line number Diff line change
@@ -1,98 +1,83 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,NATIVE_HALF,SPIR_NATIVE_HALF,SPIR_CHECK
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF,SPIR_NO_HALF,SPIR_CHECK
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv

// DXIL_NATIVE_HALF: define noundef half @
// SPIR_NATIVE_HALF: define spir_func noundef half @
// DXIL_NATIVE_HALF: call half @llvm.dx.normalize.f16(half
// SPIR_NATIVE_HALF: call half @llvm.spv.normalize.f16(half
// DXIL_NO_HALF: call float @llvm.dx.normalize.f32(float
// SPIR_NO_HALF: call float @llvm.spv.normalize.f32(float
// NATIVE_HALF: define [[FNATTRS]] half @
// NATIVE_HALF: call half @llvm.[[TARGET]].normalize.f16(half
// NO_HALF: call float @llvm.[[TARGET]].normalize.f32(float
// NATIVE_HALF: ret half
// NO_HALF: ret float
half test_normalize_half(half p0)
{
return normalize(p0);
}
// DXIL_NATIVE_HALF: define noundef <2 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <2 x half> @
// DXIL_NATIVE_HALF: call <2 x half> @llvm.dx.normalize.v2f16(<2 x half>
// SPIR_NATIVE_HALF: call <2 x half> @llvm.spv.normalize.v2f16(<2 x half>
// DXIL_NO_HALF: call <2 x float> @llvm.dx.normalize.v2f32(<2 x float>
// SPIR_NO_HALF: call <2 x float> @llvm.spv.normalize.v2f32(<2 x float>
// NATIVE_HALF: define [[FNATTRS]] <2 x half> @
// NATIVE_HALF: call <2 x half> @llvm.[[TARGET]].normalize.v2f16(<2 x half>
// NO_HALF: call <2 x float> @llvm.[[TARGET]].normalize.v2f32(<2 x float>
// NATIVE_HALF: ret <2 x half> %hlsl.normalize
// NO_HALF: ret <2 x float> %hlsl.normalize
half2 test_normalize_half2(half2 p0)
{
return normalize(p0);
}
// DXIL_NATIVE_HALF: define noundef <3 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <3 x half> @
// DXIL_NATIVE_HALF: call <3 x half> @llvm.dx.normalize.v3f16(<3 x half>
// SPIR_NATIVE_HALF: call <3 x half> @llvm.spv.normalize.v3f16(<3 x half>
// DXIL_NO_HALF: call <3 x float> @llvm.dx.normalize.v3f32(<3 x float>
// SPIR_NO_HALF: call <3 x float> @llvm.spv.normalize.v3f32(<3 x float>
// NATIVE_HALF: define [[FNATTRS]] <3 x half> @
// NATIVE_HALF: call <3 x half> @llvm.[[TARGET]].normalize.v3f16(<3 x half>
// NO_HALF: call <3 x float> @llvm.[[TARGET]].normalize.v3f32(<3 x float>
// NATIVE_HALF: ret <3 x half> %hlsl.normalize
// NO_HALF: ret <3 x float> %hlsl.normalize
half3 test_normalize_half3(half3 p0)
{
return normalize(p0);
}
// DXIL_NATIVE_HALF: define noundef <4 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <4 x half> @
// DXIL_NATIVE_HALF: call <4 x half> @llvm.dx.normalize.v4f16(<4 x half>
// SPIR_NATIVE_HALF: call <4 x half> @llvm.spv.normalize.v4f16(<4 x half>
// DXIL_NO_HALF: call <4 x float> @llvm.dx.normalize.v4f32(<4 x float>
// SPIR_NO_HALF: call <4 x float> @llvm.spv.normalize.v4f32(<4 x float>
// NATIVE_HALF: define [[FNATTRS]] <4 x half> @
// NATIVE_HALF: call <4 x half> @llvm.[[TARGET]].normalize.v4f16(<4 x half>
// NO_HALF: call <4 x float> @llvm.[[TARGET]].normalize.v4f32(<4 x float>
// NATIVE_HALF: ret <4 x half> %hlsl.normalize
// NO_HALF: ret <4 x float> %hlsl.normalize
half4 test_normalize_half4(half4 p0)
{
return normalize(p0);
}

// DXIL_CHECK: define noundef float @
// SPIR_CHECK: define spir_func noundef float @
// DXIL_CHECK: call float @llvm.dx.normalize.f32(float
// SPIR_CHECK: call float @llvm.spv.normalize.f32(float
// CHECK: define [[FNATTRS]] float @
// CHECK: call float @llvm.[[TARGET]].normalize.f32(float
// CHECK: ret float
float test_normalize_float(float p0)
{
return normalize(p0);
}
// DXIL_CHECK: define noundef <2 x float> @
// SPIR_CHECK: define spir_func noundef <2 x float> @
// DXIL_CHECK: %hlsl.normalize = call <2 x float> @llvm.dx.normalize.v2f32(
// SPIR_CHECK: %hlsl.normalize = call <2 x float> @llvm.spv.normalize.v2f32(<2 x float>
// CHECK: define [[FNATTRS]] <2 x float> @
// CHECK: %hlsl.normalize = call <2 x float> @llvm.[[TARGET]].normalize.v2f32(<2 x float>

// CHECK: ret <2 x float> %hlsl.normalize
float2 test_normalize_float2(float2 p0)
{
return normalize(p0);
}
// DXIL_CHECK: define noundef <3 x float> @
// SPIR_CHECK: define spir_func noundef <3 x float> @
// DXIL_CHECK: %hlsl.normalize = call <3 x float> @llvm.dx.normalize.v3f32(
// SPIR_CHECK: %hlsl.normalize = call <3 x float> @llvm.spv.normalize.v3f32(<3 x float>
// CHECK: define [[FNATTRS]] <3 x float> @
// CHECK: %hlsl.normalize = call <3 x float> @llvm.[[TARGET]].normalize.v3f32(
// CHECK: ret <3 x float> %hlsl.normalize
float3 test_normalize_float3(float3 p0)
{
return normalize(p0);
}
// DXIL_CHECK: define noundef <4 x float> @
// SPIR_CHECK: define spir_func noundef <4 x float> @
// DXIL_CHECK: %hlsl.normalize = call <4 x float> @llvm.dx.normalize.v4f32(
// SPIR_CHECK: %hlsl.normalize = call <4 x float> @llvm.spv.normalize.v4f32(
// CHECK: define [[FNATTRS]] <4 x float> @
// CHECK: %hlsl.normalize = call <4 x float> @llvm.[[TARGET]].normalize.v4f32(
// CHECK: ret <4 x float> %hlsl.normalize
float4 test_length_float4(float4 p0)
{
Expand Down
84 changes: 32 additions & 52 deletions clang/test/CodeGenHLSL/builtins/rsqrt.hlsl
Original file line number Diff line number Diff line change
@@ -1,84 +1,64 @@
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,DXIL_CHECK,DXIL_NATIVE_HALF,NATIVE_HALF
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,DXIL_CHECK,NO_HALF,DXIL_NO_HALF
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS=noundef -DTARGET=dx
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -fnative-half-type \
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
// RUN: --check-prefixes=CHECK,SPIR_CHECK,NATIVE_HALF,SPIR_NATIVE_HALF
// RUN: --check-prefixes=CHECK,NATIVE_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv
// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
// RUN: spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,SPIR_CHECK,NO_HALF,SPIR_NO_HALF
// RUN: -o - | FileCheck %s --check-prefixes=CHECK,NO_HALF \
// RUN: -DFNATTRS="spir_func noundef" -DTARGET=spv

// DXIL_NATIVE_HALF: define noundef half @
// SPIR_NATIVE_HALF: define spir_func noundef half @
// DXIL_NATIVE_HALF: %hlsl.rsqrt = call half @llvm.dx.rsqrt.f16(
// SPIR_NATIVE_HALF: %hlsl.rsqrt = call half @llvm.spv.rsqrt.f16(
// NATIVE_HALF: define [[FNATTRS]] half @
// NATIVE_HALF: %hlsl.rsqrt = call half @llvm.[[TARGET]].rsqrt.f16(
// NATIVE_HALF: ret half %hlsl.rsqrt
// DXIL_NO_HALF: define noundef float @
// SPIR_NO_HALF: define spir_func noundef float @
// DXIL_NO_HALF: %hlsl.rsqrt = call float @llvm.dx.rsqrt.f32(
// SPIR_NO_HALF: %hlsl.rsqrt = call float @llvm.spv.rsqrt.f32(
// NO_HALF: define [[FNATTRS]] float @
// NO_HALF: %hlsl.rsqrt = call float @llvm.[[TARGET]].rsqrt.f32(
// NO_HALF: ret float %hlsl.rsqrt
half test_rsqrt_half(half p0) { return rsqrt(p0); }
// DXIL_NATIVE_HALF: define noundef <2 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <2 x half> @
// DXIL_NATIVE_HALF: %hlsl.rsqrt = call <2 x half> @llvm.dx.rsqrt.v2f16
// SPIR_NATIVE_HALF: %hlsl.rsqrt = call <2 x half> @llvm.spv.rsqrt.v2f16
// NATIVE_HALF: define [[FNATTRS]] <2 x half> @
// NATIVE_HALF: %hlsl.rsqrt = call <2 x half> @llvm.[[TARGET]].rsqrt.v2f16
// NATIVE_HALF: ret <2 x half> %hlsl.rsqrt
// DXIL_NO_HALF: define noundef <2 x float> @
// SPIR_NO_HALF: define spir_func noundef <2 x float> @
// DXIL_NO_HALF: %hlsl.rsqrt = call <2 x float> @llvm.dx.rsqrt.v2f32(
// SPIR_NO_HALF: %hlsl.rsqrt = call <2 x float> @llvm.spv.rsqrt.v2f32(
// NO_HALF: define [[FNATTRS]] <2 x float> @
// NO_HALF: %hlsl.rsqrt = call <2 x float> @llvm.[[TARGET]].rsqrt.v2f32(
// NO_HALF: ret <2 x float> %hlsl.rsqrt
half2 test_rsqrt_half2(half2 p0) { return rsqrt(p0); }
// DXIL_NATIVE_HALF: define noundef <3 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <3 x half> @
// DXIL_NATIVE_HALF: %hlsl.rsqrt = call <3 x half> @llvm.dx.rsqrt.v3f16
// SPIR_NATIVE_HALF: %hlsl.rsqrt = call <3 x half> @llvm.spv.rsqrt.v3f16
// NATIVE_HALF: define [[FNATTRS]] <3 x half> @
// NATIVE_HALF: %hlsl.rsqrt = call <3 x half> @llvm.[[TARGET]].rsqrt.v3f16
// NATIVE_HALF: ret <3 x half> %hlsl.rsqrt
// DXIL_NO_HALF: define noundef <3 x float> @
// SPIR_NO_HALF: define spir_func noundef <3 x float> @
// DXIL_NO_HALF: %hlsl.rsqrt = call <3 x float> @llvm.dx.rsqrt.v3f32(
// SPIR_NO_HALF: %hlsl.rsqrt = call <3 x float> @llvm.spv.rsqrt.v3f32(
// NO_HALF: define [[FNATTRS]] <3 x float> @
// NO_HALF: %hlsl.rsqrt = call <3 x float> @llvm.[[TARGET]].rsqrt.v3f32(
// NO_HALF: ret <3 x float> %hlsl.rsqrt
half3 test_rsqrt_half3(half3 p0) { return rsqrt(p0); }
// DXIL_NATIVE_HALF: define noundef <4 x half> @
// SPIR_NATIVE_HALF: define spir_func noundef <4 x half> @
// DXIL_NATIVE_HALF: %hlsl.rsqrt = call <4 x half> @llvm.dx.rsqrt.v4f16
// SPIR_NATIVE_HALF: %hlsl.rsqrt = call <4 x half> @llvm.spv.rsqrt.v4f16
// NATIVE_HALF: define [[FNATTRS]] <4 x half> @
// NATIVE_HALF: %hlsl.rsqrt = call <4 x half> @llvm.[[TARGET]].rsqrt.v4f16
// NATIVE_HALF: ret <4 x half> %hlsl.rsqrt
// DXIL_NO_HALF: define noundef <4 x float> @
// SPIR_NO_HALF: define spir_func noundef <4 x float> @
// DXIL_NO_HALF: %hlsl.rsqrt = call <4 x float> @llvm.dx.rsqrt.v4f32(
// SPIR_NO_HALF: %hlsl.rsqrt = call <4 x float> @llvm.spv.rsqrt.v4f32(
// NO_HALF: define [[FNATTRS]] <4 x float> @
// NO_HALF: %hlsl.rsqrt = call <4 x float> @llvm.[[TARGET]].rsqrt.v4f32(
// NO_HALF: ret <4 x float> %hlsl.rsqrt
half4 test_rsqrt_half4(half4 p0) { return rsqrt(p0); }

// DXIL_CHECK: define noundef float @
// SPIR_CHECK: define spir_func noundef float @
// DXIL_CHECK: %hlsl.rsqrt = call float @llvm.dx.rsqrt.f32(
// SPIR_CHECK: %hlsl.rsqrt = call float @llvm.spv.rsqrt.f32(
// CHECK: define [[FNATTRS]] float @
// CHECK: %hlsl.rsqrt = call float @llvm.[[TARGET]].rsqrt.f32(
// CHECK: ret float %hlsl.rsqrt
float test_rsqrt_float(float p0) { return rsqrt(p0); }
// DXIL_CHECK: define noundef <2 x float> @
// SPIR_CHECK: define spir_func noundef <2 x float> @
// DXIL_CHECK: %hlsl.rsqrt = call <2 x float> @llvm.dx.rsqrt.v2f32
// SPIR_CHECK: %hlsl.rsqrt = call <2 x float> @llvm.spv.rsqrt.v2f32
// CHECK: define [[FNATTRS]] <2 x float> @
// CHECK: %hlsl.rsqrt = call <2 x float> @llvm.[[TARGET]].rsqrt.v2f32
// CHECK: ret <2 x float> %hlsl.rsqrt
float2 test_rsqrt_float2(float2 p0) { return rsqrt(p0); }
// DXIL_CHECK: define noundef <3 x float> @
// SPIR_CHECK: define spir_func noundef <3 x float> @
// DXIL_CHECK: %hlsl.rsqrt = call <3 x float> @llvm.dx.rsqrt.v3f32
// SPIR_CHECK: %hlsl.rsqrt = call <3 x float> @llvm.spv.rsqrt.v3f32
// CHECK: define [[FNATTRS]] <3 x float> @
// CHECK: %hlsl.rsqrt = call <3 x float> @llvm.[[TARGET]].rsqrt.v3f32
// CHECK: ret <3 x float> %hlsl.rsqrt
float3 test_rsqrt_float3(float3 p0) { return rsqrt(p0); }
// DXIL_CHECK: define noundef <4 x float> @
// SPIR_CHECK: define spir_func noundef <4 x float> @
// DXIL_CHECK: %hlsl.rsqrt = call <4 x float> @llvm.dx.rsqrt.v4f32
// SPIR_CHECK: %hlsl.rsqrt = call <4 x float> @llvm.spv.rsqrt.v4f32
// CHECK: define [[FNATTRS]] <4 x float> @
// CHECK: %hlsl.rsqrt = call <4 x float> @llvm.[[TARGET]].rsqrt.v4f32
// CHECK: ret <4 x float> %hlsl.rsqrt
float4 test_rsqrt_float4(float4 p0) { return rsqrt(p0); }
14 changes: 6 additions & 8 deletions clang/test/CodeGenHLSL/semantics/DispatchThreadID.hlsl
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv

// Make sure SV_DispatchThreadID translated into dx.thread.id.

// CHECK: define void @foo()
// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.dx.thread.id(i32 0)
// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.spv.thread.id(i32 0)
// CHECK-DXIL: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
// CHECK-SPIRV: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
// CHECK: call void @{{.*}}foo{{.*}}(i32 %[[#ID]])
[shader("compute")]
[numthreads(8,8,1)]
void foo(uint Idx : SV_DispatchThreadID) {}

// CHECK: define void @bar()
// CHECK-DXIL: %[[#ID_X:]] = call i32 @llvm.dx.thread.id(i32 0)
// CHECK-SPIRV: %[[#ID_X:]] = call i32 @llvm.spv.thread.id(i32 0)
// CHECK: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id(i32 0)
// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0
// CHECK-DXIL: %[[#ID_Y:]] = call i32 @llvm.dx.thread.id(i32 1)
// CHECK-SPIRV: %[[#ID_Y:]] = call i32 @llvm.spv.thread.id(i32 1)
// CHECK: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id(i32 1)
// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1
// CHECK-DXIL: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]])
[shader("compute")]
Expand Down
37 changes: 37 additions & 0 deletions clang/test/CodeGenHLSL/static-local-ctor.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -o - -disable-llvm-passes %s | FileCheck %s

// Verify that no per variable _Init_thread instructions are emitted for non-trivial static locals
// These would normally be emitted by the MicrosoftCXXABI, but the DirectX backend should exlude them
// Instead, check for the guardvar oparations that should protect the constructor initialization should
// only take place once.

RWBuffer<int> buf[10];

void InitBuf(RWBuffer<int> buf) {
for (unsigned int i = 0; i < 100; i++)
buf[i] = 0;
}

// CHECK-NOT: _Init_thread_epoch
// CHECK: define internal void @"?main@@YAXXZ"
// CHECK-NEXT: entry:
// CHECK-NEXT: [[Tmp1:%.*]] = alloca %"class.hlsl::RWBuffer"
// CHECK-NEXT: [[Tmp2:%.*]] = load i32, ptr
// CHECK-NEXT: [[Tmp3:%.*]] = and i32 [[Tmp2]], 1
// CHECK-NEXT: [[Tmp4:%.*]] = icmp eq i32 [[Tmp3]], 0
// CHECK-NEXT: br i1 [[Tmp4]]
// CHECK-NOT: _Init_thread_header
// CHECK: init:
// CHECK-NEXT: = or i32 [[Tmp2]], 1
// CHECK-NOT: _Init_thread_footer


[shader("compute")]
[numthreads(1,1,1)]
void main() {
// A non-trivially constructed static local will get checks to verify that it is generated just once
static RWBuffer<int> mybuf;
mybuf = buf[0];
InitBuf(mybuf);
}

4 changes: 2 additions & 2 deletions clang/test/Driver/coverage.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// GCNO-LOCATION-REL: "-coverage-notes-file={{.*}}{{/|\\\\}}foo/bar.gcno"

/// GCC allows PWD to change the paths.
// RUN: %if system-linux %{ env PWD=/proc/self/cwd %clang -### -c --coverage %s -o foo/bar.o 2>&1 | FileCheck --check-prefix=PWD %s %}
// RUN: %if system-linux %{ PWD=/proc/self/cwd %clang -### -c --coverage %s -o foo/bar.o 2>&1 | FileCheck --check-prefix=PWD %s %}
// PWD: "-coverage-notes-file=/proc/self/cwd/foo/bar.gcno" "-coverage-data-file=/proc/self/cwd/foo/bar.gcda"

/// Don't warn -Wunused-command-line-argument.
Expand Down Expand Up @@ -50,6 +50,6 @@
// LINK2: -cc1{{.*}} "-coverage-notes-file={{.*}}{{/|\\\\}}f/gb.gcno" "-coverage-data-file={{.*}}{{/|\\\\}}f/gb.gcda"

/// GCC allows PWD to change the paths.
// RUN: %if system-linux %{ env PWD=/proc/self/cwd %clang -### --coverage d/a.c d/b.c -o e/x -fprofile-dir=f 2>&1 | FileCheck %s --check-prefix=LINK3 %}
// RUN: %if system-linux %{ PWD=/proc/self/cwd %clang -### --coverage d/a.c d/b.c -o e/x -fprofile-dir=f 2>&1 | FileCheck %s --check-prefix=LINK3 %}
// LINK3: -cc1{{.*}} "-coverage-notes-file=/proc/self/cwd/e/x-a.gcno" "-coverage-data-file=f/proc/self/cwd/e/x-a.gcda"
// LINK3: -cc1{{.*}} "-coverage-notes-file=/proc/self/cwd/e/x-b.gcno" "-coverage-data-file=f/proc/self/cwd/e/x-b.gcda"
11 changes: 11 additions & 0 deletions clang/test/Driver/cxx-static-destructors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clang -### -c -fc++-static-destructors=all %s 2>&1 | FileCheck --check-prefix ALL %s
// RUN: %clang -### -c -fc++-static-destructors %s 2>&1 | FileCheck --check-prefix ALL %s
// RUN: %clang -### -c -fno-c++-static-destructors -fc++-static-destructors %s 2>&1 | FileCheck --check-prefix ALL %s
// RUN: %clang -### -c -fc++-static-destructors=none %s 2>&1 | FileCheck --check-prefix NONE %s
// RUN: %clang -### -c -fno-c++-static-destructors %s 2>&1 | FileCheck --check-prefix NONE %s
// RUN: %clang -### -c -fc++-static-destructors -fno-c++-static-destructors %s 2>&1 | FileCheck --check-prefix NONE %s
// RUN: %clang -### -c -fc++-static-destructors=thread-local %s 2>&1 | FileCheck --check-prefix THREAD-LOCAL %s

// ALL: -fc++-static-destructors=all
// NONE: -fc++-static-destructors=none
// THREAD-LOCAL: -fc++-static-destructors=thread-local
99 changes: 50 additions & 49 deletions clang/test/Driver/offload-packager.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,64 @@
// REQUIRES: amdgpu-registered-target
// UNSUPPORTED: system-windows

// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.elf.o
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t/elf.o

// Check that we can extract files from the packaged binary.
// RUN: clang-offload-packager -o %t.out \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_80 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90c
// RUN: clang-offload-packager %t.out \
// RUN: --image=file=%t-sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t-gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
// RUN: diff %t-sm_70.o %t.elf.o
// RUN: diff %t-gfx908.o %t.elf.o
// RUN: clang-offload-packager -o %t/package.out \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_80 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90c
// RUN: clang-offload-packager %t/package.out \
// RUN: --image=file=%t/sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t/gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
// RUN: diff %t/sm_70.o %t/elf.o
// RUN: diff %t/gfx908.o %t/elf.o

// Check that we generate a new name if one is not given
// RUN: clang-offload-packager -o %t \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_80 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
// RUN: --image=file=%t.elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx90c
// RUN: cd $(dirname "%t") && clang-offload-packager %t --image=kind=openmp
// RUN: diff *-nvptx64-nvidia-cuda-sm_70.0.o %t.elf.o; rm *-nvptx64-nvidia-cuda-sm_70.0.o
// RUN: diff *-nvptx64-nvidia-cuda-sm_80.1.o %t.elf.o; rm *-nvptx64-nvidia-cuda-sm_80.1.o
// RUN: diff *-amdgcn-amd-amdhsa-gfx908.2.o %t.elf.o; rm *-amdgcn-amd-amdhsa-gfx908.2.o
// RUN: diff *-amdgcn-amd-amdhsa-gfx90a.3.o %t.elf.o; rm *-amdgcn-amd-amdhsa-gfx90a.3.o
// RUN: not diff *-amdgcn-amd-amdhsa-gfx90c.4.o %t.elf.o
// RUN: clang-offload-packager -o %t/package \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_80 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx90a \
// RUN: --image=file=%t/elf.o,kind=hip,triple=amdgcn-amd-amdhsa,arch=gfx90c
// RUN: clang-offload-packager %t/package --image=kind=openmp
// RUN: diff *-nvptx64-nvidia-cuda-sm_70.0.o %t/elf.o; rm *-nvptx64-nvidia-cuda-sm_70.0.o
// RUN: diff *-nvptx64-nvidia-cuda-sm_80.1.o %t/elf.o; rm *-nvptx64-nvidia-cuda-sm_80.1.o
// RUN: diff *-amdgcn-amd-amdhsa-gfx908.2.o %t/elf.o; rm *-amdgcn-amd-amdhsa-gfx908.2.o
// RUN: diff *-amdgcn-amd-amdhsa-gfx90a.3.o %t/elf.o; rm *-amdgcn-amd-amdhsa-gfx90a.3.o
// RUN: not diff *-amdgcn-amd-amdhsa-gfx90c.4.o %t/elf.o

// Check that we can extract from an ELF object file
// RUN: clang-offload-packager -o %t.out \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
// RUN: clang-offload-packager %t.out \
// RUN: --image=file=%t-sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t-gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
// RUN: diff %t-sm_70.o %t.elf.o
// RUN: diff %t-gfx908.o %t.elf.o
// RUN: clang-offload-packager -o %t/package.out \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t/package.o -fembed-offload-object=%t/package.out
// RUN: clang-offload-packager %t/package.out \
// RUN: --image=file=%t/sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t/gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
// RUN: diff %t/sm_70.o %t/elf.o
// RUN: diff %t/gfx908.o %t/elf.o

// Check that we can extract from a bitcode file
// RUN: clang-offload-packager -o %t.out \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -o %t.bc -fembed-offload-object=%t.out
// RUN: clang-offload-packager %t.out \
// RUN: --image=file=%t-sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t-gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
// RUN: diff %t-sm_70.o %t.elf.o
// RUN: diff %t-gfx908.o %t.elf.o
// RUN: clang-offload-packager -o %t/package.out \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -o %t/package.bc -fembed-offload-object=%t/package.out
// RUN: clang-offload-packager %t/package.out \
// RUN: --image=file=%t/sm_70.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70 \
// RUN: --image=file=%t/gfx908.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
// RUN: diff %t/sm_70.o %t/elf.o
// RUN: diff %t/gfx908.o %t/elf.o

// Check that we can extract from an archive file to an archive file.
// RUN: clang-offload-packager -o %t.out \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
// RUN: llvm-ar rcs %t.a %t.o
// RUN: clang-offload-packager %t.a --archive --image=file=%t-gfx908.a,arch=gfx908
// RUN: llvm-ar t %t-gfx908.a 2>&1 | FileCheck %s
// RUN: clang-offload-packager -o %t/package.out \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
// RUN: --image=file=%t/elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t/package.o -fembed-offload-object=%t/package.out
// RUN: llvm-ar rcs %t/package.a %t/package.o
// RUN: clang-offload-packager %t/package.a --archive --image=file=%t/gfx908.a,arch=gfx908
// RUN: llvm-ar t %t/gfx908.a 2>&1 | FileCheck %s
// CHECK: {{.*}}.o
4 changes: 2 additions & 2 deletions clang/test/Driver/program-path-priority.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@

/// <default-triple>-gcc has lowest priority so <triple>-gcc
/// on PATH beats default triple in program path
// RUN: %t/clang --version | grep "Target:" | cut -d ' ' -f2 > %t/default-triple.txt
// RUN: env DEFAULT_TRIPLE=%{readfile:%t/default-triple.txt} touch %t/%{env:DEFAULT_TRIPLE}-gcc && chmod +x %t/%{env:DEFAULT_TRIPLE}-gcc
// RUN: DEFAULT_TRIPLE=`%t/clang --version | grep "Target:" | cut -d ' ' -f2`
// RUN: touch %t/$DEFAULT_TRIPLE-gcc && chmod +x %t/$DEFAULT_TRIPLE-gcc
// RUN: touch %t/%target_triple-gcc && chmod +x %t/%target_triple-gcc
// RUN: env "PATH=%t/env/" %t/clang -### -target notreal-none-elf %s 2>&1 | \
// RUN: FileCheck --check-prefix=DEFAULT_TRIPLE_GCC %s
Expand Down
8 changes: 4 additions & 4 deletions clang/test/ExtractAPI/bool.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// RUN: split-file %s %t
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
// RUN: %t/reference.output.json.in >> %t/reference.output.json
// RUN: %clang -extract-api --pretty-sgf -target arm64-apple-macosx \
// RUN: %t/input.h -o %t/output.json
// RUN: %clang_cc1 -extract-api --product-name=BoolTest --pretty-sgf -triple arm64-apple-macosx \
// RUN: %t/input.h -o %t/output.json

// Generator version is not consistent across test runs, normalize it.
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
Expand All @@ -15,7 +15,7 @@
bool Foo;

bool IsFoo(bool Bar);
/// expected-no-diagnostics
// expected-no-diagnostics

//--- reference.output.json.in
{
Expand All @@ -28,7 +28,7 @@ bool IsFoo(bool Bar);
"generator": "?"
},
"module": {
"name": "",
"name": "BoolTest",
"platform": {
"architecture": "arm64",
"operatingSystem": {
Expand Down
211 changes: 4 additions & 207 deletions clang/test/ExtractAPI/emit-symbol-graph/multi_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
#ifndef TEST_H
#define TEST_H

#define testmarcro1 32
#define testmacro2 42

int testfunc (int param1, int param2);
void testfunc2 ();
#endif /* TEST_H */
Expand Down Expand Up @@ -185,7 +182,7 @@ int main ()
"location": {
"position": {
"character": 4,
"line": 6
"line": 3
},
"uri": "file://INPUT_DIR/test.h"
},
Expand Down Expand Up @@ -249,7 +246,7 @@ int main ()
"location": {
"position": {
"character": 5,
"line": 7
"line": 4
},
"uri": "file://INPUT_DIR/test.h"
},
Expand Down Expand Up @@ -335,106 +332,6 @@ int main ()
"pathComponents": [
"main"
]
},
{
"accessLevel": "public",
"declarationFragments": [
{
"kind": "keyword",
"spelling": "#define"
},
{
"kind": "text",
"spelling": " "
},
{
"kind": "identifier",
"spelling": "testmarcro1"
}
],
"identifier": {
"interfaceLanguage": "c",
"precise": "c:test.h@39@macro@testmarcro1"
},
"kind": {
"displayName": "Macro",
"identifier": "c.macro"
},
"location": {
"position": {
"character": 8,
"line": 3
},
"uri": "file://INPUT_DIR/test.h"
},
"names": {
"navigator": [
{
"kind": "identifier",
"spelling": "testmarcro1"
}
],
"subHeading": [
{
"kind": "identifier",
"spelling": "testmarcro1"
}
],
"title": "testmarcro1"
},
"pathComponents": [
"testmarcro1"
]
},
{
"accessLevel": "public",
"declarationFragments": [
{
"kind": "keyword",
"spelling": "#define"
},
{
"kind": "text",
"spelling": " "
},
{
"kind": "identifier",
"spelling": "testmacro2"
}
],
"identifier": {
"interfaceLanguage": "c",
"precise": "c:test.h@62@macro@testmacro2"
},
"kind": {
"displayName": "Macro",
"identifier": "c.macro"
},
"location": {
"position": {
"character": 8,
"line": 4
},
"uri": "file://INPUT_DIR/test.h"
},
"names": {
"navigator": [
{
"kind": "identifier",
"spelling": "testmacro2"
}
],
"subHeading": [
{
"kind": "identifier",
"spelling": "testmacro2"
}
],
"title": "testmacro2"
},
"pathComponents": [
"testmacro2"
]
}
]
}
Expand Down Expand Up @@ -573,7 +470,7 @@ int main ()
"location": {
"position": {
"character": 4,
"line": 6
"line": 3
},
"uri": "file://INPUT_DIR/test.h"
},
Expand Down Expand Up @@ -637,7 +534,7 @@ int main ()
"location": {
"position": {
"character": 5,
"line": 7
"line": 4
},
"uri": "file://INPUT_DIR/test.h"
},
Expand All @@ -659,106 +556,6 @@ int main ()
"pathComponents": [
"testfunc2"
]
},
{
"accessLevel": "public",
"declarationFragments": [
{
"kind": "keyword",
"spelling": "#define"
},
{
"kind": "text",
"spelling": " "
},
{
"kind": "identifier",
"spelling": "testmarcro1"
}
],
"identifier": {
"interfaceLanguage": "c",
"precise": "c:test.h@39@macro@testmarcro1"
},
"kind": {
"displayName": "Macro",
"identifier": "c.macro"
},
"location": {
"position": {
"character": 8,
"line": 3
},
"uri": "file://INPUT_DIR/test.h"
},
"names": {
"navigator": [
{
"kind": "identifier",
"spelling": "testmarcro1"
}
],
"subHeading": [
{
"kind": "identifier",
"spelling": "testmarcro1"
}
],
"title": "testmarcro1"
},
"pathComponents": [
"testmarcro1"
]
},
{
"accessLevel": "public",
"declarationFragments": [
{
"kind": "keyword",
"spelling": "#define"
},
{
"kind": "text",
"spelling": " "
},
{
"kind": "identifier",
"spelling": "testmacro2"
}
],
"identifier": {
"interfaceLanguage": "c",
"precise": "c:test.h@62@macro@testmacro2"
},
"kind": {
"displayName": "Macro",
"identifier": "c.macro"
},
"location": {
"position": {
"character": 8,
"line": 4
},
"uri": "file://INPUT_DIR/test.h"
},
"names": {
"navigator": [
{
"kind": "identifier",
"spelling": "testmacro2"
}
],
"subHeading": [
{
"kind": "identifier",
"spelling": "testmacro2"
}
],
"title": "testmacro2"
},
"pathComponents": [
"testmacro2"
]
}
]
}
105 changes: 1 addition & 104 deletions clang/test/ExtractAPI/emit-symbol-graph/single_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
// CHECK-NOT: warning:

//--- main.c
#define TESTMACRO1 2
#define TESTMARCRO2 5

int main ()
{
return 0;
Expand Down Expand Up @@ -87,7 +84,7 @@ int main ()
"location": {
"position": {
"character": 4,
"line": 3
"line": 0
},
"uri": "file://INPUT_DIR/main.c"
},
Expand All @@ -109,106 +106,6 @@ int main ()
"pathComponents": [
"main"
]
},
{
"accessLevel": "public",
"declarationFragments": [
{
"kind": "keyword",
"spelling": "#define"
},
{
"kind": "text",
"spelling": " "
},
{
"kind": "identifier",
"spelling": "TESTMACRO1"
}
],
"identifier": {
"interfaceLanguage": "c",
"precise": "c:main.c@8@macro@TESTMACRO1"
},
"kind": {
"displayName": "Macro",
"identifier": "c.macro"
},
"location": {
"position": {
"character": 8,
"line": 0
},
"uri": "file://INPUT_DIR/main.c"
},
"names": {
"navigator": [
{
"kind": "identifier",
"spelling": "TESTMACRO1"
}
],
"subHeading": [
{
"kind": "identifier",
"spelling": "TESTMACRO1"
}
],
"title": "TESTMACRO1"
},
"pathComponents": [
"TESTMACRO1"
]
},
{
"accessLevel": "public",
"declarationFragments": [
{
"kind": "keyword",
"spelling": "#define"
},
{
"kind": "text",
"spelling": " "
},
{
"kind": "identifier",
"spelling": "TESTMARCRO2"
}
],
"identifier": {
"interfaceLanguage": "c",
"precise": "c:main.c@29@macro@TESTMARCRO2"
},
"kind": {
"displayName": "Macro",
"identifier": "c.macro"
},
"location": {
"position": {
"character": 8,
"line": 1
},
"uri": "file://INPUT_DIR/main.c"
},
"names": {
"navigator": [
{
"kind": "identifier",
"spelling": "TESTMARCRO2"
}
],
"subHeading": [
{
"kind": "identifier",
"spelling": "TESTMARCRO2"
}
],
"title": "TESTMARCRO2"
},
"pathComponents": [
"TESTMARCRO2"
]
}
]
}
Loading