Skip to content

Commit c88d7a2

Browse files
committed
address more feedback
1 parent 2ea9af4 commit c88d7a2

File tree

6 files changed

+69
-24
lines changed

6 files changed

+69
-24
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,11 +1828,11 @@ The following type trait primitives are supported by Clang. Those traits marked
18281828
source object on the floor. This is true of trivial types and types which
18291829
were made trivially relocatable via the ``clang::trivial_abi`` attribute.
18301830
* ``__builtin_is_cpp_trivially_relocatable`` (C++): Returns true if an object
1831-
is trivially relocatable, as defined by the C++26 standard.
1831+
is trivially relocatable, as defined by the C++26 standard [meta.unary.prop].
18321832
Note that the caller code should ensure that if the object is polymorphic,
18331833
the dynamic type is of the most derived type.
18341834
* ``__builtin_is_replaceable`` (C++): Returns true if an object
1835-
is replaceable, as defined by the C++26 standard.
1835+
is replaceable, as defined by the C++26 standard [meta.unary.prop].
18361836
* ``__is_trivially_equality_comparable`` (Clang): Returns true if comparing two
18371837
objects of the provided type is known to be equivalent to comparing their
18381838
object representations. Note that types containing padding bytes are never

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ def ext_ms_abstract_keyword : ExtWarn<
10581058
InGroup<MicrosoftAbstract>;
10591059

10601060
def ext_relocatable_keyword : ExtWarn<
1061-
"'%select{trivially_relocatable|replaceable}0_if_eligible' "
1061+
"'%select{trivially_relocatable_if_eligible|replaceable_if_eligible}0' "
10621062
"keyword is a C++2c extension">,
10631063
InGroup<CXX26>;
10641064
def warn_relocatable_keyword : Warning<

