110 lines · cpp
1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s2// PR42623 4// CHECK-NOT: _ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag5 6// The "basic_string" extern template instantiation declaration is supposed to7// suppress the implicit instantiation of non-inline member functions. Make sure8// that we suppress the implicit instantiation of non-inline member functions9// defined out-of-line. That we aren't instantiating the basic_string10// constructor when we shouldn't be. Such an instantiation forces the implicit11// instantiation of _S_construct<const char*>. Since _S_construct is a member12// template, it's instantiation is *not* suppressed (despite being in13// basic_string<char>), so we would emit it as a weak definition.14 15#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default")))16#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))17#define _LIBCPP_VISIBLE __attribute__ ((__visibility__("default")))18#if (__has_feature(cxx_noexcept))19# define _NOEXCEPT noexcept20# define _NOEXCEPT_(x) noexcept(x)21#else22# define _NOEXCEPT throw()23# define _NOEXCEPT_(x)24#endif25 26namespace std // purposefully not using versioning namespace27{28 29template<class charT> struct char_traits;30template<class T> class allocator;31template <class _CharT,32 class _Traits = char_traits<_CharT>,33 class _Allocator = allocator<_CharT> >34 class _LIBCPP_VISIBLE basic_string;35typedef basic_string<char, char_traits<char>, allocator<char> > string;36 37class _LIBCPP_EXCEPTION_ABI exception38{39public:40 _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}41 virtual ~exception() _NOEXCEPT;42 virtual const char* what() const _NOEXCEPT;43};44 45class _LIBCPP_EXCEPTION_ABI runtime_error46 : public exception47{48private:49 void* __imp_;50public:51 explicit runtime_error(const string&);52 explicit runtime_error(const char*);53 54 runtime_error(const runtime_error&) _NOEXCEPT;55 runtime_error& operator=(const runtime_error&) _NOEXCEPT;56 57 virtual ~runtime_error() _NOEXCEPT;58 59 virtual const char* what() const _NOEXCEPT;60};61 62}63 64void dummysymbol() {65 throw(std::runtime_error("string"));66}67 68namespace not_weak_on_first {69 int func();70 // CHECK: {{.*}} extern_weak {{.*}} @_ZN17not_weak_on_first4funcEv(71 int func() __attribute__ ((weak));72 73 typedef int (*FuncT)();74 75 extern const FuncT table[] = {76 func,77 };78}79 80namespace constant_eval {81 [[gnu::weak]] extern int a;82 // CHECK-LABEL: define {{.*}} @__cxx_global_var_init83 // CHECK: [[CMP:%.*]] = icmp ne ptr @_ZN13constant_eval1aE, null84 // CHECK: [[ZEXT:%.*]] = zext i1 [[CMP]] to i885 // CHECK: store i8 [[ZEXT]], ptr @_ZN13constant_eval6has_a1E,86 bool has_a1 = &a;87 // CHECK-LABEL: define {{.*}} @__cxx_global_var_init88 // CHECK: [[CMP:%.*]] = icmp ne ptr @_ZN13constant_eval1aE, null89 // CHECK: [[ZEXT:%.*]] = zext i1 [[CMP]] to i890 // CHECK: store i8 [[ZEXT]], ptr @_ZN13constant_eval6has_a2E,91 bool has_a2 = &a != nullptr;92 93 struct X {94 [[gnu::weak]] void f();95 };96 // CHECK-LABEL: define {{.*}} @__cxx_global_var_init97 // CHECK: [[CMP:%.*]] = icmp ne i{{32|64}} ptrtoint (ptr @_ZN13constant_eval1X1fEv to i{{32|64}}), 098 // CHECK: [[ZEXT:%.*]] = zext i1 [[CMP]] to i899 // CHECK: store i8 [[ZEXT]], ptr @_ZN13constant_eval6has_f1E,100 bool has_f1 = &X::f;101 // CHECK-LABEL: define {{.*}} @__cxx_global_var_init102 // CHECK: [[CMP:%.*]] = icmp ne i{{32|64}} ptrtoint (ptr @_ZN13constant_eval1X1fEv to i{{32|64}}), 0103 // CHECK: [[CMP2:%.*]] = icmp ne i{{32|64}} ptrtoint (ptr @_ZN13constant_eval1X1fEv to i{{32|64}}), 0104 // CHECK: [[AND:%.*]] = and i1 [[CMP2]], false105 // CHECK: [[OR:%.*]] = or i1 [[CMP]], [[AND]]106 // CHECK: [[ZEXT:%.*]] = zext i1 [[OR]] to i8107 // CHECK: store i8 [[ZEXT]], ptr @_ZN13constant_eval6has_f2E,108 bool has_f2 = &X::f != nullptr;109}110