llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tidy
Author: David Meng (davidmenggx)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/224465.diff
4 Files Affected:
- (modified) clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp (+10-1)
- (modified) clang-tools-extra/docs/ReleaseNotes.md (+3)
- (modified) clang-tools-extra/docs/clang-tidy/checks/misc/const-correctness.rst (+3)
- (added) clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-decltype-auto.cpp (+32)
``````````diff
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); }
``````````
</details>
https://github.com/llvm/llvm-project/pull/224465