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