clang/include/clang/Parse/Parser.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3174,12 +3174,12 @@ class Parser : public CodeCompletionHandler {
31743174

31753175
bool isCXX2CTriviallyRelocatableKeyword(Token Tok) const;
31763176
bool isCXX2CTriviallyRelocatableKeyword() const;
3177-
void ParseOptionalCXX2CTriviallyRelocatableSpecifier(
3178-
TriviallyRelocatableSpecifier &TRS);
3177+
void
3178+
ParseCXX2CTriviallyRelocatableSpecifier(TriviallyRelocatableSpecifier &TRS);
31793179

31803180
bool isCXX2CReplaceableKeyword(Token Tok) const;
31813181
bool isCXX2CReplaceableKeyword() const;
3182-
void ParseOptionalCXX2CReplaceableSpecifier(ReplaceableSpecifier &MRS);
3182+
void ParseCXX2CReplaceableSpecifier(ReplaceableSpecifier &MRS);
31833183

31843184
bool isClassCompatibleKeyword(Token Tok) const;
31853185
bool isClassCompatibleKeyword() const;

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2707,7 +2707,7 @@ bool Parser::isCXX2CTriviallyRelocatableKeyword() const {
27072707
return isCXX2CTriviallyRelocatableKeyword(Tok);
27082708
}
27092709

2710-
void Parser::ParseOptionalCXX2CTriviallyRelocatableSpecifier(
2710+
void Parser::ParseCXX2CTriviallyRelocatableSpecifier(
27112711
TriviallyRelocatableSpecifier &TRS) {
27122712
assert(isCXX2CTriviallyRelocatableKeyword() &&
27132713
"expected a trivially_relocatable specifier");
@@ -2734,7 +2734,7 @@ bool Parser::isCXX2CReplaceableKeyword() const {
27342734
return isCXX2CReplaceableKeyword(Tok);
27352735
}
27362736

2737-
void Parser::ParseOptionalCXX2CReplaceableSpecifier(ReplaceableSpecifier &MRS) {
2737+
void Parser::ParseCXX2CReplaceableSpecifier(ReplaceableSpecifier &MRS) {
27382738
assert(isCXX2CReplaceableKeyword() &&
27392739
"expected a replaceable_if_eligible specifier");
27402740

@@ -3881,20 +3881,20 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
38813881
auto Skipped = Tok;
38823882
ConsumeToken();
38833883
Diag(Skipped, diag::err_duplicate_class_relocation_specifier)
3884-
<< 0 << TriviallyRelocatable.getLocation();
3884+
<< /*trivial_relocatable*/ 0
3885+
<< TriviallyRelocatable.getLocation();
38853886
} else {
3886-
ParseOptionalCXX2CTriviallyRelocatableSpecifier(
3887-
TriviallyRelocatable);
3887+
ParseCXX2CTriviallyRelocatableSpecifier(TriviallyRelocatable);
38883888
}
38893889
continue;
38903890
} else if (isCXX2CReplaceableKeyword(Tok)) {
38913891
if (Replacable.isSet()) {
38923892
auto Skipped = Tok;
38933893
ConsumeToken();
38943894
Diag(Skipped, diag::err_duplicate_class_relocation_specifier)
3895-
<< 1 << Replacable.getLocation();
3895+
<< /*replaceable*/ 1 << Replacable.getLocation();
38963896
} else {
3897-
ParseOptionalCXX2CReplaceableSpecifier(Replacable);
3897+
ParseCXX2CReplaceableSpecifier(Replacable);
38983898
}
38993899
continue;
39003900
} else {

clang/lib/Sema/SemaChecking.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,8 @@ static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall) {
18961896
return ExprError();
18971897

18981898
if (T.isConstQualified() ||
1899-
!T.isCppTriviallyRelocatableType(S.getASTContext())) {
1899+
!T.isCppTriviallyRelocatableType(S.getASTContext()) ||
1900+
T->isIncompleteArrayType()) {
19001901
S.Diag(TheCall->getArg(0)->getExprLoc(),
19011902
diag::err_builtin_trivially_relocate_invalid_arg_type)
19021903
<< (T.isConstQualified() ? /*non-const*/ 1 : /*relocatable*/ 2);

clang/test/SemaCXX/cxx2c-trivially-relocatable.cpp

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,79 @@
11
// RUN: %clang_cc1 -std=c++2c -verify %s
22

33
class Trivial {};
4+
static_assert(__builtin_is_cpp_trivially_relocatable(Trivial));
45
struct NonRelocatable {
56
~NonRelocatable();
67
};
78
static NonRelocatable NonRelocatable_g;
89

910
class A trivially_relocatable_if_eligible {};
11+
static_assert(__builtin_is_cpp_trivially_relocatable(A));
12+
13+
1014
class B trivially_relocatable_if_eligible : Trivial{};
15+
static_assert(__builtin_is_cpp_trivially_relocatable(B));
16+
1117
class C trivially_relocatable_if_eligible {
1218
int a;
1319
void* b;
1420
int c[3];
1521
Trivial d[3];
1622
NonRelocatable& e = NonRelocatable_g;
1723
};
24+
static_assert(__builtin_is_cpp_trivially_relocatable(C));
25+
26+
1827
class D trivially_relocatable_if_eligible : Trivial {};
28+
static_assert(__builtin_is_cpp_trivially_relocatable(D));
29+
30+
1931
class E trivially_relocatable_if_eligible : virtual Trivial {};
32+
static_assert(!__builtin_is_cpp_trivially_relocatable(E));
33+
2034

2135
class F trivially_relocatable_if_eligible : NonRelocatable {};
36+
static_assert(!__builtin_is_cpp_trivially_relocatable(F));
37+
38+
class G trivially_relocatable_if_eligible {
39+
G(G&&);
40+
};
41+
static_assert(__builtin_is_cpp_trivially_relocatable(G));
42+
43+
class H trivially_relocatable_if_eligible {
44+
~H();
45+
};
46+
static_assert(__builtin_is_cpp_trivially_relocatable(H));
2247

2348
class I trivially_relocatable_if_eligible {
2449
NonRelocatable a;
2550
NonRelocatable b[1];
2651
const NonRelocatable c;
2752
const NonRelocatable d[1];
2853
};
54+
static_assert(!__builtin_is_cpp_trivially_relocatable(I));
55+
2956

3057
class J trivially_relocatable_if_eligible: virtual Trivial, NonRelocatable {
3158
NonRelocatable a;
3259
};
60+
static_assert(!__builtin_is_cpp_trivially_relocatable(J));
3361

34-
class G trivially_relocatable_if_eligible {
35-
G(G&&);
36-
};
37-
38-
class H trivially_relocatable_if_eligible {
39-
~H();
40-
};
4162

4263
struct Incomplete; // expected-note {{forward declaration of 'Incomplete'}}
4364
static_assert(__builtin_is_cpp_trivially_relocatable(Incomplete)); // expected-error {{incomplete type 'Incomplete' used in type trait expression}}
44-
static_assert(__builtin_is_cpp_trivially_relocatable(Trivial));
45-
static_assert(__builtin_is_cpp_trivially_relocatable(G));
46-
static_assert(__builtin_is_cpp_trivially_relocatable(H));
4765
static_assert(__builtin_is_cpp_trivially_relocatable(int));
4866
static_assert(__builtin_is_cpp_trivially_relocatable(void*));
4967
static_assert(!__builtin_is_cpp_trivially_relocatable(int&));
5068
static_assert(!__builtin_is_cpp_trivially_relocatable(Trivial&));
5169
static_assert(__builtin_is_cpp_trivially_relocatable(const Trivial));
5270
static_assert(__builtin_is_cpp_trivially_relocatable(Trivial[1]));
71+
static_assert(__builtin_is_cpp_trivially_relocatable(Trivial[]));
72+
73+
struct WithConst {
74+
const int i;
75+
};
76+
static_assert(__builtin_is_cpp_trivially_relocatable(WithConst));
5377

5478
struct UserDtr {
5579
~UserDtr();
@@ -115,9 +139,15 @@ struct DeletedMoveAssign {
115139
DeletedMoveAssign& operator=(DeletedMoveAssign&&) = delete;
116140
};
117141

142+
struct DeletedDtr {
143+
~DeletedDtr() = delete;
144+
};
145+
118146
static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedMove));
119147
static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedCopy));
120148
static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedMoveAssign));
149+
static_assert(!__builtin_is_cpp_trivially_relocatable(DeletedDtr));
150+
121151

