Skip to content

Commit 0d76dc2

Browse files
committed
[libclang] Avoid crashing when getting layout info of an undeduced type.
When the type is not deducible, return an error instead of crashing. This fixes https://bugs.llvm.org/show_bug.cgi?id=40813. Differential Revision: https://reviews.llvm.org/D58569 llvm-svn: 354885
1 parent 582d463 commit 0d76dc2

File tree

4 files changed

+46
-13
lines changed

4 files changed

+46
-13
lines changed

clang/include/clang-c/Index.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
3333
*/
3434
#define CINDEX_VERSION_MAJOR 0
35-
#define CINDEX_VERSION_MINOR 52
35+
#define CINDEX_VERSION_MINOR 53
3636

3737
#define CINDEX_VERSION_ENCODE(major, minor) ( \
3838
((major) * 10000) \
@@ -3841,7 +3841,11 @@ enum CXTypeLayoutError {
38413841
/**
38423842
* The Field name is not valid for this record.
38433843
*/
3844-
CXTypeLayoutError_InvalidFieldName = -5
3844+
CXTypeLayoutError_InvalidFieldName = -5,
3845+
/**
3846+
* The type is undeduced.
3847+
*/
3848+
CXTypeLayoutError_Undeduced = -6
38453849
};
38463850

38473851
/**

clang/test/Index/print-type-size.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,10 @@ plopplop;
400400
struct lastValid {
401401
};
402402

403+
// CHECK64: CXXMethod=Tie:[[@LINE+3]]:8 (const) [type=auto (void *) const] [typekind=FunctionProto] [sizeof=1] [alignof=4] [resulttype=auto] [resulttypekind=Auto] [resultsizeof=-6] [resultalignof=-6]
404+
// CHECK32: CXXMethod=Tie:[[@LINE+2]]:8 (const) [type=auto (void *) const] [typekind=FunctionProto] [sizeof=1] [alignof=4] [resulttype=auto] [resulttypekind=Auto] [resultsizeof=-6] [resultalignof=-6]
405+
class BrowsingContext {
406+
auto Tie(void*) const;
407+
};
408+
403409
}

clang/tools/c-index-test/c-index-test.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,29 +1670,44 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
16701670
return CXChildVisit_Recurse;
16711671
}
16721672

1673-
static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
1674-
CXClientData d) {
1675-
CXType T;
1676-
enum CXCursorKind K = clang_getCursorKind(cursor);
1677-
if (clang_isInvalid(K))
1678-
return CXChildVisit_Recurse;
1679-
T = clang_getCursorType(cursor);
1680-
PrintCursor(cursor, NULL);
1681-
PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
1673+
static void PrintSingleTypeSize(CXType T, const char *TypeKindFormat,
1674+
const char *SizeFormat,
1675+
const char *AlignFormat) {
1676+
PrintTypeAndTypeKind(T, TypeKindFormat);
16821677
/* Print the type sizeof if applicable. */
16831678
{
16841679
long long Size = clang_Type_getSizeOf(T);
16851680
if (Size >= 0 || Size < -1 ) {
1686-
printf(" [sizeof=%lld]", Size);
1681+
printf(SizeFormat, Size);
16871682
}
16881683
}
16891684
/* Print the type alignof if applicable. */
16901685
{
16911686
long long Align = clang_Type_getAlignOf(T);
16921687
if (Align >= 0 || Align < -1) {
1693-
printf(" [alignof=%lld]", Align);
1688+
printf(AlignFormat, Align);
16941689
}
16951690
}
1691+
1692+
/* Print the return type if it exists. */
1693+
{
1694+
CXType RT = clang_getResultType(T);
1695+
if (RT.kind != CXType_Invalid)
1696+
PrintSingleTypeSize(RT, " [resulttype=%s] [resulttypekind=%s]",
1697+
" [resultsizeof=%lld]", " [resultalignof=%lld]");
1698+
}
1699+
}
1700+
1701+
static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
1702+
CXClientData d) {
1703+
CXType T;
1704+
enum CXCursorKind K = clang_getCursorKind(cursor);
1705+
if (clang_isInvalid(K))
1706+
return CXChildVisit_Recurse;
1707+
T = clang_getCursorType(cursor);
1708+
PrintCursor(cursor, NULL);
1709+
PrintSingleTypeSize(T, " [type=%s] [typekind=%s]", " [sizeof=%lld]",
1710+
" [alignof=%lld]");
16961711
/* Print the record field offset if applicable. */
16971712
{
16981713
CXString FieldSpelling = clang_getCursorSpelling(cursor);
@@ -1730,7 +1745,9 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
17301745
if (IsBitfield)
17311746
printf(" [BitFieldSize=%d]", clang_getFieldDeclBitWidth(cursor));
17321747
}
1748+
17331749
printf("\n");
1750+
17341751
return CXChildVisit_Recurse;
17351752
}
17361753

clang/tools/libclang/CXType.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,9 @@ long long clang_Type_getAlignOf(CXType T) {
891891
return CXTypeLayoutError_Incomplete;
892892
if (QT->isDependentType())
893893
return CXTypeLayoutError_Dependent;
894+
if (const auto *Deduced = dyn_cast<DeducedType>(QT))
895+
if (Deduced->getDeducedType().isNull())
896+
return CXTypeLayoutError_Undeduced;
894897
// Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
895898
// if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
896899
// if (QT->isVoidType()) return 1;
@@ -928,6 +931,9 @@ long long clang_Type_getSizeOf(CXType T) {
928931
return CXTypeLayoutError_Dependent;
929932
if (!QT->isConstantSizeType())
930933
return CXTypeLayoutError_NotConstantSize;
934+
if (const auto *Deduced = dyn_cast<DeducedType>(QT))
935+
if (Deduced->getDeducedType().isNull())
936+
return CXTypeLayoutError_Undeduced;
931937
// [gcc extension] lib/AST/ExprConstant.cpp:1372
932938
// HandleSizeof : {voidtype,functype} == 1
933939
// not handled by ASTContext.cpp:1313 getTypeInfoImpl

0 commit comments

Comments
 (0)