Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more tests for diagnostic messages #113

Open
wants to merge 9 commits into
base: p2996
Choose a base branch
from
90 changes: 90 additions & 0 deletions libcxx/test/std/experimental/reflection/names.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//===----------------------------------------------------------------------===//
//
// Copyright 2024 Bloomberg Finance L.P.
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
// ADDITIONAL_COMPILE_FLAGS: -freflection
// ADDITIONAL_COMPILE_FLAGS: -freflection-new-syntax
// ADDITIONAL_COMPILE_FLAGS: -fparameter-reflection
// ADDITIONAL_COMPILE_FLAGS: -Wno-unneeded-internal-declaration -Wno-unused-variable -Wno-unused-value

// <experimental/reflection>
//
// [reflection]

#include <experimental/meta>

struct A {
constexpr A([[maybe_unused]] int _a) {}

constexpr ~A() {}

consteval A operator+(int num) const { return A(num); }

template <typename T>
consteval static void foo() {}

operator int() const { return 42; }

template <typename T>
operator double() const {
return 42.0f;
}

template <typename T>
void operator()([[maybe_unused]] T lhs, [[maybe_unused]] T rhs) {}
};

int main() {
// ======================
// identifier_of
// ======================
int var;
identifier_of(^^var); // ok

identifier_of(^^int);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note-re@-2 {{reflected {{.*}} is anonymous and has no associated identifier}}

identifier_of(^^A::foo<int>);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{names of template specializations are not identifiers}}

/* TODO: clarify if test with constructor should fail or not
identifier_of(^^A::A);
// {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// {{names of constructors are not identifiers}}
*/

identifier_of(^^A::~A);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{names of destructors are not identifiers}}

identifier_of(^^A::operator+);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{names of operators are not identifiers}}

identifier_of(^^A::operator int);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{names of conversion functions are not identifiers}}

// todo: come up with test for constructor template

identifier_of(^^A::operator());
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{names of operator templates are not identifiers}}

identifier_of(^^A::operator double);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{names of conversion function templates are not identifiers}}

identifier_of(^^::);
// expected-error@-1 {{call to consteval function 'std::meta::identifier_of' is not a constant expression}}
// expected-note@-2 {{the global namespace has no associated identifier}}
}
63 changes: 61 additions & 2 deletions libcxx/test/std/experimental/reflection/reflect-invoke.verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// [reflection]

#include <experimental/meta>
#include <type_traits>

namespace NS {
struct A {
Expand All @@ -32,9 +33,67 @@ struct A {
};
};

struct B {};
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
consteval T foo(T arg) {
return arg + 1;
}

int bar() {
return 42;
}

struct B {
public:
constexpr B(const int _a) : a(_a) {}

private:
[[maybe_unused]] const int a;
};

constexpr B createB(int a) {
return B(a);
}

template <typename T>
struct C {
T data;
};

int main() {
// ======================
// common validation
// ======================
reflect_invoke(^^foo, {^^int}, {std::meta::reflect_value(42)}); // ok

reflect_invoke(^^bar, {});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note@-2 {{invocation is not a constant expression}}

reflect_invoke(^^foo, {^^NS}, {std::meta::reflect_value(42)});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{a reflection of {{.*}} cannot represent a template argument}}

reflect_invoke(^^foo, {^^int}, {^^NS});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{a reflection of {{.*}} cannot represent a function argument}}

reflect_invoke(^^NS, {});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{cannot invoke {{.*}}}}

auto data = C<int>{3};
reflect_invoke(^^C, {});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{cannot invoke {{.*}}}}

reflect_invoke(^^foo, {^^data});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{no specialization of the function template {{.*}} matched the provided arguments}}

reflect_invoke(^^createB, {std::meta::reflect_value(42)});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{invocation evaluates to a value of non-structural type {{.*}}, which cannot be represented as a reflection}}

