llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Giovanni B. (Z3rox-dev) <details> <summary>Changes</summary> Follow-up to #<!-- -->127924, which appears to be abandoned. The diagnostic for a structured binding declaration without an initializer (e.g. auto [a, b];) now tells the user what to write --- Full diff: https://github.com/llvm/llvm-project/pull/181803.diff 7 Files Affected: - (modified) clang-tools-extra/test/clang-tidy/checkers/misc/misplaced-const-cxx17.cpp (+1-1) - (modified) clang/docs/ReleaseNotes.rst (+4) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2-1) - (modified) clang/lib/Sema/SemaDecl.cpp (+3-3) - (modified) clang/test/PCH/cxx1z-decomposition.cpp (+1-1) - (modified) clang/test/Parser/cxx1z-decomposition.cpp (+1-1) - (added) clang/test/Parser/decomp-decl-init-diagnostic.cpp (+26) ``````````diff diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/misplaced-const-cxx17.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/misplaced-const-cxx17.cpp index 56029325420e1..d22394ae874a4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/misplaced-const-cxx17.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/misplaced-const-cxx17.cpp @@ -3,7 +3,7 @@ // This test previously would cause a failed assertion because the structured // binding declaration had no valid type associated with it. This ensures the // expected clang diagnostic is generated instead. -// CHECK-MESSAGES: :[[@LINE+1]]:6: error: structured binding declaration '[x]' requires an initializer [clang-diagnostic-error] +// CHECK-MESSAGES: :[[@LINE+1]]:6: error: structured binding declaration '[x]' requires an initializer; expected '=' or a braced initializer list [clang-diagnostic-error] auto [x]; struct S { int a; }; diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c9bedb87c6a79..25b318aa69f8c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -245,6 +245,10 @@ Improvements to Clang's diagnostics - The ``-Wloop-analysis`` warning has been extended to catch more cases of variable modification inside lambda expressions (#GH132038). +- Improved the diagnostic for structured binding declarations missing an + initializer to tell the user what is expected (``=`` or a braced initializer + list). (#GH90107) + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 85a023435ba23..29340caea5980 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -606,7 +606,8 @@ def err_decomp_decl_template : Error< def err_decomp_decl_not_alone : Error< "structured binding declaration must be the only declaration in its group">; def err_decomp_decl_requires_init : Error< - "structured binding declaration %0 requires an initializer">; + "structured binding declaration %0 requires an initializer; " + "expected '=' or a braced initializer list">; def err_decomp_decl_wrong_number_bindings : Error< "type %0 binds to %3 %plural{1:element|:elements}2, but " "%select{%plural{0:no|:only %1}1|%1}4 " diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4dfde4bf8cedf..892c5646892af 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -14378,9 +14378,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { QualType Type = Var->getType(); // C++1z [dcl.dcl]p1 grammar implies that an initializer is mandatory. - if (isa<DecompositionDecl>(RealDecl)) { - Diag(Var->getLocation(), diag::err_decomp_decl_requires_init) << Var; - Var->setInvalidDecl(); + if (auto *DD = dyn_cast<DecompositionDecl>(RealDecl)) { + Diag(DD->getLocation(), diag::err_decomp_decl_requires_init) << DD; + DD->setInvalidDecl(); return; } diff --git a/clang/test/PCH/cxx1z-decomposition.cpp b/clang/test/PCH/cxx1z-decomposition.cpp index 340d5eae0b8c3..086eed71d8ed5 100644 --- a/clang/test/PCH/cxx1z-decomposition.cpp +++ b/clang/test/PCH/cxx1z-decomposition.cpp @@ -22,7 +22,7 @@ constexpr int foo(Q &&q) { return a * 10 + b; } -auto [noinit]; // expected-error{{structured binding declaration '[noinit]' requires an initializer}} +auto [noinit]; // expected-error{{structured binding declaration '[noinit]' requires an initializer; expected '=' or a braced initializer list}} #else diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp index 21c9419e8f413..9fa78fa0d4c81 100644 --- a/clang/test/Parser/cxx1z-decomposition.cpp +++ b/clang/test/Parser/cxx1z-decomposition.cpp @@ -152,7 +152,7 @@ namespace Init { void f() { int arr[1]; struct S { int n; }; - auto &[bad1]; // expected-error {{structured binding declaration '[bad1]' requires an initializer}} + auto &[bad1]; // expected-error {{structured binding declaration '[bad1]' requires an initializer; expected '=' or a braced initializer list}} const auto &[bad2](S{}, S{}); // expected-error {{initializer for variable '[bad2]' with type 'const auto &' contains multiple expressions}} const auto &[bad3](); // expected-error {{expected expression}} auto &[good1] = arr; diff --git a/clang/test/Parser/decomp-decl-init-diagnostic.cpp b/clang/test/Parser/decomp-decl-init-diagnostic.cpp new file mode 100644 index 0000000000000..b0322d717c4c3 --- /dev/null +++ b/clang/test/Parser/decomp-decl-init-diagnostic.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s + +struct S { int a; double b; }; +S getS(); + +void test() { + auto [x]; // expected-error {{requires an initializer; expected '=' or a braced initializer list}} + auto &[a, b]; // expected-error {{requires an initializer; expected '=' or a braced initializer list}} + const auto &[p, q]; // expected-error {{requires an initializer; expected '=' or a braced initializer list}} + auto &&[r, s]; // expected-error {{requires an initializer; expected '=' or a braced initializer list}} + + auto [c, d] e = getS(); // expected-error {{requires an initializer; expected '=' or a braced initializer list}} \ + // expected-error {{expected ';' at end of declaration}} +} + +template <typename T> +void test_template(T) { + auto [x, y]; // expected-error {{requires an initializer; expected '=' or a braced initializer list}} +} + +void test_valid() { + S s = {1, 2.0}; + auto [a, b] = s; + auto &[c, d] = s; + auto &&[e, f] = getS(); +} `````````` </details> https://github.com/llvm/llvm-project/pull/181803 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
