https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/200675
>From 51021711fee3cde9778c58a4d8f62318c4f69377 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser <[email protected]> Date: Sun, 31 May 2026 19:16:13 +0200 Subject: [PATCH] [Clang] Accept auto casts pre-C++23 as an extension --- clang/docs/LanguageExtensions.rst | 1 + .../clang/Basic/DiagnosticSemaKinds.td | 3 ++ clang/lib/Frontend/InitPreprocessor.cpp | 2 +- clang/lib/Parse/ParseTentative.cpp | 2 - clang/lib/Sema/SemaExprCXX.cpp | 10 +++-- clang/lib/Sema/SemaType.cpp | 11 +++-- .../dcl.spec/dcl.type/dcl.spec.auto/p5.cpp | 4 +- .../dcl.type/dcl.type.auto.deduct/p2.cpp | 43 ++++++++++--------- .../expr/expr.post/expr.type.conv/p1-2b.cpp | 37 ++++++++-------- clang/test/Lexer/cxx-features.cpp | 2 +- clang/test/Parser/cxx1z-decomposition.cpp | 5 +-- clang/test/Parser/cxx2b-auto-x.cpp | 25 +++++------ 12 files changed, 72 insertions(+), 73 deletions(-) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index fbb9947f39d3e..1ecc8c01a5f8e 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1978,6 +1978,7 @@ Pack Indexing __cpp_pack_indexing C ``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03 Variadic Friends __cpp_variadic_friend C++26 C++03 Trivial Relocatability __cpp_trivial_relocatability C++26 C++03 +``auto()`` cast __cpp_auto_cast C++26 C++03 --------------------------------------------- -------------------------------- ------------- ------------- Designated initializers (N494) C99 C89 ``_Complex`` (N693) C99 C89, C++ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 077aace321264..97636a9f9c963 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2705,6 +2705,9 @@ def err_auto_expr_init_paren_braces : Error< def warn_cxx20_compat_auto_expr : Warning< "'auto' as a functional-style cast is incompatible with C++ standards " "before C++23">, InGroup<CXXPre23Compat>, DefaultIgnore; +def ext_auto_expr : + ExtWarn<"'auto' as a functional-style cast is a C++23 extension">, + InGroup<CXX23>; def err_auto_missing_trailing_return : Error< "'auto' return without trailing return type; deduced return types are a " "C++14 extension">; diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 3f0468a938149..448cb551cc930 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -735,7 +735,6 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_size_t_suffix", "202011L"); Builder.defineMacro("__cpp_if_consteval", "202106L"); Builder.defineMacro("__cpp_multidimensional_subscript", "202211L"); - Builder.defineMacro("__cpp_auto_cast", "202110L"); Builder.defineMacro("__cpp_explicit_this_parameter", "202110L"); } @@ -743,6 +742,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, // we also define their feature test macros. if (LangOpts.CPlusPlus11) Builder.defineMacro("__cpp_static_call_operator", "202207L"); + Builder.defineMacro("__cpp_auto_cast", "202110L"); Builder.defineMacro("__cpp_named_character_escapes", "202207L"); Builder.defineMacro("__cpp_placeholder_variables", "202306L"); diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index f77b1001332fe..74180cf2ddeaf 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1143,8 +1143,6 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, BracedCastResult, InvalidAsDeclSpec); case tok::kw_auto: { - if (!getLangOpts().CPlusPlus23) - return TPResult::True; if (NextToken().is(tok::l_brace)) return TPResult::False; if (NextToken().is(tok::l_paren)) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 00c873833c8a7..66a5825fe6c36 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1560,6 +1560,12 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits()); } + if (Ty->getAs<AutoType>()) + Diag(TyBeginLoc, getLangOpts().CPlusPlus23 + ? diag::warn_cxx20_compat_auto_expr + : diag::ext_auto_expr) + << FullRange; + if (Inits.empty()) return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression) << Ty << FullRange); @@ -1569,10 +1575,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, diag::err_auto_expr_init_multiple_expressions) << Ty << FullRange); } - if (getLangOpts().CPlusPlus23) { - if (Ty->getAs<AutoType>()) - Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange; - } Expr *Deduce = Inits[0]; if (isa<InitListExpr>(Deduce)) return ExprError( diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 44ac4f6630690..9e8abee1e2d44 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -3251,6 +3251,10 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, DeducedIsTrailingReturnType = true; } + SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc(); + if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId) + AutoRange = D.getName().getSourceRange(); + // C++11 [dcl.spec.auto]p5: reject 'auto' if it is not in an allowed context. if (Deduced) { AutoType *Auto = dyn_cast<AutoType>(Deduced); @@ -3382,8 +3386,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, case DeclaratorContext::FunctionalCast: if (isa<DeducedTemplateSpecializationType>(Deduced)) break; - if (SemaRef.getLangOpts().CPlusPlus23 && IsCXXAutoType && - !Auto->isDecltypeAuto()) + if (IsCXXAutoType && !Auto->isDecltypeAuto()) break; // auto(x) [[fallthrough]]; case DeclaratorContext::TypeName: @@ -3419,10 +3422,6 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, (!SemaRef.getLangOpts().CPlusPlus11 || !IsCXXAutoType)) Error = 13; - SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc(); - if (D.getName().getKind() == UnqualifiedIdKind::IK_ConversionFunctionId) - AutoRange = D.getName().getSourceRange(); - if (Error != -1) { unsigned Kind; if (Auto) { diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp index 9571d6670e70d..bdf3a587a7c52 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp @@ -56,8 +56,8 @@ void j() { (void)reinterpret_cast<auto>(n); // expected-error{{'auto' not allowed here}} (void)const_cast<auto>(n); // expected-error{{'auto' not allowed here}} (void)(auto)(n); // expected-error{{'auto' not allowed here}} - (void)auto(n); // expected-error{{'auto' not allowed here}} - (void)auto{n}; // expected-error{{'auto' not allowed here}} + (void)auto(n); // expected-warning{{'auto' as a functional-style cast is a C++23 extension}} + (void)auto{n}; // expected-warning{{'auto' as a functional-style cast is a C++23 extension}} } template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp index 1655685f44808..1c6c66882c570 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp @@ -1,37 +1,38 @@ +// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx20 %s // RUN: %clang_cc1 -std=c++23 -verify %s // p2.3 allows only T = auto in T(x). void test_decay() { int v[3]; - static_assert(__is_same(decltype(auto(v)), int *)); - static_assert(__is_same(decltype(auto{v}), int *)); - static_assert(__is_same(decltype(auto("lit")), char const *)); - static_assert(__is_same(decltype(auto{"lit"}), char const *)); + static_assert(__is_same(decltype(auto(v)), int *)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto{v}), int *)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto("lit")), char const *)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto{"lit"}), char const *)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} constexpr long i = 1; static_assert(__is_same(decltype(i), long const)); - static_assert(__is_same(decltype(auto(1L)), long)); - static_assert(__is_same(decltype(auto{1L}), long)); - static_assert(__is_same(decltype(auto(i)), long)); - static_assert(__is_same(decltype(auto{i}), long)); + static_assert(__is_same(decltype(auto(1L)), long)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto{1L}), long)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(i)), long)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto{i}), long)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} class A { } a; A const ac; - static_assert(__is_same(decltype(auto(a)), A)); - static_assert(__is_same(decltype(auto(ac)), A)); + static_assert(__is_same(decltype(auto(a)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(ac)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} A &lr = a; A const &lrc = a; A &&rr = static_cast<A &&>(a); A const &&rrc = static_cast<A &&>(a); - static_assert(__is_same(decltype(auto(lr)), A)); - static_assert(__is_same(decltype(auto(lrc)), A)); - static_assert(__is_same(decltype(auto(rr)), A)); - static_assert(__is_same(decltype(auto(rrc)), A)); + static_assert(__is_same(decltype(auto(lr)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(lrc)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(rr)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(rrc)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} } class cmdline_parser { @@ -42,7 +43,7 @@ class cmdline_parser { void test_rvalue_fluent_interface() { auto cmdline = cmdline_parser("driver"); - auto internal = auto{cmdline}.add_option("--dump-full", "do not minimize dump"); + auto internal = auto{cmdline}.add_option("--dump-full", "do not minimize dump"); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} } template <class T> constexpr auto decay_copy(T &&v) { return static_cast<T &&>(v); } // expected-error {{calling a protected constructor}} @@ -55,17 +56,17 @@ class A { A(); auto test_access() { - static_assert(__is_same(decltype(auto(*this)), A)); - static_assert(__is_same(decltype(auto(this)), A *)); + static_assert(__is_same(decltype(auto(*this)), A)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(this)), A *)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} f(A(*this)); // ok - f(auto(*this)); // ok in P0849 + f(auto(*this)); // ok in P0849 cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} f(decay_copy(*this)); // expected-note {{in instantiation of function template specialization}} } auto test_access() const { - static_assert(__is_same(decltype(auto(*this)), A)); // ditto - static_assert(__is_same(decltype(auto(this)), A const *)); + static_assert(__is_same(decltype(auto(*this)), A)); // ditto cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + static_assert(__is_same(decltype(auto(this)), A const *)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} } protected: @@ -77,5 +78,5 @@ namespace auto_x { constexpr struct Uncopyable { constexpr explicit Uncopyable(int) {} constexpr Uncopyable(Uncopyable &&) = delete; -} u = auto(Uncopyable(auto(Uncopyable(42)))); +} u = auto(Uncopyable(auto(Uncopyable(42)))); // cxx20-warning 2 {{'auto' as a functional-style cast is a C++23 extension}} } // namespace auto_x diff --git a/clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp b/clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp index bbfce5e698d15..08560ea19c9c7 100644 --- a/clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp +++ b/clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp @@ -1,3 +1,4 @@ +// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx20 %s // RUN: %clang_cc1 -std=c++23 -verify %s template <class T> @@ -12,28 +13,28 @@ struct A { // C++23 [dcl.type.auto.deduct]p2.3 // For an explicit type conversion, T is the specified type, which shall be auto. void diagnostics() { - foo(auto()); // expected-error {{initializer for functional-style cast to 'auto' is empty}} - foo(auto{}); // expected-error {{initializer for functional-style cast to 'auto' is empty}} - foo(auto({})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} - foo(auto{{}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} + foo(auto()); // expected-error {{initializer for functional-style cast to 'auto' is empty}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{}); // expected-error {{initializer for functional-style cast to 'auto' is empty}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto({})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{{}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} // - If the initializer is a parenthesized expression-list, the expression-list shall be a single assignmentexpression and E is the assignment-expression. - foo(auto(a)); + foo(auto(a)); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} // - If the initializer is a braced-init-list, it shall consist of a single brace-enclosed assignment-expression and E is the assignment-expression. - foo(auto{a}); - foo(auto({a})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} - foo(auto{{a}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} + foo(auto{a}); // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto({a})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{{a}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} - foo(auto(&A::g)); // expected-error {{functional-style cast to 'auto' has incompatible initializer of type '<overloaded function type>'}} + foo(auto(&A::g)); // expected-error {{functional-style cast to 'auto' has incompatible initializer of type '<overloaded function type>'}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} - foo(auto(a, 3.14)); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} - foo(auto{a, 3.14}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} - foo(auto({a, 3.14})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} - foo(auto{{a, 3.14}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} - foo(auto({a}, {3.14})); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} - foo(auto{{a}, {3.14}}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} + foo(auto(a, 3.14)); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{a, 3.14}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto({a, 3.14})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{{a, 3.14}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto({a}, {3.14})); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{{a}, {3.14}}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} - foo(auto{1, 2}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} - foo(auto({1, 2})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} - foo(auto{{1, 2}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} + foo(auto{1, 2}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto({1, 2})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} + foo(auto{{1, 2}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}} cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}}s } diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index 171ef99cee5b7..9e67240ee8491 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -60,7 +60,7 @@ // --- C++23 features --- -#if check(auto_cast, 0, 0, 0, 0, 0, 202110, 202110) +#if check(auto_cast, 202110, 202110, 202110, 202110, 202110, 202110, 202110) #error "wrong value for __cpp_auto_cast" #endif diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp index 21c9419e8f413..c075fa3c8128e 100644 --- a/clang/test/Parser/cxx1z-decomposition.cpp +++ b/clang/test/Parser/cxx1z-decomposition.cpp @@ -105,9 +105,8 @@ namespace BadSpecifiers { // defining-type-specifiers other than cv-qualifiers and 'auto' S [a] = s; // expected-error {{cannot be declared with type 'S'}} decltype(auto) [b] = s; // expected-error {{cannot be declared with type 'decltype(auto)'}} - auto ([c2]) = s; // cxx17-error {{structured binding declaration cannot be declared with parenthese}} \ - // post2b-error {{use of undeclared identifier 'c2'}} \ - // post2b-error {{expected body of lambda expression}} \ + auto ([c2]) = s; // expected-error {{use of undeclared identifier 'c2'}} \ + // expected-error {{expected body of lambda expression}} // FIXME: This error is not very good. auto [d]() = s; // expected-error {{expected ';'}} expected-error {{expected expression}} diff --git a/clang/test/Parser/cxx2b-auto-x.cpp b/clang/test/Parser/cxx2b-auto-x.cpp index 9e0277eee76a9..fed80ace7db85 100644 --- a/clang/test/Parser/cxx2b-auto-x.cpp +++ b/clang/test/Parser/cxx2b-auto-x.cpp @@ -2,14 +2,15 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s void looks_like_decltype_auto() { - decltype(auto(42)) b = 42; // cxx20-error {{'auto' not allowed here}} \ + decltype(auto(42)) b = 42; // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} \ cxx23-warning {{'auto' as a functional-style cast is incompatible with C++ standards before C++23}} decltype(long *) a = 42; // expected-error {{expected '(' for function-style cast or type construction}} \ expected-error {{expected expression}} decltype(auto *) a = 42; // expected-error {{expected '(' for function-style cast or type construction}} \ expected-error {{expected expression}} - decltype(auto()) c = 42; // cxx23-error {{initializer for functional-style cast to 'auto' is empty}} \ - cxx20-error {{'auto' not allowed here}} + decltype(auto()) c = 42; // expected-error {{initializer for functional-style cast to 'auto' is empty}} \ + cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} \ + cxx23-warning {{'auto' as a functional-style cast is incompatible with C++ standards before C++23}} } struct looks_like_declaration { @@ -19,11 +20,9 @@ struct looks_like_declaration { using T = looks_like_declaration *; void f() { T(&a)->n = 1; } void g() { auto(&a)->n = 0; } // cxx23-warning {{before C++23}} \ - // cxx20-error {{declaration of variable 'a' with deduced type 'auto (&)' requires an initializer}} \ - // cxx20-error {{expected ';' at end of declaration}} + // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} void h() { auto{&a}->n = 0; } // cxx23-warning {{before C++23}} \ - // cxx20-error {{expected unqualified-id}} \ - // cxx20-error {{expected expression}} + // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} void e(auto (*p)(int y) -> decltype(y)) {} @@ -36,19 +35,15 @@ struct S{ } s; // expected-note {{here}} void test() { - auto(s)()->N; // cxx23-warning {{expression result unused}} \ + auto(s)()->N; // expected-warning {{expression result unused}} \ // cxx23-warning {{before C++23}} \ - // cxx20-error {{unknown type name 'N'}} + // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} auto(s)()->M; // expected-error {{redefinition of 's' as different kind of symbol}} } void test_paren() { int a = (auto(0)); // cxx23-warning {{before C++23}} \ - // cxx20-error {{expected expression}} \ - // cxx20-error {{expected ')'}} \ - // cxx20-note {{to match this '('}} + // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} int b = (auto{0}); // cxx23-warning {{before C++23}} \ - // cxx20-error {{expected expression}} \ - // cxx20-error {{expected ')'}} \ - // cxx20-note {{to match this '('}} + // cxx20-warning {{'auto' as a functional-style cast is a C++23 extension}} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
