https://github.com/davidmenggx updated https://github.com/llvm/llvm-project/pull/224465
>From 2237065ae201db89573e8d11d71a867a08f92474 Mon Sep 17 00:00:00 2001 From: David Meng <[email protected]> Date: Thu, 17 Sep 2026 15:45:57 -0700 Subject: [PATCH 1/3] [clang-tidy] Skip `decltype(auto)` variables in misc-const-correctness Since #157319 the check analyzes `auto` variables, which also pulled in `decltype(auto)`. Its fix-it inserts `const`, but `decltype(auto)` cannot be combined with other type specifiers, so the fix does not compile: ```cpp decltype(auto) x = get_ref(); decltype(auto) const x = get_ref(); // error ``` Exclude such variables from the analysis, as no `const` can be added. Fixes #223940 --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 11 ++++++- clang-tools-extra/docs/ReleaseNotes.md | 3 ++ .../checks/misc/const-correctness.rst | 3 ++ .../misc/const-correctness-decltype-auto.cpp | 32 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 1abe4db743a25..b187f68be7ff0 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -45,6 +45,11 @@ AST_MATCHER(TypeLoc, hasContainedAutoType) { return !Node.getContainedAutoTypeLoc().isNull(); } +AST_MATCHER(TypeLoc, hasContainedDecltypeAutoType) { + const AutoTypeLoc Loc = Node.getContainedAutoTypeLoc(); + return !Loc.isNull() && Loc.isDecltypeAuto(); +} + AST_MATCHER(FunctionDecl, isTemplate) { return Node.getDescribedFunctionTemplate() != nullptr; } @@ -142,6 +147,9 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { const auto FunctionPointerRef = hasType(hasCanonicalType(referenceType(pointee(functionType())))); + // 'const' cannot be combined with 'decltype(auto)'. + const auto DecltypeAutoType = hasTypeLoc(hasContainedDecltypeAutoType()); + const auto CommonExcludeTypes = anyOf(ConstType, ConstReference, RValueReference, TemplateType, FunctionPointerRef, hasType(cxxRecordDecl(isLambda())), @@ -153,7 +161,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { isLocal(), hasInitializer(anything()), unless(anyOf(ConstType, ConstReference, TemplateType, hasInitializer(isInstantiationDependent()), RValueReference, - FunctionPointerRef, isImplicit(), AllowedType)), + FunctionPointerRef, isImplicit(), AllowedType, + DecltypeAutoType)), AnalyzeLambdas ? Matcher<VarDecl>(anything()) : Matcher<VarDecl>(unless(hasType(cxxRecordDecl(isLambda())))), diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md index 7d34d544a5d99..ad17c23674701 100644 --- a/clang-tools-extra/docs/ReleaseNotes.md +++ b/clang-tools-extra/docs/ReleaseNotes.md @@ -209,6 +209,9 @@ infrastructure are described first, followed by tool-specific sections. - Fixed false positives when the pointee is written through a pointer assignment, such as `*(p = q) = 0`. + - No longer diagnoses variables declared with `decltype(auto)`, where the + suggested `const` does not compile. + - Improved {doc}`misc-redundant-expression <clang-tidy/checks/misc/redundant-expression>` by fixing false positives in nested expressions involving different macros or a mix of macro and diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst index ce699e06b9276..7f8599b616c4d 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst @@ -60,6 +60,9 @@ Limitations The check does not run on `C` code. +Variables declared with ``decltype(auto)`` are not analyzed, because +``decltype(auto)`` cannot be combined with ``const``. + The check will not analyze templated variables, template functions or variables that are instantiation dependent. Different instantiations can result in different ``const`` correctness properties and in general it is not diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp new file mode 100644 index 0000000000000..8b50caecec75d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp @@ -0,0 +1,32 @@ +// RUN: %check_clang_tidy -std=c++14-or-later %s misc-const-correctness %t \ +// RUN: -config='{CheckOptions: {misc-const-correctness.WarnPointersAsValues: true}}' \ +// RUN: -- -fno-delayed-template-parsing + +// 'decltype(auto)' cannot be combined with 'const', so variables declared with +// it must not be diagnosed, whatever type they deduce to. + +int global = 0; +int &get_ref() { return global; } +int *get_ptr() { return &global; } + +void sink(int); + +void decltype_auto_is_ignored() { + int i = 42; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: variable 'i' of type 'int' can be declared 'const' + // CHECK-FIXES: int const i = 42; + + decltype(auto) value = i; + decltype(auto) ref = get_ref(); + decltype(auto) ptr = get_ptr(); + sink(value); + sink(ref); + sink(*ptr); +} + +template <typename T> +void decltype_auto_in_template(T t) { + decltype(auto) value = t; + sink(value); +} +void instantiate_template() { decltype_auto_in_template(0); } >From 64564815b8a7e64035874ce7a43fd6fed59cabea Mon Sep 17 00:00:00 2001 From: David Meng <[email protected]> Date: Thu, 17 Sep 2026 19:37:21 -0700 Subject: [PATCH 2/3] Address review comments --- .../clang-tidy/misc/ConstCorrectnessCheck.cpp | 8 ++------ .../docs/clang-tidy/checks/misc/const-correctness.rst | 3 --- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index b187f68be7ff0..640385de7258b 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -40,16 +40,12 @@ AST_MATCHER(ReferenceType, isSpelledAsLValue) { return Node.isSpelledAsLValue(); } AST_MATCHER(Type, isDependentType) { return Node.isDependentType(); } +AST_MATCHER(AutoType, isDecltypeAuto) { return Node.isDecltypeAuto(); } AST_MATCHER(TypeLoc, hasContainedAutoType) { return !Node.getContainedAutoTypeLoc().isNull(); } -AST_MATCHER(TypeLoc, hasContainedDecltypeAutoType) { - const AutoTypeLoc Loc = Node.getContainedAutoTypeLoc(); - return !Loc.isNull() && Loc.isDecltypeAuto(); -} - AST_MATCHER(FunctionDecl, isTemplate) { return Node.getDescribedFunctionTemplate() != nullptr; } @@ -148,7 +144,7 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(hasCanonicalType(referenceType(pointee(functionType())))); // 'const' cannot be combined with 'decltype(auto)'. - const auto DecltypeAutoType = hasTypeLoc(hasContainedDecltypeAutoType()); + const auto DecltypeAutoType = hasType(autoType(isDecltypeAuto())); const auto CommonExcludeTypes = anyOf(ConstType, ConstReference, RValueReference, TemplateType, diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst index 7f8599b616c4d..ce699e06b9276 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst @@ -60,9 +60,6 @@ Limitations The check does not run on `C` code. -Variables declared with ``decltype(auto)`` are not analyzed, because -``decltype(auto)`` cannot be combined with ``const``. - The check will not analyze templated variables, template functions or variables that are instantiation dependent. Different instantiations can result in different ``const`` correctness properties and in general it is not >From 6c5a6ce1f307899836b0f89a068e9308b7ef23b9 Mon Sep 17 00:00:00 2001 From: David Meng <[email protected]> Date: Fri, 18 Sep 2026 06:12:10 -0700 Subject: [PATCH 3/3] Address review comments --- clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp | 3 ++- .../checkers/misc/const-correctness-decltype-auto.cpp | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp index 640385de7258b..57c2bda6c3fd5 100644 --- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp @@ -144,7 +144,8 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) { hasType(hasCanonicalType(referenceType(pointee(functionType())))); // 'const' cannot be combined with 'decltype(auto)'. - const auto DecltypeAutoType = hasType(autoType(isDecltypeAuto())); + const auto DecltypeAutoType = + hasType(ignoringParens(autoType(isDecltypeAuto()))); const auto CommonExcludeTypes = anyOf(ConstType, ConstReference, RValueReference, TemplateType, diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp index 8b50caecec75d..e20bea53cf1d5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp @@ -19,9 +19,11 @@ void decltype_auto_is_ignored() { decltype(auto) value = i; decltype(auto) ref = get_ref(); decltype(auto) ptr = get_ptr(); + decltype(auto) (paren) = 42; sink(value); sink(ref); sink(*ptr); + sink(paren); } template <typename T> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
