Author: Volodymyr Sapsai Date: 2023-01-18T16:15:53-06:00 New Revision: 304d7307aee15b6eb88d198ae94b595f4e09f485
URL: https://github.com/llvm/llvm-project/commit/304d7307aee15b6eb88d198ae94b595f4e09f485 DIFF: https://github.com/llvm/llvm-project/commit/304d7307aee15b6eb88d198ae94b595f4e09f485.diff LOG: [clang][Sema] Fix uninitialized `SourceLocation` for types with multiple attributes and macros. Some `TypeLoc`s are considered "sugar" and we go past them in `GetTypeSourceInfoForDeclarator`. The problem is that we peel off only the same kind of `TypeLoc` at the time which makes it impossible to handle mixed sequences like `AttributedTypeLoc - MacroQualifiedTypeLoc - AttributedTypeLoc - PointerTypeLoc` In this situation, as shown in the added test, we don't get to `PointerTypeLoc` and don't set its starLoc leaving it uninitialized. Address FIXME and peel off "sugar" `TypeLoc`s regardless of their order. rdar://102149264 Differential Revision: https://reviews.llvm.org/D141424 Added: Modified: clang/lib/Sema/SemaType.cpp clang/unittests/AST/SourceLocationTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index eb61a5fe4fbae..ac00e87944845 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6515,29 +6515,42 @@ GetTypeSourceInfoForDeclarator(TypeProcessingState &State, CurrTL = ATL.getValueLoc().getUnqualifiedLoc(); } - while (MacroQualifiedTypeLoc TL = CurrTL.getAs<MacroQualifiedTypeLoc>()) { - TL.setExpansionLoc( - State.getExpansionLocForMacroQualifiedType(TL.getTypePtr())); - CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); - } + bool HasDesugaredTypeLoc = true; + while (HasDesugaredTypeLoc) { + switch (CurrTL.getTypeLocClass()) { + case TypeLoc::MacroQualified: { + auto TL = CurrTL.castAs<MacroQualifiedTypeLoc>(); + TL.setExpansionLoc( + State.getExpansionLocForMacroQualifiedType(TL.getTypePtr())); + CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); + break; + } - while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) { - fillAttributedTypeLoc(TL, State); - CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); - } + case TypeLoc::Attributed: { + auto TL = CurrTL.castAs<AttributedTypeLoc>(); + fillAttributedTypeLoc(TL, State); + CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); + break; + } - while (BTFTagAttributedTypeLoc TL = CurrTL.getAs<BTFTagAttributedTypeLoc>()) - CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); + case TypeLoc::Adjusted: + case TypeLoc::BTFTagAttributed: { + CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); + break; + } - while (DependentAddressSpaceTypeLoc TL = - CurrTL.getAs<DependentAddressSpaceTypeLoc>()) { - fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs()); - CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc(); - } + case TypeLoc::DependentAddressSpace: { + auto TL = CurrTL.castAs<DependentAddressSpaceTypeLoc>(); + fillDependentAddressSpaceTypeLoc(TL, D.getTypeObject(i).getAttrs()); + CurrTL = TL.getPointeeTypeLoc().getUnqualifiedLoc(); + break; + } - // FIXME: Ordering here? - while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>()) - CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); + default: + HasDesugaredTypeLoc = false; + break; + } + } DeclaratorLocFiller(S.Context, State, D.getTypeObject(i)).Visit(CurrTL); CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp index 43b7149bd1183..ca9e9a2161974 100644 --- a/clang/unittests/AST/SourceLocationTest.cpp +++ b/clang/unittests/AST/SourceLocationTest.cpp @@ -438,6 +438,47 @@ TEST(UnaryTransformTypeLoc, ParensRange) { loc(unaryTransformType()))); } +TEST(PointerTypeLoc, StarLoc) { + llvm::Annotations Example(R"c( + int $star^*var; + )c"); + + auto AST = tooling::buildASTFromCode(Example.code()); + SourceManager &SM = AST->getSourceManager(); + auto &Ctx = AST->getASTContext(); + + auto *VD = selectFirst<VarDecl>("vd", match(varDecl(hasName("var")).bind("vd"), Ctx)); + ASSERT_NE(VD, nullptr); + + auto TL = + VD->getTypeSourceInfo()->getTypeLoc().castAs<PointerTypeLoc>(); + ASSERT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("star")); +} + +TEST(PointerTypeLoc, StarLocBehindSugar) { + llvm::Annotations Example(R"c( + #define NODEREF __attribute__((noderef)) + char $1st^* NODEREF _Nonnull $2nd^* var; + )c"); + + auto AST = tooling::buildASTFromCode(Example.code()); + SourceManager &SM = AST->getSourceManager(); + auto &Ctx = AST->getASTContext(); + + auto *VD = selectFirst<VarDecl>("vd", match(varDecl(hasName("var")).bind("vd"), Ctx)); + ASSERT_NE(VD, nullptr); + + auto TL = VD->getTypeSourceInfo()->getTypeLoc().castAs<PointerTypeLoc>(); + EXPECT_EQ(SM.getFileOffset(TL.getStarLoc()), Example.point("2nd")); + + // Cast intermediate TypeLoc to make sure the structure matches expectations. + auto InnerPtrTL = TL.getPointeeLoc().castAs<AttributedTypeLoc>() + .getNextTypeLoc().castAs<MacroQualifiedTypeLoc>() + .getNextTypeLoc().castAs<AttributedTypeLoc>() + .getNextTypeLoc().castAs<PointerTypeLoc>(); + EXPECT_EQ(SM.getFileOffset(InnerPtrTL.getStarLoc()), Example.point("1st")); +} + TEST(CXXFunctionalCastExpr, SourceRange) { RangeVerifier<CXXFunctionalCastExpr> Verifier; Verifier.expectRange(2, 10, 2, 14); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits