Skip to content

Commit 14b0e97

Browse files
authored
Fix more tests in error handling (#53)
* Checkpoint Failed Tests (12): Clang :: CXX/drs/cwg25xx.cpp Clang :: CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp Clang :: CXX/temp/temp.constr/temp.constr.atomic/constrant-satisfaction-conversions.cpp Clang :: CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp Clang :: CXX/temp/temp.constr/temp.constr.normal/p1.cpp Clang :: SemaCXX/concept-crash-on-diagnostic.cpp Clang :: SemaCXX/cxx23-assume.cpp Clang :: SemaCXX/cxx2c-fold-exprs.cpp Clang :: SemaCXX/invalid-requirement-requires-expr.cpp Clang :: SemaTemplate/concepts-recursive-inst.cpp Clang :: SemaTemplate/concepts.cpp Clang :: SemaTemplate/cxx2a-constraint-exprs.cpp * Fix more tests in error handling Remaining Failed Tests (7): Clang :: AST/ByteCode/libcxx/primitive-temporary.cpp Clang :: CXX/drs/cwg25xx.cpp Clang :: CXX/temp/temp.constr/temp.constr.normal/p1.cpp Clang :: SemaCXX/cxx2c-fold-exprs.cpp Clang :: SemaTemplate/alias-template-with-lambdas.cpp Clang :: SemaTemplate/concepts-recursive-inst.cpp Clang :: SemaTemplate/instantiate-abbreviated-template.cpp * Fix one more test * save * Fix more tests * Do not set ContainsError on substitution failure That would completely break overload resolution; see 684a789#diff-b7090bd1c9146da9ed3ff99bef9fa52903cf7034e9bca340446ffa0ab3549d04 ```cpp template <class _Tp, class _Up> concept same_as = __is_same(_Up, _Tp); template <class> using type_identity_t = int; enum __arg_t {}; template <class _Context, same_as<typename _Context::char_type>> void __determine_arg_t(); template <class, class> __arg_t __determine_arg_t(); struct array { int data; }; struct __compile_time_basic_format_context; template <class, class... _Args> struct basic_format_string { template <class _Tp> basic_format_string(_Tp __str) {} array __types_{ __determine_arg_t<__compile_time_basic_format_context, _Args>()...}; }; template <class... _Args> using format_string = basic_format_string<char, type_identity_t<_Args>...>; template <class... _Args> void format(format_string<_Args...>, _Args...); void __format() { format("", char()); } ``` * Reapply 7483711: Instantiate concepts with sugared template arguments The sugared arguments of concepts are necessary to compile the following case, thanks to a Profile bug of DependentDecltypeType: namespace { template <int __v> struct integral_constant { static const int value = __v; }; template <class _Tp> _Tp forward; struct _IfImpl { template <class _IfRes, class> using _Select = _IfRes; }; template <bool, class _IfRes, class _ElseRes> using _If = _IfImpl::_Select<_IfRes, _ElseRes>; template <class _If> struct conditional { using type = _If; }; template <bool, class _If, class> using __conditional_t = conditional<_If>::type; template <class _Tp> struct enable_if { typedef _Tp type; }; template <class _Tp> _Tp __declval(long); template <class _Tp> decltype(__declval<_Tp>(0)) declval(); template <class _Fp, class... _Args> decltype(_Fp()(declval<_Args>()...)) __invoke(_Fp, _Args...); template <class, class _Fp, class... _Args> struct __invokable_r { template <class _XFp, class... _XArgs> static decltype(__invoke(_XFp(), declval<_XArgs>()...)) __try_call(int); using _Result = decltype(__try_call<_Fp, _Args...>(0)); }; template <class _Func, class... _Args> struct __invoke_result : enable_if<typename __invokable_r<void, _Func, _Args...>::_Result> {}; template <class _Fn, class... _Args> using invoke_result_t = __invoke_result<_Fn, _Args...>::type; template <class _From, class _To> constexpr bool is_convertible_v = __is_convertible(_From, _To); template <class _From, class> concept convertible_to = requires { _From(); }; template <class _Tp> concept move_constructible = convertible_to<_Tp, _Tp>; template <class _Tp> constexpr bool is_object_v = __is_object(_Tp); template <class _Dp, class _Bp> concept derived_from = is_convertible_v<_Dp, _Bp>; template <class _Tp> concept __boolean_testable = requires { forward<_Tp>; }; template <class _Fn, class... _Args> invoke_result_t<_Fn, _Args...> invoke(_Fn, _Args...); template <class _Fn, class... _Args> concept invocable = requires(_Fn __fn, _Args... __args) { invoke(__fn, __args...); }; template <class _Fn, class... _Args> concept regular_invocable = invocable<_Fn, _Args...>; template <class _Fn, class... _Args> concept predicate = __boolean_testable<invoke_result_t<_Fn, _Args...>>; template <class> using iter_difference_t = decltype(static_cast<int *>(nullptr) - static_cast<int *>(nullptr)); template <decltype(sizeof(int)), class> struct tuple_element; template <class...> struct tuple {}; template <decltype(sizeof(int)) _Ip, class... _Tp> tuple_element<_Ip, tuple<_Tp...>>::type get(tuple<_Tp...>); template <class _Tp, _Tp...> struct integer_sequence; template <decltype(sizeof(int))... _Ip> using index_sequence = integer_sequence<decltype(sizeof(int)), _Ip...>; template <class _Tp, _Tp _Ep> using make_integer_sequence = __make_integer_seq<integer_sequence, _Tp, _Ep>; template <decltype(sizeof(int)) _Np> using make_index_sequence = make_integer_sequence<decltype(sizeof(int)), _Np>; template <class... _Tp> using index_sequence_for = make_index_sequence<sizeof...(_Tp)>; template <class...> struct __tuple_types; template <decltype(sizeof(int)) _Ip, class... _Types> struct tuple_element<_Ip, __tuple_types<_Types...>> { using type = __type_pack_element<_Ip, _Types...>; }; template <class _Tp> concept __dereferenceable = requires(_Tp __t) { __t; }; template <__dereferenceable _Tp> using iter_reference_t = decltype(*_Tp()); struct input_iterator_tag {}; struct forward_iterator_tag : input_iterator_tag {}; struct bidirectional_iterator_tag : forward_iterator_tag {}; struct contiguous_iterator_tag : bidirectional_iterator_tag {}; auto to_address(0); template <class _Ip> concept input_or_output_iterator = requires(_Ip __i) { __i; }; template <class _Sp, class _Ip> concept sized_sentinel_for = requires(_Ip __i, _Sp __s) { __i - __s; }; template <class _Ip> concept input_iterator = derived_from<typename _Ip::iterator_concept, input_iterator_tag>; template <class _Ip> concept forward_iterator = derived_from<typename _Ip::iterator_concept, forward_iterator_tag>; template <class> concept bidirectional_iterator = requires { to_address; }; template <class _Fp, class _It> concept indirect_unary_predicate = predicate<_Fp, iter_reference_t<_It>>; namespace ranges { struct { template <class _Tp> auto operator()(_Tp __t) { return __t.begin(); } } begin; template <class _Tp> using iterator_t = decltype(begin(declval<_Tp>())); template <class> constexpr bool enable_view = requires { nullptr; }; template <class _Tp> concept __difference = requires(_Tp __t) { { begin(__t) } -> sized_sentinel_for<decltype(begin(declval<_Tp>()))>; // { begin(__t) } -> sized_sentinel_for<decltype(begin(_Tp()))>; }; struct { template <__difference _Tp> auto operator()(_Tp __t) { auto __trans_tmp_1(__t); 0 - __trans_tmp_1; } } size; template <class _Tp> concept range = requires(_Tp __t) { __t; }; template <class _Tp> concept input_range = input_iterator<iterator_t<_Tp>>; template <range _Rp> using range_difference_t = iter_difference_t<_Rp>; template <range _Rp> using range_reference_t = iter_reference_t<iterator_t<_Rp>>; template <class _Tp> concept sized_range = requires(_Tp __t) { size(__t); }; template <class _Tp> concept forward_range = forward_iterator<iterator_t<_Tp>>; template <class _Tp> concept bidirectional_range = bidirectional_iterator<_Tp>; } // namespace ranges template <class> struct tuple_size; template <class... _Tp> struct tuple_size<tuple<_Tp...>> : integral_constant<sizeof...(_Tp)> {}; template <class _Tp> constexpr decltype(sizeof(int)) tuple_size_v = tuple_size<_Tp>::value; namespace ranges { template <class _Derived> struct view_interface { template <class _D2 = _Derived> void front() requires forward_range<_D2>; }; } // namespace ranges struct __rule {}; struct basic_string {}; template <decltype(sizeof(int)) _Ip, class... _Tp> struct tuple_element<_Ip, tuple<_Tp...>> { using type = tuple_element<_Ip, __tuple_types<_Tp...>>::type; }; template <bool _Const, class _Tp> using __maybe_const = __conditional_t<_Const, _Tp, _Tp>; template <class...> struct __perfect_forward_impl; template <class _Op, decltype(sizeof(int))... _Idx, class... _BoundArgs> struct __perfect_forward_impl<_Op, index_sequence<_Idx...>, _BoundArgs...> { tuple<_BoundArgs...> __bound_args_; template <class... _Args> auto operator()(_Args... __args) -> decltype(_Op()(get<_Idx>(__bound_args_)..., __args...)); }; template <class _Op, class... _Args> using __perfect_forward = __perfect_forward_impl<_Op, index_sequence_for<_Args...>, _Args...>; struct __wrap_iter { typedef contiguous_iterator_tag iterator_concept; __rule operator*(); }; struct vector { __wrap_iter begin(); }; namespace ranges { template <class> concept _RangeAdaptorClosure = requires { nullptr; }; template <range _Range, _RangeAdaptorClosure _Closure> auto operator|(_Range __range, _Closure __closure) { return invoke(__closure, __range); } } // namespace ranges template <input_or_output_iterator _Iter> struct counted_iterator : _Iter { counted_iterator(_Iter, iter_difference_t<_Iter>); }; template <decltype(sizeof(int)) _NBound, class = make_index_sequence<_NBound>> struct __bind_back_op; template <decltype(sizeof(int)) _NBound, decltype(sizeof(int))... _Ip> struct __bind_back_op<_NBound, index_sequence<_Ip...>> { template <class _Fn, class _BoundArgs, class... _Args> auto operator()(_Fn __f, _BoundArgs __bound_args, _Args... __args) -> decltype(invoke(__f, __args..., get<_Ip>(__bound_args)...)); }; template <class _Fn, class _BoundArgs> struct __bind_back_t : __perfect_forward<__bind_back_op<tuple_size_v<_BoundArgs>>, _Fn, _BoundArgs> {}; template <class _Fn, class... _Args> auto __bind_back(_Fn, _Args...) -> decltype(__bind_back_t<_Fn, tuple<_Args...>>()); namespace ranges { struct __empty_cache; template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred> requires is_object_v<_Pred> class filter_view { class __iterator; public: filter_view(_View, _Pred); __iterator begin(); }; template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred> requires is_object_v<_Pred> class filter_view<_View, _Pred>::__iterator { public: using iterator_concept = _If<bidirectional_range<_View>, bidirectional_iterator_tag, _If<forward_range<_View>, forward_iterator_tag, input_iterator_tag>>; range_reference_t<_View> operator*(); }; struct { template <class _Range, class _Pred> auto operator()(_Range __range, _Pred __pred) -> decltype(filter_view(__range, __pred)); template <class _Pred> auto operator()(_Pred __pred) { return __bind_back(*this, __pred); } } filter; template <input_range _View> struct lazy_split_view { template <int _Const> struct __outer_iterator { using _Base = __maybe_const<_Const, _View>; _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>; }; }; template <class _View> struct take_view : view_interface<take_view<_View>> { _View __base_; range_difference_t<_View> __count_; take_view(_View, range_difference_t<_View>); auto begin() { sized_range<_View>; return counted_iterator(ranges::begin(__base_), __count_); } }; struct { template <class _Range, convertible_to<_Range> _Np> auto operator()(_Range __range, _Np __n) -> decltype(take_view(__range, __n)); auto operator()(int __n) { return __bind_back(*this, __n); } } take; template <class _View, class _Fn> concept __transform_view_constraints = regular_invocable<_Fn, invoke_result_t<_Fn, range_reference_t<_View>>>; template <class _View, class _Fn> struct transform_view { template <bool> class __iterator; transform_view(_View, _Fn); __iterator<false> begin(); }; template <class> struct __transform_view_iterator_concept { using type = forward_iterator_tag; }; template <class _View, class _Fn> template <bool _Const> class transform_view<_View, _Fn>::__iterator { using _Base = __maybe_const<_Const, _View>; public: using iterator_concept = __transform_view_iterator_concept<_View>::type; _Base friend operator-(__iterator, __iterator) // iterator_t<_Base> was canonicalized to the type of the one written on line 221 iterator_t<_Base>. requires sized_sentinel_for<_Base, iterator_t<_Base>> {} }; struct { template <class _Range, class _Fn> auto operator()(_Range __range, _Fn __f) -> decltype(transform_view(__range, __f)); template <class _Fn> auto operator()(_Fn __f) { return __bind_back(*this, __f); } } transform; } // namespace ranges namespace views = ranges; vector __letters_before_first_rule___rules; basic_string __letters_before_first_rule() { auto __letters = __letters_before_first_rule___rules | views::filter([](__rule) { return 0; }) | views::transform([](__rule __rule) { return __rule; }) | views::take(1); __letters.front(); } } // namespace
1 parent a0dd009 commit 14b0e97

27 files changed

+345
-245
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,6 @@ Bug Fixes to C++ Support
835835
- Fixed an access checking bug when initializing non-aggregates in default arguments (#GH62444), (#GH83608)
836836
- Fixed a pack substitution bug in deducing class template partial specializations. (#GH53609)
837837
- Fixed a crash when constant evaluating some explicit object member assignment operators. (#GH142835)
838-
- Fixed an access checking bug when substituting into concepts (#GH115838)
839838

840839
Bug Fixes to AST Handling
841840
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Sema/Template.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,8 @@ enum class TemplateSubstitutionKind : char {
234234
/// Replaces the current 'innermost' level with the provided argument list.
235235
/// This is useful for type deduction cases where we need to get the entire
236236
/// list from the AST, but then add the deduced innermost list.
237-
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) {
237+
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args,
238+
bool Final = false) {
238239
assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) &&
239240
"Replacing in an empty list?");
240241

@@ -249,7 +250,7 @@ enum class TemplateSubstitutionKind : char {
249250
} else {
250251
--NumRetainedOuterLevels;
251252
TemplateArgumentLists.push_back(
252-
{{AssociatedDecl, /*Final=*/false}, Args});
253+
{{AssociatedDecl, /*Final=*/Final}, Args});
253254
}
254255
}
255256

0 commit comments

Comments
 (0)