diff options
author | Volodymyr Sapsai <vsapsai@apple.com> | 2023-01-10 12:41:11 -0800 |
---|---|---|
committer | Volodymyr Sapsai <vsapsai@apple.com> | 2023-01-18 16:15:53 -0600 |
commit | 304d7307aee15b6eb88d198ae94b595f4e09f485 (patch) | |
tree | 8925002ec068a9f822e14c3596b2461dd44ece55 /clang/unittests/AST | |
parent | d3da9067d143f3d4ce59b6d9ab4606a8ef1dc937 (diff) | |
download | llvm-304d7307aee15b6eb88d198ae94b595f4e09f485.tar.gz |
[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
Diffstat (limited to 'clang/unittests/AST')
-rw-r--r-- | clang/unittests/AST/SourceLocationTest.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp index 43b7149bd118..ca9e9a216197 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); |