[clang] 304d730 - [clang][Sema] Fix uninitialized `SourceLocation` for types with multiple attributes and macros.
Volodymyr Sapsai via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 18 14:16:10 PST 2023
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);
More information about the cfe-commits
mailing list