mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 09:36:06 +00:00

The AST/conditionally-trivial-smfs tests look a bit questionable, but are consistent with GCC's POD-ness, at least as far as packing is concerned: https://godbolt.org/z/36nqPMbKM (questionable because it looks like the type would be non-copyable, so how could it be pod? But the calling convention/pass by value seems to work correctly (local testing verifies that this behavior is preserved even with this patch: https://godbolt.org/z/3Pa89zsv6 )) Differential Revision: https://reviews.llvm.org/D119051
347 lines
14 KiB
C++
347 lines
14 KiB
C++
// RUN: %clang_cc1 -std=c++20 -triple x86_64-pc-linux -ast-dump=json %s | FileCheck %s --check-prefixes=CHECK,LIN
|
|
// RUN: %clang_cc1 -std=c++20 -triple x86_64-pc-win32 -ast-dump=json %s | FileCheck %s
|
|
|
|
// This test validates that we compute correct AST properties of classes with
|
|
// conditionally trivial special member functions.
|
|
|
|
template <int N>
|
|
struct DefaultConstructorCheck {
|
|
DefaultConstructorCheck() requires(N == 1) = default;
|
|
DefaultConstructorCheck() requires(N == 2) = delete;
|
|
DefaultConstructorCheck() requires(N == 3);
|
|
DefaultConstructorCheck();
|
|
};
|
|
|
|
|
|
template struct DefaultConstructorCheck<1>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "defaultCtor": {
|
|
// CHECK-NEXT: "defaultedIsConstexpr": true,
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "isConstexpr": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userProvided": true
|
|
// CHECK-NEXT: },
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isLiteral": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTrivial": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
|
|
template struct DefaultConstructorCheck<2>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "defaultCtor": {
|
|
// CHECK-NEXT: "defaultedIsConstexpr": true,
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "isConstexpr": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userProvided": true
|
|
// CHECK-NEXT: },
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isLiteral": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTrivial": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
|
|
|
|
template struct DefaultConstructorCheck<3>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "defaultCtor": {
|
|
// CHECK-NEXT: "defaultedIsConstexpr": true,
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "isConstexpr": true,
|
|
// CHECK-NEXT: "nonTrivial": true,
|
|
// CHECK-NEXT: "userProvided": true
|
|
// CHECK-NEXT: },
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isLiteral": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
|
|
template <int N>
|
|
struct CopyConstructorCheck {
|
|
CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 1) = default;
|
|
CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 2) = delete;
|
|
CopyConstructorCheck(const CopyConstructorCheck&) requires(N == 3);
|
|
CopyConstructorCheck(const CopyConstructorCheck&);
|
|
};
|
|
|
|
|
|
template struct CopyConstructorCheck<1>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "copyCtor": {
|
|
// CHECK-NEXT: "hasConstParam": true,
|
|
// CHECK-NEXT: "implicitHasConstParam": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: },
|
|
|
|
// CHECK: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
// CHECK-NEXT: "moveAssign": {},
|
|
|
|
template struct CopyConstructorCheck<2>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "copyCtor": {
|
|
// CHECK-NEXT: "hasConstParam": true,
|
|
// CHECK-NEXT: "implicitHasConstParam": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: },
|
|
|
|
// CHECK: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
// CHECK-NEXT: "moveAssign": {},
|
|
|
|
template struct CopyConstructorCheck<3>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "copyCtor": {
|
|
// CHECK-NEXT: "hasConstParam": true,
|
|
// CHECK-NEXT: "implicitHasConstParam": true,
|
|
// CHECK-NEXT: "nonTrivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: },
|
|
|
|
// CHECK: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "moveAssign": {},
|
|
|
|
template <int N>
|
|
struct MoveConstructorCheck {
|
|
MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 1) = default;
|
|
MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 2) = delete;
|
|
MoveConstructorCheck(MoveConstructorCheck&&) requires(N == 3);
|
|
MoveConstructorCheck(MoveConstructorCheck&&);
|
|
};
|
|
|
|
|
|
template struct MoveConstructorCheck<1>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// LIN-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
// CHECK-NEXT: "moveAssign": {},
|
|
// CHECK-NEXT: "moveCtor": {
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: }
|
|
|
|
template struct MoveConstructorCheck<2>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
// CHECK-NEXT: "moveAssign": {},
|
|
// CHECK-NEXT: "moveCtor": {
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: }
|
|
|
|
template struct MoveConstructorCheck<3>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "hasUserDeclaredConstructor": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "moveAssign": {},
|
|
// CHECK-NEXT: "moveCtor": {
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "nonTrivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: }
|
|
|
|
template <int N>
|
|
struct CopyAssignmentCheck {
|
|
CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 1) = default;
|
|
CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 2) = delete;
|
|
CopyAssignmentCheck& operator=(const CopyAssignmentCheck&) requires(N == 3);
|
|
CopyAssignmentCheck& operator=(const CopyAssignmentCheck&);
|
|
};
|
|
|
|
|
|
template struct CopyAssignmentCheck<1>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT "copyAssign": {
|
|
// CHECK-NEXT "hasConstParam": true,
|
|
// CHECK-NEXT "implicitHasConstParam": true,
|
|
// CHECK-NEXT "trivial": true,
|
|
// CHECK-NEXT "userDeclared": true
|
|
// CHECK-NEXT },
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT "isAggregate": true,
|
|
// CHECK-NEXT "isEmpty": true,
|
|
// CHECK-NEXT "isLiteral": true,
|
|
// CHECK-NEXT "isStandardLayout": true,
|
|
// CHECK-NEXT "isTrivial": true,
|
|
// CHECK-NEXT "isTriviallyCopyable": true,
|
|
// CHECK-NEXT "moveAssign": {},
|
|
|
|
template struct CopyAssignmentCheck<2>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT "copyAssign": {
|
|
// CHECK-NEXT "hasConstParam": true,
|
|
// CHECK-NEXT "implicitHasConstParam": true,
|
|
// CHECK-NEXT "trivial": true,
|
|
// CHECK-NEXT "userDeclared": true
|
|
// CHECK-NEXT },
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT "isAggregate": true,
|
|
// CHECK-NEXT "isEmpty": true,
|
|
// CHECK-NEXT "isLiteral": true,
|
|
// CHECK-NEXT "isStandardLayout": true,
|
|
// CHECK-NEXT "isTrivial": true,
|
|
// CHECK-NEXT "isTriviallyCopyable": true,
|
|
// CHECK-NEXT "moveAssign": {},
|
|
|
|
template struct CopyAssignmentCheck<3>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "canPassInRegisters": true,
|
|
// CHECK-NEXT "copyAssign": {
|
|
// CHECK-NEXT "hasConstParam": true,
|
|
// CHECK-NEXT "implicitHasConstParam": true,
|
|
// CHECK-NEXT "trivial": true,
|
|
// CHECK-NEXT "userDeclared": true
|
|
// CHECK-NEXT },
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT "isAggregate": true,
|
|
// CHECK-NEXT "isEmpty": true,
|
|
// CHECK-NEXT "isLiteral": true,
|
|
// CHECK-NEXT "isStandardLayout": true,
|
|
// CHECK-NEXT "moveAssign": {},
|
|
|
|
template <int N>
|
|
struct MoveAssignmentCheck {
|
|
MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 1) = default;
|
|
MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 2) = delete;
|
|
MoveAssignmentCheck& operator=(MoveAssignmentCheck&&) requires(N == 3);
|
|
MoveAssignmentCheck& operator=(MoveAssignmentCheck&&);
|
|
};
|
|
|
|
|
|
template struct MoveAssignmentCheck<1>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT: "isAggregate": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isLiteral": true,
|
|
// CHECK-NEXT: "isPOD": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTrivial": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
// CHECK-NEXT: "moveAssign": {
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: },
|
|
|
|
template struct MoveAssignmentCheck<2>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT: "isAggregate": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isLiteral": true,
|
|
// CHECK-NEXT: "isPOD": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "isTrivial": true,
|
|
// CHECK-NEXT: "isTriviallyCopyable": true,
|
|
// CHECK-NEXT: "moveAssign": {
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "trivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: },
|
|
|
|
template struct MoveAssignmentCheck<3>;
|
|
// CHECK: "kind": "ClassTemplateSpecializationDecl",
|
|
// CHECK: "definitionData": {
|
|
// CHECK-NEXT: "canConstDefaultInit": true,
|
|
// CHECK-NEXT: "copyAssign": {
|
|
|
|
// CHECK: "hasConstexprNonCopyMoveConstructor": true,
|
|
// CHECK-NEXT: "isAggregate": true,
|
|
// CHECK-NEXT: "isEmpty": true,
|
|
// CHECK-NEXT: "isLiteral": true,
|
|
// CHECK-NEXT: "isPOD": true,
|
|
// CHECK-NEXT: "isStandardLayout": true,
|
|
// CHECK-NEXT: "moveAssign": {
|
|
// CHECK-NEXT: "exists": true,
|
|
// CHECK-NEXT: "nonTrivial": true,
|
|
// CHECK-NEXT: "userDeclared": true
|
|
// CHECK-NEXT: },
|