cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
132 lines
4.6 KiB
C++
132 lines
4.6 KiB
C++
// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes=CHECK,C
|
|
// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CXX
|
|
// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fclang-abi-compat=19 | FileCheck %s --check-prefixes=CHECK,CXXCLANG19
|
|
// RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0 -target-abi aapcs16 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WATCHOS
|
|
|
|
// Empty structs are ignored for PCS purposes on WatchOS and in C mode
|
|
// elsewhere. In C++ mode they consume a register slot though. Functions are
|
|
// slightly bigger than minimal to make confirmation against actual GCC
|
|
// behaviour easier.
|
|
|
|
#if __cplusplus
|
|
#define EXTERNC extern "C"
|
|
#else
|
|
#define EXTERNC
|
|
#endif
|
|
|
|
struct Empty {};
|
|
|
|
// C: define{{.*}} i32 @empty_arg(i32 noundef %a)
|
|
// CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a)
|
|
// CXXCLANG19: define{{.*}} i32 @empty_arg(i32 noundef %a)
|
|
// WATCHOS: define{{.*}} i32 @empty_arg(i32 noundef %a)
|
|
EXTERNC int empty_arg(struct Empty e, int a) {
|
|
return a;
|
|
}
|
|
|
|
// C: define{{.*}} void @empty_ret()
|
|
// CXX: define{{.*}} void @empty_ret()
|
|
// CXXCLANG19: define{{.*}} void @empty_ret()
|
|
// WATCHOS: define{{.*}} void @empty_ret()
|
|
EXTERNC struct Empty empty_ret(void) {
|
|
struct Empty e;
|
|
return e;
|
|
}
|
|
|
|
// However, what counts as "empty" is a baroque mess. This is super-empty, it's
|
|
// ignored even in C++ mode. It also has sizeof == 0, violating C++, but that's
|
|
// legacy for you:
|
|
|
|
struct SuperEmpty {
|
|
int arr[0];
|
|
};
|
|
|
|
// C: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
|
|
// CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
|
|
// CXXCLANG19: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
|
|
// WATCHOS: define{{.*}} i32 @super_empty_arg(i32 noundef %a)
|
|
EXTERNC int super_empty_arg(struct SuperEmpty e, int a) {
|
|
return a;
|
|
}
|
|
|
|
struct SortOfEmpty {
|
|
struct SuperEmpty e;
|
|
};
|
|
|
|
// C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
|
|
// CXX: define{{.*}} i32 @sort_of_empty_arg(i8 %e.coerce, i32 noundef %a)
|
|
// CXXCLANG19: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
|
|
// WATCHOS: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a)
|
|
EXTERNC int sort_of_empty_arg(struct Empty e, int a) {
|
|
return a;
|
|
}
|
|
|
|
// C: define{{.*}} void @sort_of_empty_ret()
|
|
// CXX: define{{.*}} void @sort_of_empty_ret()
|
|
// CXXCLANG19: define{{.*}} void @sort_of_empty_ret()
|
|
// WATCHOS: define{{.*}} void @sort_of_empty_ret()
|
|
EXTERNC struct SortOfEmpty sort_of_empty_ret(void) {
|
|
struct SortOfEmpty e;
|
|
return e;
|
|
}
|
|
|
|
#include <stdarg.h>
|
|
|
|
// va_arg matches the above rules, consuming an incoming argument in cases
|
|
// where one would be passed, and not doing so when the argument should be
|
|
// ignored.
|
|
|
|
EXTERNC int empty_arg_variadic(int a, ...) {
|
|
// CHECK-LABEL: @empty_arg_variadic(
|
|
// C: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// C-NOT: {{ getelementptr }}
|
|
// CXX: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// CXX: %argp.next2 = getelementptr inbounds i8, ptr %argp.cur1, i32 4
|
|
// CXXCLANG19: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// CXXCLANG19-NOT: {{ getelementptr }}
|
|
// WATCHOS: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// WATCHOS-NOT: {{ getelementptr }}
|
|
va_list vl;
|
|
va_start(vl, a);
|
|
struct Empty b = va_arg(vl, struct Empty);
|
|
int c = va_arg(vl, int);
|
|
va_end(vl);
|
|
return c;
|
|
}
|
|
|
|
EXTERNC int super_empty_arg_variadic(int a, ...) {
|
|
// CHECK-LABEL: @super_empty_arg_variadic(
|
|
// C: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// C-NOT: {{ getelementptr }}
|
|
// CXX: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// CXX-NOT: {{ getelementptr }}
|
|
// CXXCLANG19: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// CXXCLANG19-NOT: {{ getelementptr }}
|
|
// WATCHOS: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// WATCHOS-NOT: {{ getelementptr }}
|
|
va_list vl;
|
|
va_start(vl, a);
|
|
struct SuperEmpty b = va_arg(vl, struct SuperEmpty);
|
|
int c = va_arg(vl, int);
|
|
va_end(vl);
|
|
return c;
|
|
}
|
|
|
|
EXTERNC int sort_of_empty_arg_variadic(int a, ...) {
|
|
// CHECK-LABEL: @sort_of_empty_arg_variadic(
|
|
// C: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// C-NOT: {{ getelementptr }}
|
|
// CXX: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// CXX-NOT: {{ getelementptr }}
|
|
// CXXCLANG19: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// CXXCLANG19-NOT: {{ getelementptr }}
|
|
// WATCHOS: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4
|
|
// WATCHOS-NOT: {{ getelementptr }}
|
|
va_list vl;
|
|
va_start(vl, a);
|
|
struct SortOfEmpty b = va_arg(vl, struct SortOfEmpty);
|
|
int c = va_arg(vl, int);
|
|
va_end(vl);
|
|
return c;
|
|
}
|