Skip to content

Commit 52f8212

Browse files
committed
[CHERIoT] Fix divergence between frontend and backend as to whether CHERIoT counts as EABI.
It was always intended to be treated as such, but when upstream added support for EABI, we missed updating the check in the frontend to handle CHERIoT as well. This manifests as a bug only in one very specific scenario: clang maintains compatibility with non-conforming versions of GCC that do not properly align doubles on the stack when targeting EABI, aligning them instead to 4 bytes. CHERIoT does not specifically care whether or not we are using the GCC-compatible version, but if the frontend and backend disagree on which version we are using, then the caller and callee will end up with incompatible stack layouts. This is because the caller layout is constructed by the backend, while the callee layout is constructed by the frontend.
1 parent 592752f commit 52f8212

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ createTargetCodeGenInfo(CodeGenModule &CGM) {
244244
else if (ABIStr.ends_with("d"))
245245
ABIFLen = 64;
246246
bool EABI = ABIStr.ends_with("e");
247+
EABI |= ABIStr == "cheriot";
248+
EABI |= ABIStr == "cheriot-baremetal";
247249
return createRISCVTargetCodeGenInfo(CGM, XLen, ABIFLen, EABI);
248250
}
249251

clang/test/CodeGen/cheri/cheriot-variadic.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,24 @@ typedef struct {
1414

1515
extern int onward(void *, int, char *);
1616

17+
// CHECK-LABEL: @foo
1718
int foo(va_list ap) {
1819
// Make sure that we don't see a memcpy in address space zero!
1920
// CHECK-NOT: p0i8
2021
bar_t x = va_arg(ap, bar_t);
2122
return onward(x.a, x.b, x.c);
2223
}
24+
25+
// CHECK-LABEL: @bar
26+
double bar(const char* c, ...) {
27+
// Make sure that a double is *not* dynamically aligned up to 8 bytes.
28+
// This may change once the RVE spec is ratified and compatibility
29+
// with old versions of GCC are dropped in upstream.
30+
// CHECK-NOT: ptrmask
31+
va_list ap;
32+
va_start((ap), c);
33+
int i1 = va_arg(ap, int);
34+
double f = va_arg(ap, double);
35+
va_end(ap);
36+
return f;
37+
}

0 commit comments

Comments
 (0)