1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
// RUN: %clang_cc1 -triple x86_64-linux -fblocks -emit-llvm -o - %s -std=c++1y | FileCheck %s
// CHECK: @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2" =
// CHECK: internal global i32* @"_ZZNK17pr18020_constexpr3$_1clEvE2l1"
// CHECK: @_ZZL14deduced_returnvE1n = internal global i32 42
// CHECK: @_ZZZL20block_deduced_returnvEUb_E1n = internal global i32 42
// CHECK: @_ZZ18static_local_labelPvE1q = linkonce_odr global i8* blockaddress(@_Z18static_local_labelPv, %{{.*}})
// CHECK: @"_ZZNK3$_2clEvE1x" = internal global i32 42
namespace pr6769 {
struct X {
static void f();
};
void X::f() {
static int *i;
{
struct Y {
static void g() {
i = new int();
*i = 100;
(*i) = (*i) +1;
}
};
(void)Y::g();
}
(void)i;
}
}
namespace pr7101 {
void foo() {
static int n = 0;
struct Helper {
static void Execute() {
n++;
}
};
Helper::Execute();
}
}
// These tests all break the assumption that the static var decl has to be
// emitted before use of the var decl. This happens because we defer emission
// of variables with internal linkage and no initialization side effects, such
// as 'x'. Then we hit operator()() in 'f', and emit the callee before we emit
// the arguments, so we emit the innermost function first.
namespace pr18020_lambda {
// Referring to l1 before emitting it used to crash.
auto x = []() {
static int l1 = 0;
return [] { return l1; };
};
int f() { return x()(); }
}
// CHECK-LABEL: define internal i32 @"_ZZNK14pr18020_lambda3$_0clEvENKUlvE_clEv"
// CHECK: load i32, i32* @"_ZZNK14pr18020_lambda3$_0clEvE2l1"
namespace pr18020_constexpr {
// Taking the address of l1 in a constant expression used to crash.
auto x = []() {
static int l1 = 0;
return [] {
static int *l2 = &l1;
return *l2;
};
};
int f() { return x()(); }
}
// CHECK-LABEL: define internal i32 @"_ZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEv"
// CHECK: load i32*, i32** @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2"
// Lambda-less reduction that references l1 before emitting it. This didn't
// crash if you put it in a namespace.
struct pr18020_class {
auto operator()() {
static int l1 = 0;
struct U {
int operator()() { return l1; }
};
return U();
}
};
static pr18020_class x;
int pr18020_f() { return x()(); }
// CHECK-LABEL: define linkonce_odr i32 @_ZZN13pr18020_classclEvEN1UclEv
// CHECK: load i32, i32* @_ZZN13pr18020_classclEvE2l1
// In this test case, the function containing the static local will not be
// emitted because it is unneeded. However, the operator call of the inner class
// is called, and the static local is referenced and must be emitted.
static auto deduced_return() {
static int n = 42;
struct S { int *operator()() { return &n; } };
return S();
}
extern "C" int call_deduced_return_operator() {
return *decltype(deduced_return())()();
}
// CHECK-LABEL: define i32 @call_deduced_return_operator()
// CHECK: call i32* @_ZZL14deduced_returnvEN1SclEv(
// CHECK: load i32, i32* %
// CHECK: ret i32 %
// CHECK-LABEL: define internal i32* @_ZZL14deduced_returnvEN1SclEv(%struct.S* %this)
// CHECK: ret i32* @_ZZL14deduced_returnvE1n
static auto block_deduced_return() {
auto (^b)() = ^() {
static int n = 42;
struct S { int *operator()() { return &n; } };
return S();
};
return b();
}
extern "C" int call_block_deduced_return() {
return *decltype(block_deduced_return())()();
}
// CHECK-LABEL: define i32 @call_block_deduced_return()
// CHECK: call i32* @_ZZZL20block_deduced_returnvEUb_EN1SclEv(
// CHECK: load i32, i32* %
// CHECK: ret i32 %
// CHECK-LABEL: define internal i32* @_ZZZL20block_deduced_returnvEUb_EN1SclEv(%struct.S.6* %this) #0 align 2 {
// CHECK: ret i32* @_ZZZL20block_deduced_returnvEUb_E1n
inline auto static_local_label(void *p) {
if (p)
goto *p;
static void *q = &&label;
struct S { static void *get() { return q; } };
return S();
label:
__builtin_abort();
}
void *global_label = decltype(static_local_label(0))::get();
// CHECK-LABEL: define linkonce_odr i8* @_ZZ18static_local_labelPvEN1S3getEv()
// CHECK: %[[lbl:[^ ]*]] = load i8*, i8** @_ZZ18static_local_labelPvE1q
// CHECK: ret i8* %[[lbl]]
auto global_lambda = []() {
static int x = 42;
struct S { static int *get() { return &x; } };
return S();
};
extern "C" int use_global_lambda() {
return *decltype(global_lambda())::get();
}
// CHECK-LABEL: define i32 @use_global_lambda()
// CHECK: call i32* @"_ZZNK3$_2clEvEN1S3getEv"()
// CHECK-LABEL: define internal i32* @"_ZZNK3$_2clEvEN1S3getEv"()
// CHECK: ret i32* @"_ZZNK3$_2clEvE1x"
|