Skip to content

Commit e0ebb39

Browse files
committed
Memory copies from string literals do not need to preserve tags
1 parent 26fe50a commit e0ebb39

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

clang/lib/CodeGen/CodeGenTypes.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,11 @@ CodeGenTypes::copyShouldPreserveTags(const Expr *E, Optional<CharUnits> Size) {
10131013
QualType Ty = E->IgnoreParenImpCasts()->getType();
10141014
if (Ty->isAnyPointerType())
10151015
Ty = Ty->getPointeeType();
1016+
const Expr *UnderlyingExpr = E->IgnoreParenCasts();
1017+
if (const auto *SL = dyn_cast<StringLiteral>(UnderlyingExpr)) {
1018+
// String literals can never contain tag bits.
1019+
return llvm::PreserveCheriTags::Unnecessary;
1020+
}
10161021
// TODO: Find the underlying VarDecl to improve diagnostics
10171022
const VarDecl *UnderlyingVar = nullptr;
10181023
// TODO: this assertion may be overly aggressive.

clang/test/CodeGen/cheri/no-tag-copy-attribute-with-caps.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,16 @@ void test_string_constant(struct OneCap *cap) {
110110
// CHECK-LABEL: void @test_string_constant(
111111
// Same for string -> char*
112112
__builtin_memmove(cap, "abcdefghijklmnopqrstuvwxyz", sizeof(*cap));
113-
// expected-warning@-1{{memcpy operation with capability argument <unknown type> and underaligned destination (aligned to 1 bytes) may be inefficient or result in CHERI tags bits being stripped}} expected-note@-1{{For more information}}
114113
// CHECK: call void @llvm.memmove.p200i8.p200i8.i64(i8 addrspace(200)* align 16 {{%[a-z0-9]+}}, i8 addrspace(200)* align 1 getelementptr inbounds ([27 x i8], [27 x i8] addrspace(200)* @.str
115114
// CHECK-SAME: , i64 0
116115
// CHECK-SAME: , i64 0)
117-
// CHECK-SAME: , i64 16, i1 false) [[MUST_PRESERVE_ATTR]]{{$}}
118-
// FIXME-SAME: , i64 16, i1 false) [[NO_PRESERVE_ATTR]]{{$}}
116+
// CHECK-SAME: , i64 16, i1 false) [[NO_PRESERVE_ATTR]]{{$}}
117+
/// Check that the explicit cast does not affect the analysis.
118+
__builtin_memmove(cap, (void*)"abcdefghijklmnopqrstuvwxyz", sizeof(*cap));
119+
// CHECK: call void @llvm.memmove.p200i8.p200i8.i64(i8 addrspace(200)* align 16 {{%[a-z0-9]+}}, i8 addrspace(200)* align 1 getelementptr inbounds ([27 x i8], [27 x i8] addrspace(200)* @.str
120+
// CHECK-SAME: , i64 0
121+
// CHECK-SAME: , i64 0)
122+
// CHECK-SAME: , i64 16, i1 false) [[NO_PRESERVE_ATTR]]{{$}}
119123
}
120124

121125
void test_void_buffer(struct OneCap *cap, void *buf) {

0 commit comments

Comments
 (0)