xref: /llvm-project/clang/test/Headers/crash-instantiated-in-scope-cxx-modules.cpp (revision 2ccac07bf22d17029d4437b0a727dd55c8c86d56)
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