llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Nikolas Klauser (philnik777) <details> <summary>Changes</summary> Fixes #<!-- -->115609 --- Patch is 23.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/200675.diff 12 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) - (modified) clang/lib/Frontend/InitPreprocessor.cpp (+1-1) - (modified) clang/lib/Parse/ParseTentative.cpp (-2) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+6-4) - (modified) clang/lib/Sema/SemaType.cpp (+5-6) - (modified) clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp (+2-2) - (modified) clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp (+22-21) - (modified) clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp (+19-18) - (modified) clang/test/Lexer/cxx-features.cpp (+1-1) - (modified) clang/test/Parser/cxx1z-decomposition.cpp (+2-3) - (modified) clang/test/Parser/cxx2b-auto-x.cpp (+10-15) ``````````diff 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..fed80ace7... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/200675 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
