[clang] 06bd74b - Fix implementation of [temp.param]p14's first sentence. (#83487)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 1 07:46:06 PST 2024
Author: Erich Keane
Date: 2024-03-01T07:27:06-08:00
New Revision: 06bd74ba4ac5229f01b64772b49e025be5eb7b53
URL: https://github.com/llvm/llvm-project/commit/06bd74ba4ac5229f01b64772b49e025be5eb7b53
DIFF: https://github.com/llvm/llvm-project/commit/06bd74ba4ac5229f01b64772b49e025be5eb7b53.diff
LOG: Fix implementation of [temp.param]p14's first sentence. (#83487)
The first sentence says:
If a template-parameter of a class template, variable template, or alias
template has a default template-argument, each subsequent
template-parameter shall either have a default template-argument
supplied or be a template parameter pack.
However, we were only testing for "not a function function template",
and referring to an older version of the standard. As far as I can tell,
CWG2032 added the variable-template, and the alias-template pre-dates
the standard on github.
This patch started as a bug fix for #83461 , but ended up fixing a
number of similar cases, so those are validated as well.
Added:
clang/test/SemaCXX/GH83461.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplate.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4e5c870e4177fe..1286263700963c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -301,6 +301,12 @@ Bug Fixes to C++ Support
- Clang now properly reports supported C++11 attributes when using
``__has_cpp_attribute`` and parses attributes with arguments in C++03
(`#82995 <https://github.com/llvm/llvm-project/issues/82995>`_)
+- Clang now properly diagnoses missing 'default' template arguments on a variety
+ of templates. Previously we were diagnosing on any non-function template
+ instead of only on class, alias, and variable templates, as last updated by
+ CWG2032.
+ Fixes (`#83461 <https://github.com/llvm/llvm-project/issues/83461>`_)
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index e91033dd886891..a7910bda874c8d 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3141,12 +3141,14 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
diag::note_template_param_prev_default_arg_in_other_module)
<< PrevModuleName;
Invalid = true;
- } else if (MissingDefaultArg && TPC != TPC_FunctionTemplate) {
- // C++ [temp.param]p11:
- // If a template-parameter of a class template has a default
- // template-argument, each subsequent template-parameter shall either
- // have a default template-argument supplied or be a template parameter
- // pack.
+ } else if (MissingDefaultArg &&
+ (TPC == TPC_ClassTemplate || TPC == TPC_FriendClassTemplate ||
+ TPC == TPC_VarTemplate || TPC == TPC_TypeAliasTemplate)) {
+ // C++ 23[temp.param]p14:
+ // If a template-parameter of a class template, variable template, or
+ // alias template has a default template argument, each subsequent
+ // template-parameter shall either have a default template argument
+ // supplied or be a template parameter pack.
Diag((*NewParam)->getLocation(),
diag::err_template_param_default_arg_missing);
Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg);
diff --git a/clang/test/SemaCXX/GH83461.cpp b/clang/test/SemaCXX/GH83461.cpp
new file mode 100644
index 00000000000000..509535e883e6d9
--- /dev/null
+++ b/clang/test/SemaCXX/GH83461.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+struct S {
+ template<typename Ty = int>
+ friend void foo(auto){}
+
+ template<typename Ty = int, typename Tz>
+ friend void foo2(){}
+};
+
+template<typename T>
+struct TemplS {
+ template<typename Ty = int>
+ friend void foo3(auto){}
+
+ template<typename Ty = int, typename Tz>
+ friend void foo4(){}
+};
+
+void Inst() {
+ TemplS<int>();
+}
+// expected-error at +2{{template parameter missing a default argument}}
+// expected-note at +1{{previous default template argument defined here}}
+template<typename T = int, typename U>
+struct ClassTempl{};
+
+struct HasFriendClassTempl {
+ // expected-error at +1{{default template argument not permitted on a friend template}}
+ template<typename T = int, typename U>
+ friend struct Friend;
+
+ // expected-error at +3{{cannot define a type in a friend declaration}}
+ // expected-error at +1{{default template argument not permitted on a friend template}}
+ template<typename T = int, typename U>
+ friend struct Friend2{};
+};
+
+template<typename Ty>
+struct HasFriendClassTempl2 {
+ // expected-error at +3{{template parameter missing a default argument}}
+ // expected-note at +2{{previous default template argument defined here}}
+ // expected-note@#INST2{{in instantiation of template class}}
+ template<typename T = int, typename U>
+ friend struct Friend;
+};
+
+void Inst2() {
+ HasFriendClassTempl2<int>(); // #INST2
+}
+
+// expected-error at +2{{template parameter missing a default argument}}
+// expected-note at +1{{previous default template argument defined here}}
+template<typename T = int, typename U>
+static constexpr U VarTempl;
+
+// expected-error at +2{{template parameter missing a default argument}}
+// expected-note at +1{{previous default template argument defined here}}
+template<typename T = int, typename U>
+using TypeAlias = U;
More information about the cfe-commits
mailing list