diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4d152d220289b..4c69bdf131aaa 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -575,6 +575,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: `_) - Clang now diagnoses the requirement that non-template friend declarations with requires clauses and template friend declarations with a constraint that depends on a template parameter from an enclosing template must be a definition. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 03b0122d1c08f..23692758e9b8a 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 828a0ec3dd042..df5bd55e7c283 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11321,9 +11321,20 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) { << ClassType << ConvType; } - if (FunctionTemplateDecl *ConversionTemplate - = Conversion->getDescribedFunctionTemplate()) + if (FunctionTemplateDecl *ConversionTemplate = + Conversion->getDescribedFunctionTemplate()) { + if (const auto *ConvTypePtr = ConvType->getAs()) { + ConvType = ConvTypePtr->getPointeeType(); + } + if (ConvType->isUndeducedAutoType()) { + Diag(Conversion->getTypeSpecStartLoc(), diag::err_auto_not_allowed) + << getReturnTypeLoc(Conversion).getSourceRange() + << llvm::to_underlying(ConvType->getAs()->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 0245f03986dd7..f2c056e13ecad 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__) @@ -319,6 +319,41 @@ namespace dr1872 { // dr1872: 9 #endif } +namespace dr1878 { // dr1878: 18 +#if __cplusplus >= 201402L +#if __cplusplus >= 202002L +template +concept C = true; +#endif + +struct S { + template + operator auto() const { return short(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator const auto() const { return int(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator const auto&() const { return char(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator const auto*() const { return long(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator decltype(auto)() const { return unsigned(); } + // since-cxx14-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}} +#if __cplusplus >= 202002L + template + operator C auto() const { return float(); } + // since-cxx20-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator C decltype(auto)() const { return double(); } + // since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}} +#endif +}; +#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 eac9c587869f5..c0d43911b8c71 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-cxx20,since-cxx14,cxx20_23,cxx23 %s +// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,since-cxx20,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-cxx20,since-cxx14,cxx14_20,cxx20_23 %s +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,since-cxx20,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,41 @@ auto f(auto x) { // cxx14-error {{'auto' not allowed in function prototype}} } } + +#if __cplusplus >= 202002L +template +concept C = true; +#endif + +struct DeducedTargetTypeOfConversionFunction { + operator auto() const { return char(); } + operator const auto() const { return float(); } + operator const auto&() const { return int(); } + // expected-warning@-1 {{returning reference to local temporary object}} + operator decltype(auto)() const { return double(); } +#if __cplusplus >= 202002L + operator C auto() const { return unsigned(); } + operator C decltype(auto)() const { return long(); } +#endif + + template + operator auto() const { return short(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator const auto() const { return int(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator const auto&() const { return char(); } + // since-cxx14-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator decltype(auto)() const { return unsigned(); } + // since-cxx14-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}} +#if __cplusplus >= 202002L + template + operator C auto() const { return float(); } + // since-cxx20-error@-1 {{'auto' not allowed in declaration of conversion function template}} + template + operator C decltype(auto)() const { return double(); } + // since-cxx20-error@-1 {{'decltype(auto)' not allowed in declaration of conversion function template}} +#endif +}; diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index b29a746bcf6e8..f0d835fc091ce 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -11076,7 +11076,7 @@

C++ defect report implementation status

1878 CD4 operator auto template - Unknown + Clang 18 1879