diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-GH153649.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-GH153649.cpp new file mode 100644 index 0000000000000..142eb5847ae10 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/type-traits-GH153649.cpp @@ -0,0 +1,15 @@ +// RUN: %check_clang_tidy -std=c++20 %s modernize-type-traits %t + +namespace std { +template struct tuple_size { + static const int value = 1; +}; +template struct tuple_element { + using type = int; +}; +} + +struct A {}; +template int get(const A&); + +auto [a] = A(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index dd66a5f15a970..30930d9cf48c0 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1373,10 +1373,13 @@ static bool checkTupleLikeDecomposition(Sema &S, S.BuildReferenceType(T, E.get()->isLValue(), Loc, B->getDeclName()); if (RefType.isNull()) return true; - auto *RefVD = VarDecl::Create( - S.Context, Src->getDeclContext(), Loc, Loc, - B->getDeclName().getAsIdentifierInfo(), RefType, - S.Context.getTrivialTypeSourceInfo(T, Loc), Src->getStorageClass()); + + // Don't give this VarDecl a TypeSourceInfo, since this is a synthesized + // entity and this type was never written in source code. + auto *RefVD = + VarDecl::Create(S.Context, Src->getDeclContext(), Loc, Loc, + B->getDeclName().getAsIdentifierInfo(), RefType, + /*TInfo=*/nullptr, Src->getStorageClass()); RefVD->setLexicalDeclContext(Src->getLexicalDeclContext()); RefVD->setTSCSpec(Src->getTSCSpec()); RefVD->setImplicit(); diff --git a/clang/test/Analysis/anonymous-decls.cpp b/clang/test/Analysis/anonymous-decls.cpp index 3f972a33aa621..76e5155b61b67 100644 --- a/clang/test/Analysis/anonymous-decls.cpp +++ b/clang/test/Analysis/anonymous-decls.cpp @@ -78,12 +78,12 @@ int main() { // CHECK-NEXT: 8: decomposition-a-b // CHECK-NEXT: 9: [B3.7]([B3.8]) // CHECK-NEXT: 10: [B3.9] -// CHECK-NEXT: 11: std::tuple_element<0UL, std::pair>::type a = get<0UL>(decomposition-a-b); +// CHECK-NEXT: 11: std::tuple_element<0UL, std::pair>::type &&a = get<0UL>(decomposition-a-b); // CHECK-NEXT: 12: get<1UL> // CHECK-NEXT: 13: [B3.12] (ImplicitCastExpr, FunctionToPointerDecay, tuple_element<1L, pair >::type (*)(pair &)) // CHECK-NEXT: 14: decomposition-a-b // CHECK-NEXT: 15: [B3.13]([B3.14]) // CHECK-NEXT: 16: [B3.15] -// CHECK-NEXT: 17: std::tuple_element<1UL, std::pair>::type b = get<1UL>(decomposition-a-b); +// CHECK-NEXT: 17: std::tuple_element<1UL, std::pair>::type &&b = get<1UL>(decomposition-a-b); // CHECK-NEXT: Preds (1): B1 // CHECK-NEXT: Succs (1): B2