// 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 struct S { int x, y; }; // CHECK-LABEL: @_Z23get_offset_of_y_naivelyv( // CHECK-NEXT: entry: // CHECK-NEXT: ret i64 ptrtoint (ptr getelementptr ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64) // 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 ptrtoint (ptr getelementptr ([[STRUCT_S:%.*]], ptr getelementptr ([[STRUCT_T:%.*]], ptr null, i32 0, i32 1), i32 0, i32 1) to i64) // 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 ptrtoint (ptr getelementptr ([[STRUCT_S:%.*]], ptr getelementptr ([[STRUCT_T:%.*]], ptr null, i32 0, i32 1), i32 0, i32 1) to i64) // 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 ptrtoint (ptr getelementptr (i8, ptr null, i64 16) to i64) // 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 ptrtoint (ptr getelementptr ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64) // 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 ptrtoint (ptr getelementptr ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64) // 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 ptrtoint (ptr getelementptr ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64) // 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 ptrtoint (ptr getelementptr inbounds nuw ([[STRUCT_S:%.*]], ptr null, i32 0, i32 1) to i64) // 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); }