Просмотр исходного кода

[DeclPrinter] Fix two cases that crash clang -ast-print.

Both are related to handling anonymous structures.
* clang didn't handle () around an anonymous struct variable.
* clang also crashed on syntax errors that could lead to other
  syntactic constructs following the declaration of an
  anonymous struct. While the code is invalid, that's not
  a good reason to panic compiler.

Differential Revision: https://reviews.llvm.org/D41788

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322742 91177308-0d34-0410-b5e6-96231b3b80d8
Artem Belevich 7 лет назад
Родитель
Сommit
62d06f7f32
3 измененных файлов с 21 добавлено и 4 удалено
  1. 5 4
      lib/AST/DeclPrinter.cpp
  2. 4 0
      test/Sema/ast-print.c
  3. 12 0
      test/SemaCXX/ast-print-crash.cpp

+ 5 - 4
lib/AST/DeclPrinter.cpp

@@ -128,9 +128,7 @@ static QualType GetBaseType(QualType T) {
   // FIXME: This should be on the Type class!
   QualType BaseType = T;
   while (!BaseType->isSpecifierType()) {
-    if (isa<TypedefType>(BaseType))
-      break;
-    else if (const PointerType* PTy = BaseType->getAs<PointerType>())
+    if (const PointerType *PTy = BaseType->getAs<PointerType>())
       BaseType = PTy->getPointeeType();
     else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>())
       BaseType = BPy->getPointeeType();
@@ -144,8 +142,11 @@ static QualType GetBaseType(QualType T) {
       BaseType = RTy->getPointeeType();
     else if (const AutoType *ATy = BaseType->getAs<AutoType>())
       BaseType = ATy->getDeducedType();
+    else if (const ParenType *PTy = BaseType->getAs<ParenType>())
+      BaseType = PTy->desugar();
     else
-      llvm_unreachable("Unknown declarator!");
+      // This must be a syntax error.
+      break;
   }
   return BaseType;
 }

+ 4 - 0
test/Sema/ast-print.c

@@ -15,6 +15,10 @@ struct blah {
   };
 };
 
+// This used to crash clang.
+struct {
+}(s1);
+
 int foo(const struct blah *b) {
   // CHECK: return b->b;
   return b->b;

+ 12 - 0
test/SemaCXX/ast-print-crash.cpp

@@ -0,0 +1,12 @@
+// RUN: not %clang_cc1 -triple %ms_abi_triple -ast-print %s -std=gnu++11 \
+// RUN:     | FileCheck %s
+
+// The test compiles a file with a syntax error which used to cause a crash with
+// -ast-print. Compilation fails due to the syntax error, but compiler should
+// not crash and print out whatever it manager to parse.
+
+// CHECK:      struct {
+// CHECK-NEXT: } dont_crash_on_syntax_error;
+// CHECK-NEXT: decltype(nullptr) p;
+struct {
+} dont_crash_on_syntax_error /* missing ; */ decltype(nullptr) p;