https://github.com/davidmenggx created https://github.com/llvm/llvm-project/pull/224465
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 >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] [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); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