122152
union U {
123153
G g;
@@ -174,6 +204,7 @@ static_assert(__builtin_is_replaceable(DefaultedMoveAssign));
174204
static_assert(!__builtin_is_replaceable(DeletedMove));
175205
static_assert(!__builtin_is_replaceable(DeletedCopy));
176206
static_assert(!__builtin_is_replaceable(DeletedMoveAssign));
207+
static_assert(!__builtin_is_replaceable(DeletedDtr));
177208

178209
static_assert(!__builtin_is_replaceable(UserProvidedMove));
179210
static_assert(!__builtin_is_replaceable(UserProvidedCopy));
@@ -276,3 +307,16 @@ void test__builtin_trivially_relocate() {
276307
__builtin_trivially_relocate((int*)0, (int*)0, 0);
277308
__builtin_trivially_relocate((R*)0, (R*)0, 0);
278309
}
310+
311+
void test__builtin_trivially_relocate(auto&& src, auto&&dest, auto size) {
312+
__builtin_trivially_relocate(src, dest, size); // #reloc1
313+
}
314+
315+
void do_test__builtin_trivially_relocate() {
316+
struct S{ ~S();};
317+
struct R {};
318+
test__builtin_trivially_relocate((R*)0, (R*)0, 0);
319+
test__builtin_trivially_relocate((S*)0, (S*)0, 0);
320+
// expected-note@-1 {{'test__builtin_trivially_relocate<S *, S *, int>' requested here}}
321+
// expected-error@#reloc1 {{first argument to '__builtin_trivially_relocate' must be relocatable}}
322+
}

0 commit comments

Comments
 (0)