1*2ccac07bSDmitry Polukhin // RUN: rm -fR %t 2*2ccac07bSDmitry Polukhin // RUN: split-file %s %t 3*2ccac07bSDmitry Polukhin // RUN: cd %t 4*2ccac07bSDmitry Polukhin // RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header -Werror=uninitialized folly-conv.h 5*2ccac07bSDmitry Polukhin // RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header -Werror=uninitialized thrift_cpp2_base.h 6*2ccac07bSDmitry Polukhin // RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header -Werror=uninitialized -fmodule-file=folly-conv.pcm -fmodule-file=thrift_cpp2_base.pcm logger_base.h 7*2ccac07bSDmitry Polukhin 8*2ccac07bSDmitry Polukhin //--- Conv.h 9*2ccac07bSDmitry Polukhin #pragma once 10*2ccac07bSDmitry Polukhin 11*2ccac07bSDmitry Polukhin template <typename _Tp, typename _Up = _Tp&&> 12*2ccac07bSDmitry Polukhin _Up __declval(int); 13*2ccac07bSDmitry Polukhin 14*2ccac07bSDmitry Polukhin template <typename _Tp> 15*2ccac07bSDmitry Polukhin auto declval() noexcept -> decltype(__declval<_Tp>(0)); 16*2ccac07bSDmitry Polukhin 17*2ccac07bSDmitry Polukhin namespace folly { 18*2ccac07bSDmitry Polukhin 19*2ccac07bSDmitry Polukhin template <class Value, class Error> 20*2ccac07bSDmitry Polukhin struct Expected { 21*2ccac07bSDmitry Polukhin template <class Yes> 22*2ccac07bSDmitry Polukhin auto thenOrThrow() -> decltype(declval<Value&>()) { 23*2ccac07bSDmitry Polukhin return 1; 24*2ccac07bSDmitry Polukhin } 25*2ccac07bSDmitry Polukhin }; 26*2ccac07bSDmitry Polukhin 27*2ccac07bSDmitry Polukhin struct ExpectedHelper { 28*2ccac07bSDmitry Polukhin template <class Error, class T> 29*2ccac07bSDmitry Polukhin static constexpr Expected<T, Error> return_(T) { 30*2ccac07bSDmitry Polukhin return Expected<T, Error>(); 31*2ccac07bSDmitry Polukhin } 32*2ccac07bSDmitry Polukhin 33*2ccac07bSDmitry Polukhin template <class This, class Fn, class E = int, class T = ExpectedHelper> 34*2ccac07bSDmitry Polukhin static auto then_(This&&, Fn&&) 35*2ccac07bSDmitry Polukhin -> decltype(T::template return_<E>((declval<Fn>()(true), 0))) { 36*2ccac07bSDmitry Polukhin return Expected<int, int>(); 37*2ccac07bSDmitry Polukhin } 38*2ccac07bSDmitry Polukhin }; 39*2ccac07bSDmitry Polukhin 40*2ccac07bSDmitry Polukhin template <class Tgt> 41*2ccac07bSDmitry Polukhin inline Expected<Tgt, const char*> tryTo() { 42*2ccac07bSDmitry Polukhin Tgt result = 0; 43*2ccac07bSDmitry Polukhin // In build with asserts: 44*2ccac07bSDmitry Polukhin // clang/lib/Sema/SemaTemplateInstantiate.cpp: llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *clang::LocalInstantiationScope::findInstantiationOf(const Decl *): Assertion `isa<LabelDecl>(D) && "declaration not instantiated in this scope"' failed. 45*2ccac07bSDmitry Polukhin // In release build compilation error on the line below inside lambda: 46*2ccac07bSDmitry Polukhin // error: variable 'result' is uninitialized when used here [-Werror,-Wuninitialized] 47*2ccac07bSDmitry Polukhin ExpectedHelper::then_(Expected<bool, int>(), [&](bool) { return result; }); 48*2ccac07bSDmitry Polukhin return {}; 49*2ccac07bSDmitry Polukhin } 50*2ccac07bSDmitry Polukhin 51*2ccac07bSDmitry Polukhin } // namespace folly 52*2ccac07bSDmitry Polukhin 53*2ccac07bSDmitry Polukhin inline void bar() { 54*2ccac07bSDmitry Polukhin folly::tryTo<int>(); 55*2ccac07bSDmitry Polukhin } 56*2ccac07bSDmitry Polukhin // expected-no-diagnostics 57*2ccac07bSDmitry Polukhin 58*2ccac07bSDmitry Polukhin //--- folly-conv.h 59*2ccac07bSDmitry Polukhin #pragma once 60*2ccac07bSDmitry Polukhin #include "Conv.h" 61*2ccac07bSDmitry Polukhin // expected-no-diagnostics 62*2ccac07bSDmitry Polukhin 63*2ccac07bSDmitry Polukhin //--- thrift_cpp2_base.h 64*2ccac07bSDmitry Polukhin #pragma once 65*2ccac07bSDmitry Polukhin #include "Conv.h" 66*2ccac07bSDmitry Polukhin // expected-no-diagnostics 67*2ccac07bSDmitry Polukhin 68*2ccac07bSDmitry Polukhin //--- logger_base.h 69*2ccac07bSDmitry Polukhin #pragma once 70*2ccac07bSDmitry Polukhin import "folly-conv.h"; 71*2ccac07bSDmitry Polukhin import "thrift_cpp2_base.h"; 72*2ccac07bSDmitry Polukhin 73*2ccac07bSDmitry Polukhin inline void foo() { 74*2ccac07bSDmitry Polukhin folly::tryTo<unsigned>(); 75*2ccac07bSDmitry Polukhin } 76*2ccac07bSDmitry Polukhin // expected-no-diagnostics 77