Skip to content

Commit cc13e87

Browse files
zyn0217cor3ntin
authored andcommitted
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 c996b9e commit cc13e87

26 files changed

+379
-186
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Bug Fixes to Attribute Support
181181

182182
Bug Fixes to C++ Support
183183
^^^^^^^^^^^^^^^^^^^^^^^^
184+
<<<<<<< HEAD
184185
- Diagnose binding a reference to ``*nullptr`` during constant evaluation. (#GH48665)
185186
- Suppress ``-Wdeprecated-declarations`` in implicitly generated functions. (#GH147293)
186187
- Fix a crash when deleting a pointer to an incomplete array (#GH150359).
@@ -189,6 +190,96 @@ Bug Fixes to C++ Support
189190
- Fix the dynamic_cast to final class optimization to correctly handle
190191
casts that are guaranteed to fail (#GH137518).
191192
- Fix bug rejecting partial specialization of variable templates with auto NTTPs (#GH118190).
193+
=======
194+
195+
- Clang now supports implicitly defined comparison operators for friend declarations. (#GH132249)
196+
- Clang now diagnoses copy constructors taking the class by value in template instantiations. (#GH130866)
197+
- Clang is now better at keeping track of friend function template instance contexts. (#GH55509)
198+
- Clang now prints the correct instantiation context for diagnostics suppressed
199+
by template argument deduction.
200+
- Errors that occur during evaluation of certain type traits and builtins are
201+
no longer incorrectly emitted when they are used in an SFINAE context. The
202+
type traits are:
203+
204+
- ``__is_constructible`` and variants,
205+
- ``__is_convertible`` and variants,
206+
- ``__is_assignable`` and variants,
207+
- ``__reference_binds_to_temporary``,
208+
``__reference_constructs_from_temporary``,
209+
``__reference_converts_from_temporary``,
210+
- ``__is_trivially_equality_comparable``.
211+
212+
The builtin is ``__builtin_common_type``. (#GH132044)
213+
- Clang is now better at instantiating the function definition after its use inside
214+
of a constexpr lambda. (#GH125747)
215+
- Fixed a local class member function instantiation bug inside dependent lambdas. (#GH59734), (#GH132208)
216+
- Clang no longer crashes when trying to unify the types of arrays with
217+
certain differences in qualifiers (this could happen during template argument
218+
deduction or when building a ternary operator). (#GH97005)
219+
- Fixed type alias CTAD issues involving default template arguments. (#GH134471)
220+
- Fixed CTAD issues when initializing anonymous fields with designated initializers. (#GH67173)
221+
- The initialization kind of elements of structured bindings
222+
direct-list-initialized from an array is corrected to direct-initialization.
223+
- Clang no longer crashes when a coroutine is declared ``[[noreturn]]``. (#GH127327)
224+
- Clang now uses the parameter location for abbreviated function templates in ``extern "C"``. (#GH46386)
225+
- Clang will emit an error instead of crash when use co_await or co_yield in
226+
C++26 braced-init-list template parameter initialization. (#GH78426)
227+
- Improved fix for an issue with pack expansions of type constraints, where this
228+
now also works if the constraint has non-type or template template parameters.
229+
(#GH131798)
230+
- Fixes to partial ordering of non-type template parameter packs. (#GH132562)
231+
- Fix crash when evaluating the trailing requires clause of generic lambdas which are part of
232+
a pack expansion.
233+
- Fixes matching of nested template template parameters. (#GH130362)
234+
- Correctly diagnoses template template parameters which have a pack parameter
235+
not in the last position.
236+
- Disallow overloading on struct vs class on dependent types, which is IFNDR, as
237+
this makes the problem diagnosable.
238+
- Improved preservation of the presence or absence of typename specifier when
239+
printing types in diagnostics.
240+
- Clang now correctly parses ``if constexpr`` expressions in immediate function context. (#GH123524)
241+
- Fixed an assertion failure affecting code that uses C++23 "deducing this". (#GH130272)
242+
- Clang now properly instantiates destructors for initialized members within non-delegating constructors. (#GH93251)
243+
- Correctly diagnoses if unresolved using declarations shadows template parameters (#GH129411)
244+
- Fixed C++20 aggregate initialization rules being incorrectly applied in certain contexts. (#GH131320)
245+
- Clang was previously coalescing volatile writes to members of volatile base class subobjects.
246+
The issue has been addressed by propagating qualifiers during derived-to-base conversions in the AST. (#GH127824)
247+
- Correctly propagates the instantiated array type to the ``DeclRefExpr`` that refers to it. (#GH79750), (#GH113936), (#GH133047)
248+
- Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892)
249+
- Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused
250+
and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810)
251+
- Declarations using class template argument deduction with redundant
252+
parentheses around the declarator are no longer rejected. (#GH39811)
253+
- Fixed a crash caused by invalid declarations of ``std::initializer_list``. (#GH132256)
254+
- Clang no longer crashes when establishing subsumption between some constraint expressions. (#GH122581)
255+
- Clang now issues an error when placement new is used to modify a const-qualified variable
256+
in a ``constexpr`` function. (#GH131432)
257+
- Fixed an incorrect TreeTransform for calls to ``consteval`` functions if a conversion template is present. (#GH137885)
258+
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)
259+
- Fixed a missed initializer instantiation bug for variable templates. (#GH134526), (#GH138122)
260+
- Fix a crash when checking the template template parameters of a dependent lambda appearing in an alias declaration.
261+
(#GH136432), (#GH137014), (#GH138018)
262+
- Fixed an assertion when trying to constant-fold various builtins when the argument
263+
referred to a reference to an incomplete type. (#GH129397)
264+
- Fixed a crash when a cast involved a parenthesized aggregate initialization in dependent context. (#GH72880)
265+
- No longer crashes when instantiating invalid variable template specialization
266+
whose type depends on itself. (#GH51347), (#GH55872)
267+
- Improved parser recovery of invalid requirement expressions. In turn, this
268+
fixes crashes from follow-on processing of the invalid requirement. (#GH138820)
269+
- Fixed the handling of pack indexing types in the constraints of a member function redeclaration. (#GH138255)
270+
- Clang now correctly parses arbitrary order of ``[[]]``, ``__attribute__`` and ``alignas`` attributes for declarations (#GH133107)
271+
- Fixed a crash when forming an invalid function type in a dependent context. (#GH138657) (#GH115725) (#GH68852)
272+
- Clang no longer segfaults when there is a configuration mismatch between modules and their users (http://crbug.com/400353616).
273+
- Fix an incorrect deduction when calling an explicit object member function template through an overload set address.
274+
- Fixed bug in constant evaluation that would allow using the value of a
275+
reference in its own initializer in C++23 mode (#GH131330).
276+
- Clang could incorrectly instantiate functions in discarded contexts (#GH140449)
277+
- Fix instantiation of default-initialized variable template specialization. (#GH140632) (#GH140622)
278+
- Clang modules now allow a module and its user to differ on TrivialAutoVarInit*
279+
- Fixed an access checking bug when initializing non-aggregates in default arguments (#GH62444), (#GH83608)
280+
- Fixed a pack substitution bug in deducing class template partial specializations. (#GH53609)
281+
- Fixed a crash when constant evaluating some explicit object member assignment operators. (#GH142835)
282+
>>>>>>> 14b0e97a546e (Fix more tests in error handling (#53))
192283

193284
Bug Fixes to AST Handling
194285
^^^^^^^^^^^^^^^^^^^^^^^^^

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)