[clang] [clang] Implement CWG1878 "`operator auto` template" (PR #78103)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 14 08:51:01 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Vlad Serebrennikov (Endilll)
<details>
<summary>Changes</summary>
C++14 introduced deduced return type for regular functions, but shortly after [CWG1878](https://wg21.link/cwg1878) was filed and resolved to disallow deduced return types in conversion function templates. So this patch diagnoses such usage of deduced return type in C++14 mode onwards.
Fixes #<!-- -->51776
---
Full diff: https://github.com/llvm/llvm-project/pull/78103.diff
6 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+2)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2-1)
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+9-1)
- (modified) clang/test/CXX/drs/dr18xx.cpp (+21-5)
- (modified) clang/test/SemaCXX/deduced-return-type-cxx14.cpp (+22-6)
- (modified) clang/www/cxx_dr_status.html (+1-1)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3cbce1be1594376..271e641a5ccce0f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -560,6 +560,8 @@ Improvements to Clang's diagnostics
- Clang now diagnoses unexpanded packs within the template argument lists of function template specializations.
- Clang now diagnoses attempts to bind a bitfield to an NTTP of a reference type as erroneous
converted constant expression and not as a reference to subobject.
+- Clang now diagnoses ``auto`` and ``decltype(auto)`` in declarations of conversion function template
+ (`CWG1878: <https://cplusplus.github.io/CWG/issues/1878.html>`_)
Improvements to Clang's time-trace
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1a79892e40030ae..de99d753a13a6cd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2411,7 +2411,8 @@ def err_auto_not_allowed : Error<
"|in type allocated by 'new'|in K&R-style function parameter"
"|in template parameter|in friend declaration|in function prototype that is "
"not a function declaration|in requires expression parameter"
- "|in array declaration}1">;
+ "|in array declaration"
+ "|in declaration of conversion function template}1">;
def err_dependent_deduced_tst : Error<
"typename specifier refers to "
"%select{class template|function template|variable template|alias template|"
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 36e53c684ac4dc3..613dccbf445f91d 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11323,8 +11323,16 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
}
if (FunctionTemplateDecl *ConversionTemplate
- = Conversion->getDescribedFunctionTemplate())
+ = Conversion->getDescribedFunctionTemplate()) {
+ if (ConvType->isUndeducedAutoType()) {
+ Diag(Conversion->getTypeSpecStartLoc(), diag::err_auto_not_allowed)
+ << Conversion->getTypeSourceInfo()->getTypeLoc().getContainedAutoTypeLoc().getSourceRange()
+ << llvm::to_underlying(Conversion->getConversionType()->getAs<AutoType>()->getKeyword())
+ << /* in declaration of conversion function template */ 24;
+ }
+
return ConversionTemplate;
+ }
return Conversion;
}
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index 175c39e8b73abbe..8be94ed49e639d2 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx98 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx11-17,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,cxx98-14,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
@@ -317,6 +317,22 @@ namespace dr1872 { // dr1872: 9
#endif
}
+namespace dr1878 { // dr1878: 18
+#if __cplusplus >= 201402L
+struct S {
+ template <typename T>
+ operator auto() const { return short(); }
+ // since-cxx14-error at -1 {{'auto' not allowed in declaration of conversion function template}}
+ template <typename T>
+ operator const auto() const { return int(); }
+ // since-cxx14-error at -1 {{'auto' not allowed in declaration of conversion function template}}
+ template <typename T>
+ operator decltype(auto)() const { return unsigned(); }
+ // since-cxx14-error at -1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
+};
+#endif
+}
+
namespace dr1881 { // dr1881: 7
struct A { int a : 4; };
struct B : A { int b : 3; };
diff --git a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
index eac9c587869f552..6533a9e561f248f 100644
--- a/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ b/clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,cxx20_23,cxx23 %s
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,cxx20_23,cxx23 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,since-cxx14,cxx20_23,cxx23 %s
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,since-cxx14,cxx20_23,cxx23 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
-// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx14_20,cxx20_23 %s
-// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx14_20,cxx20_23 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,since-cxx14,cxx14_20,cxx20_23 %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,since-cxx14,cxx14_20,cxx20_23 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
-// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify=expected,cxx14_20,cxx14 %s
-// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify=expected,cxx14_20,cxx14 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify=expected,since-cxx14,cxx14_20,cxx14 %s
+// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify=expected,since-cxx14,cxx14_20,cxx14 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
auto f(); // expected-note {{previous}}
int f(); // expected-error {{differ only in their return type}}
@@ -686,3 +686,19 @@ auto f(auto x) { // cxx14-error {{'auto' not allowed in function prototype}}
}
}
+
+struct DeducedTargetTypeOfConversionFunction {
+ operator auto() const { return char(); }
+ operator const auto() const { return float(); }
+ operator decltype(auto)() const { return double(0); }
+
+ template <typename T>
+ operator auto() const { return short(); }
+ // since-cxx14-error at -1 {{'auto' not allowed in declaration of conversion function template}}
+ template <typename T>
+ operator const auto() const { return int(); }
+ // since-cxx14-error at -1 {{'auto' not allowed in declaration of conversion function template}}
+ template <typename T>
+ operator decltype(auto)() const { return unsigned(); }
+ // since-cxx14-error at -1 {{'decltype(auto)' not allowed in declaration of conversion function template}}
+};
diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html
index 397bf1357d3cb36..c0b481936942304 100755
--- a/clang/www/cxx_dr_status.html
+++ b/clang/www/cxx_dr_status.html
@@ -11076,7 +11076,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/1878.html">1878</a></td>
<td>CD4</td>
<td><TT>operator auto</TT> template</td>
- <td class="unknown" align="center">Unknown</td>
+ <td class="unreleased" align="center">Clang 18</td>
</tr>
<tr id="1879">
<td><a href="https://cplusplus.github.io/CWG/issues/1879.html">1879</a></td>
``````````
</details>
https://github.com/llvm/llvm-project/pull/78103
More information about the cfe-commits
mailing list