Use the DataLayout-aware TargetFolder instead of ConstantFolder in Clang's CGBuilder. The primary impact of this change is that GEP constant expressions are now emitted in canonical `getelementptr i8` form. This is in preparation for the migration to ptradd, which requires this form. Part of the test updates were performed by Claude Code and reviewed by me.
96 lines
2.4 KiB
C++
96 lines
2.4 KiB
C++
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
|
// RUN: %clang_cc1 -x c++ -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
|
|
// RUN: %clang_cc1 -x c++ -fsanitize=pointer-overflow -fno-sanitize-recover=pointer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
|
|
|
|
#include <stdint.h>
|
|
|
|
struct S {
|
|
int x, y;
|
|
};
|
|
|
|
// CHECK-LABEL: @_Z23get_offset_of_y_naivelyv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 4
|
|
//
|
|
uintptr_t get_offset_of_y_naively() {
|
|
return ((uintptr_t)(&(((S *)nullptr)->y)));
|
|
}
|
|
|
|
struct Empty {};
|
|
|
|
struct T {
|
|
int a;
|
|
S s;
|
|
[[no_unique_address]] Empty e1;
|
|
int b;
|
|
[[no_unique_address]] Empty e2;
|
|
};
|
|
|
|
// CHECK-LABEL: @_Z30get_offset_of_y_naively_nestedv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 8
|
|
//
|
|
uintptr_t get_offset_of_y_naively_nested() {
|
|
return ((uintptr_t)(&(((T *)nullptr)->s.y)));
|
|
}
|
|
|
|
// CHECK-LABEL: @_Z42get_offset_of_y_naively_nested_with_parensv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 8
|
|
//
|
|
uintptr_t get_offset_of_y_naively_nested_with_parens() {
|
|
return ((uintptr_t)(&((((T *)nullptr)->s).y)));
|
|
}
|
|
|
|
// CHECK-LABEL: @_Z26get_offset_of_zero_storagev(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 16
|
|
//
|
|
uintptr_t get_offset_of_zero_storage() {
|
|
return ((uintptr_t)(&(((T *)nullptr)->e2)));
|
|
}
|
|
|
|
namespace std { typedef decltype(__nullptr) nullptr_t; }
|
|
// CHECK-LABEL: @_Z29get_offset_of_y_integral_zerov(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 4
|
|
//
|
|
uintptr_t get_offset_of_y_integral_zero() {
|
|
return ((uintptr_t)(&(((S *)0)->y)));
|
|
}
|
|
|
|
// CHECK-LABEL: @_Z37get_offset_of_y_integral_zero_voidptrv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 4
|
|
//
|
|
uintptr_t get_offset_of_y_integral_zero_voidptr() {
|
|
return ((uintptr_t)(&(((S *)(void*)0)->y)));
|
|
}
|
|
|
|
// CHECK-LABEL: @_Z25get_offset_of_y_nullptr_tv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 4
|
|
//
|
|
uintptr_t get_offset_of_y_nullptr_t() {
|
|
return ((uintptr_t)(&(((S *)std::nullptr_t{})->y)));
|
|
}
|
|
|
|
// CHECK-LABEL: @_Z32get_offset_of_y_nullptr_constantv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[NULL:%.*]] = alloca ptr, align 8
|
|
// CHECK-NEXT: store ptr null, ptr [[NULL]], align 8
|
|
// CHECK-NEXT: ret i64 4
|
|
//
|
|
uintptr_t get_offset_of_y_nullptr_constant() {
|
|
constexpr void *null = nullptr;
|
|
return ((uintptr_t)(&(((S *)null)->y)));
|
|
}
|
|
|
|
// CHECK-LABEL: @_Z27get_offset_of_y_via_builtinv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: ret i64 4
|
|
//
|
|
uintptr_t get_offset_of_y_via_builtin() {
|
|
return __builtin_offsetof(S, y);
|
|
}
|