summaryrefslogtreecommitdiff
path: root/clang/unittests/AST
diff options
context:
space:
mode:
authorVolodymyr Sapsai <vsapsai@apple.com>2023-01-10 12:41:11 -0800
committerVolodymyr Sapsai <vsapsai@apple.com>2023-01-18 16:15:53 -0600
commit304d7307aee15b6eb88d198ae94b595f4e09f485 (patch)
tree8925002ec068a9f822e14c3596b2461dd44ece55 /clang/unittests/AST
parentd3da9067d143f3d4ce59b6d9ab4606a8ef1dc937 (diff)
downloadllvm-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.cpp41
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);