[libclang] Avoid crashing when getting layout info of an undeduced type.
authorEmilio Cobos Alvarez <emilio@crisal.io>
Tue, 26 Feb 2019 15:04:18 +0000 (15:04 +0000)
committerEmilio Cobos Alvarez <emilio@crisal.io>
Tue, 26 Feb 2019 15:04:18 +0000 (15:04 +0000)
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

clang/include/clang-c/Index.h
clang/test/Index/print-type-size.cpp
clang/tools/c-index-test/c-index-test.c
clang/tools/libclang/CXType.cpp

index e6555fa..a5ef2d2 100644 (file)
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 52
+#define CINDEX_VERSION_MINOR 53
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
       ((major) * 10000)                       \
@@ -3841,7 +3841,11 @@ enum CXTypeLayoutError {
   /**
    * The Field name is not valid for this record.
    */
-  CXTypeLayoutError_InvalidFieldName = -5
+  CXTypeLayoutError_InvalidFieldName = -5,
+  /**
+   * The type is undeduced.
+   */
+  CXTypeLayoutError_Undeduced = -6
 };
 
 /**
index 1ea5346..b4098d9 100644 (file)
@@ -400,4 +400,10 @@ plopplop;
 struct lastValid {
 };
 
+// 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]
+// 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]
+class BrowsingContext {
+  auto Tie(void*) const;
+};
+
 }
index fc6ba46..2cf442e 100644 (file)
@@ -1670,29 +1670,44 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
   return CXChildVisit_Recurse;
 }
 
-static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
-                                             CXClientData d) {
-  CXType T;
-  enum CXCursorKind K = clang_getCursorKind(cursor);
-  if (clang_isInvalid(K))
-    return CXChildVisit_Recurse;
-  T = clang_getCursorType(cursor);
-  PrintCursor(cursor, NULL);
-  PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
+static void PrintSingleTypeSize(CXType T, const char *TypeKindFormat,
+                                const char *SizeFormat,
+                                const char *AlignFormat) {
+  PrintTypeAndTypeKind(T, TypeKindFormat);
   /* Print the type sizeof if applicable. */
   {
     long long Size = clang_Type_getSizeOf(T);
     if (Size >= 0 || Size < -1 ) {
-      printf(" [sizeof=%lld]", Size);
+      printf(SizeFormat, Size);
     }
   }
   /* Print the type alignof if applicable. */
   {
     long long Align = clang_Type_getAlignOf(T);
     if (Align >= 0 || Align < -1) {
-      printf(" [alignof=%lld]", Align);
+      printf(AlignFormat, Align);
     }
   }
+
+  /* Print the return type if it exists. */
+  {
+    CXType RT = clang_getResultType(T);
+    if (RT.kind != CXType_Invalid)
+      PrintSingleTypeSize(RT, " [resulttype=%s] [resulttypekind=%s]",
+                              " [resultsizeof=%lld]", " [resultalignof=%lld]");
+  }
+}
+
+static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
+                                             CXClientData d) {
+  CXType T;
+  enum CXCursorKind K = clang_getCursorKind(cursor);
+  if (clang_isInvalid(K))
+    return CXChildVisit_Recurse;
+  T = clang_getCursorType(cursor);
+  PrintCursor(cursor, NULL);
+  PrintSingleTypeSize(T, " [type=%s] [typekind=%s]", " [sizeof=%lld]",
+                      " [alignof=%lld]");
   /* Print the record field offset if applicable. */
   {
     CXString FieldSpelling = clang_getCursorSpelling(cursor);
@@ -1730,7 +1745,9 @@ static enum CXChildVisitResult PrintTypeSize(CXCursor cursor, CXCursor p,
     if (IsBitfield)
       printf(" [BitFieldSize=%d]", clang_getFieldDeclBitWidth(cursor));
   }
+
   printf("\n");
+
   return CXChildVisit_Recurse;
 }
 
index 55397d6..0d1bfec 100644 (file)
@@ -891,6 +891,9 @@ long long clang_Type_getAlignOf(CXType T) {
     return CXTypeLayoutError_Incomplete;
   if (QT->isDependentType())
     return CXTypeLayoutError_Dependent;
+  if (const auto *Deduced = dyn_cast<DeducedType>(QT))
+    if (Deduced->getDeducedType().isNull())
+      return CXTypeLayoutError_Undeduced;
   // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
   // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
   // if (QT->isVoidType()) return 1;
@@ -928,6 +931,9 @@ long long clang_Type_getSizeOf(CXType T) {
     return CXTypeLayoutError_Dependent;
   if (!QT->isConstantSizeType())
     return CXTypeLayoutError_NotConstantSize;
+  if (const auto *Deduced = dyn_cast<DeducedType>(QT))
+    if (Deduced->getDeducedType().isNull())
+      return CXTypeLayoutError_Undeduced;
   // [gcc extension] lib/AST/ExprConstant.cpp:1372
   //                 HandleSizeof : {voidtype,functype} == 1
   // not handled by ASTContext.cpp:1313 getTypeInfoImpl