Make sure LLDB can deal with forward declarations to enums without crashing or asserting.
authorGreg Clayton <gclayton@apple.com>
Fri, 29 Apr 2016 20:48:39 +0000 (20:48 +0000)
committerGreg Clayton <gclayton@apple.com>
Fri, 29 Apr 2016 20:48:39 +0000 (20:48 +0000)
<rdar://problem/23776428>

llvm-svn: 268098

lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py
lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Symbol/ClangASTContext.cpp

index b0c5c88..3e0f742 100644 (file)
@@ -63,7 +63,14 @@ class EnumTypesTestCase(TestBase):
                         'Sunday',
                         'kNumDays',
                         '5'];
-
+                                                                                                                             
+        # Make sure a pointer to an anonymous enum type does crash LLDB and displays correctly using
+        # frame variable and expression commands
+        self.expect('frame variable f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', 'f.op', '0x0000000000000000'])
+        self.expect('frame variable *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops', '*f.op', '<parent is NULL>'])
+        self.expect('expr f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['ops *', '$', '0x0000000000000000'])
+        self.expect('expr *f.op', DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['error:'], error = True)
+        
         bkpt = self.target().FindBreakpointByID(bkpt_id)
         for enum_value in enum_values:
             self.expect("frame variable day", 'check for valid enumeration value',
index 3d59654..be0fa57 100644 (file)
@@ -8,6 +8,15 @@
 //===----------------------------------------------------------------------===//
 #include <stdio.h>
 
+#include <stdio.h>
+
+// Forward declare an enumeration (only works in C, not C++)
+typedef enum ops ops;
+
+struct foo {
+       ops *op;
+};
+
 int main (int argc, char const *argv[])
 {
     enum days {
@@ -21,6 +30,8 @@ int main (int argc, char const *argv[])
         kNumDays
     };
     enum days day;
+    struct foo f;
+       f.op = NULL;
     for (day = Monday - 1; day <= kNumDays + 1; day++)
     {
         printf("day as int is %i\n", (int)day); // Set break point at this line.
index 62d8f89..0d53ccf 100644 (file)
@@ -1011,9 +1011,18 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc,
                             }
 
                             if (!enumerator_clang_type)
-                                enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
-                                                                                                        DW_ATE_signed,
-                                                                                                        byte_size * 8);
+                            {
+                                if (byte_size > 0)
+                                {
+                                    enumerator_clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(NULL,
+                                                                                                           DW_ATE_signed,
+                                                                                                           byte_size * 8);
+                                }
+                                else
+                                {
+                                    enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
+                                }
+                            }
 
                             clang_type = m_ast.CreateEnumerationType (type_name_cstr,
                                                                       GetClangDeclContextContainingDIE (die, nullptr),
index e80faa1..6b61646 100644 (file)
@@ -8545,24 +8545,28 @@ ClangASTContext::CompleteTagDeclarationDefinition (const CompilerType& type)
                     clang::ASTContext *ast = lldb_ast->getASTContext();
 
                     /// TODO This really needs to be fixed.
-                    
-                    unsigned NumPositiveBits = 1;
-                    unsigned NumNegativeBits = 0;
-                    
-                    clang::QualType promotion_qual_type;
-                    // If the enum integer type is less than an integer in bit width,
-                    // then we must promote it to an integer size.
-                    if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+
+                    QualType integer_type(enum_decl->getIntegerType());
+                    if (!integer_type.isNull())
                     {
-                        if (enum_decl->getIntegerType()->isSignedIntegerType())
-                            promotion_qual_type = ast->IntTy;
+                        unsigned NumPositiveBits = 1;
+                        unsigned NumNegativeBits = 0;
+                        
+                        clang::QualType promotion_qual_type;
+                        // If the enum integer type is less than an integer in bit width,
+                        // then we must promote it to an integer size.
+                        if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy))
+                        {
+                            if (enum_decl->getIntegerType()->isSignedIntegerType())
+                                promotion_qual_type = ast->IntTy;
+                            else
+                                promotion_qual_type = ast->UnsignedIntTy;
+                        }
                         else
-                            promotion_qual_type = ast->UnsignedIntTy;
+                            promotion_qual_type = enum_decl->getIntegerType();
+                        
+                        enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
                     }
-                    else
-                        promotion_qual_type = enum_decl->getIntegerType();
-                    
-                    enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits);
                 }
                 return true;
             }