// ======================
// non-static member functions
// ======================
Expand All @@ -53,7 +112,7 @@ int main() {
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note@-2 {{expected related object reflection as a first argument for invoking non-static member function}}

constexpr B differentClass{};
constexpr B differentClass{42};
reflect_invoke(^^A::fn, {^^differentClass});
// expected-error-re@-1 {{call to consteval function 'std::meta::reflect_invoke<{{.*}}>' is not a constant expression}}
// expected-note@-2 {{method is not a member of given object reflection}}
Expand Down
113 changes: 113 additions & 0 deletions libcxx/test/std/experimental/reflection/related-reflections.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//===----------------------------------------------------------------------===//
//
// Copyright 2024 Bloomberg Finance L.P.
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
// ADDITIONAL_COMPILE_FLAGS: -freflection -freflection-new-syntax
// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-variable -Wno-unused-value

// <experimental/reflection>
//
// [reflection]

#include <experimental/meta>
#include <utility>

template <typename T>
class A {};

int foo() {
return 42;
}

struct B {
constexpr B() {}

constexpr ~B() {}

struct InnerCls {};
};

int main() {
// ==============
// operator_of
// ==============
std::meta::operator_of(^^int);
// expected-error@-1 {{call to consteval function 'std::meta::operator_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} is not an operator or operator template}}

// ==============
// type_of
// ==============
constexpr int a = 3;
std::meta::type_of(^^a); // ok

std::meta::type_of(^^int);
// expected-error@-1 {{call to consteval function 'std::meta::type_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} has no type}}

std::meta::type_of(^^::);
// expected-error@-1 {{call to consteval function 'std::meta::type_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} has no type}}

std::meta::type_of(^^A<int>);
// expected-error@-1 {{call to consteval function 'std::meta::type_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} has no type}}

const auto [x, y] = std::pair{1, 2};
std::meta::type_of(^^x);
// expected-error@-1 {{call to consteval function 'std::meta::type_of' is not a constant expression}}
// expected-note-re@-2 {{cannot query the type of {{.*}}}}

std::meta::type_of(^^B::~B);
// expected-error@-1 {{call to consteval function 'std::meta::type_of' is not a constant expression}}
// expected-note-re@-2 {{cannot query the type of {{.*}}}}

// ==============
// parent_of
// ==============
parent_of(^^B::InnerCls); // ok

std::meta::parent_of(^^::);
// expected-error@-1 {{call to consteval function 'std::meta::parent_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} has no parent}}

std::meta::parent_of(std::meta::reflect_value(42));
// expected-error@-1 {{call to consteval function 'std::meta::parent_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} has no parent}}

constexpr int b = 1;
std::meta::parent_of(object_of(^^b));
// expected-error@-1 {{call to consteval function 'std::meta::parent_of' is not a constant expression}}
// expected-note-re@-2 {{{{.*}} has no parent}}

std::meta::parent_of(^^int);
// expected-error@-1 {{call to consteval function 'std::meta::parent_of' is not a constant expression}}

// ==============
// template_of
// ==============
template_of(^^A<int>); // ok

template_of(^^B);
// expected-error@-1 {{call to consteval function 'std::meta::template_of' is not a constant expression}}
// expected-note@-2 {{expected a reflection of a template specialization}}

template_of(^^foo);
// expected-error@-1 {{call to consteval function 'std::meta::template_of' is not a constant expression}}
// expected-note@-2 {{expected a reflection of a template specialization}}

template_of(^^int);
// expected-error@-1 {{call to consteval function 'std::meta::template_of' is not a constant expression}}
// expected-note@-2 {{expected a reflection of a template specialization}}

template_of(^^::);
// expected-error@-1 {{call to consteval function 'std::meta::template_of' is not a constant expression}}
// expected-note@-2 {{expected a reflection of a template specialization}}
}
37 changes: 37 additions & 0 deletions libcxx/test/std/experimental/reflection/substitute.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===----------------------------------------------------------------------===//
//
// Copyright 2024 Bloomberg Finance L.P.
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03 || c++11 || c++14 || c++17 || c++20
// ADDITIONAL_COMPILE_FLAGS: -freflection -freflection-new-syntax
// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-variable -Wno-unused-value

// <experimental/reflection>
//
// [reflection]

#include <experimental/meta>
#include <vector>

int main() {
can_substitute(^^std::vector, {^^int}); //ok
substitute(^^std::vector, {^^int}); //ok

can_substitute(^^int, {^^int});
// expected-error-re@-1 {{call to consteval function 'std::meta::can_substitute<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{expected a reflection of a template, but got {{.*}}}}

substitute(^^int, {^^int});
// expected-error-re@-1 {{call to consteval function 'std::meta::substitute<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{expected a reflection of a template, but got {{.*}}}}

substitute(^^std::vector, {^^::});
// expected-error-re@-1 {{call to consteval function 'std::meta::substitute<{{.*}}>' is not a constant expression}}
// expected-note-re@-2 {{a reflection of {{.*}} cannot represent a template argument}}
}
Loading
Loading